Merge branch 'master' of https://github.com/singularity-viewer/SingularityViewer
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
<key>OpenCircuit</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>template</string>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>false</boolean>
|
||||
</map>
|
||||
@@ -370,6 +370,14 @@
|
||||
</map>
|
||||
|
||||
<!-- Server to client -->
|
||||
<key>DisplayNameUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>ParcelVoiceInfo</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
@@ -419,6 +427,22 @@
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>SetDisplayNameReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>SimConsoleResponse</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>DirLandReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
@@ -515,8 +539,24 @@
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<!-- UDPDeprecated Messages -->
|
||||
|
||||
<key>NavMeshStatusUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>AgentStateUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<!-- UDPDeprecated Messages -->
|
||||
<key>ScriptRunningReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
@@ -569,26 +609,9 @@
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<!-- Server to client -->
|
||||
<key>DisplayNameUpdate</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
<key>SetDisplayNameReply</key>
|
||||
<map>
|
||||
<key>flavor</key>
|
||||
<string>llsd</string>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
<key>trusted-sender</key>
|
||||
<boolean>true</boolean>
|
||||
</map>
|
||||
|
||||
</map>
|
||||
<key>capBans</key>
|
||||
|
||||
@@ -395,12 +395,12 @@ LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, con
|
||||
{
|
||||
mInternetStreamURL = url;
|
||||
|
||||
FMOD_CREATESOUNDEXINFO exinfo;
|
||||
/*FMOD_CREATESOUNDEXINFO exinfo;
|
||||
memset(&exinfo,0,sizeof(exinfo));
|
||||
exinfo.cbsize = sizeof(exinfo);
|
||||
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_MPEG; //Hint to speed up loading.
|
||||
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS; //Hint to speed up loading.*/
|
||||
|
||||
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, &exinfo, &mInternetStream);
|
||||
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
|
||||
|
||||
if (result!= FMOD_OK)
|
||||
{
|
||||
|
||||
@@ -193,19 +193,14 @@ void LLCharacter::requestStopMotion( LLMotion* motion)
|
||||
//-----------------------------------------------------------------------------
|
||||
// updateMotions()
|
||||
//-----------------------------------------------------------------------------
|
||||
static LLFastTimer::DeclareTimer FTM_UPDATE_ANIMATION("Update Animation");
|
||||
static LLFastTimer::DeclareTimer FTM_UPDATE_HIDDEN_ANIMATION("Update Hidden Anim");
|
||||
|
||||
void LLCharacter::updateMotions(e_update_t update_type)
|
||||
{
|
||||
if (update_type == HIDDEN_UPDATE)
|
||||
{
|
||||
LLFastTimer t(FTM_UPDATE_HIDDEN_ANIMATION);
|
||||
mMotionController.updateMotionsMinimal();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFastTimer t(FTM_UPDATE_ANIMATION);
|
||||
// unpause if the number of outstanding pause requests has dropped to the initial one
|
||||
if (mMotionController.isPaused() && mPauseRequest->getNumRefs() == 1)
|
||||
{
|
||||
|
||||
@@ -837,6 +837,7 @@ void LLMotionController::updateMotions(bool force_update)
|
||||
}
|
||||
|
||||
updateLoadingMotions();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type)
|
||||
}
|
||||
|
||||
// static
|
||||
LLAssetType::EType LLAssetType::lookup( const char* name )
|
||||
LLAssetType::EType LLAssetType::lookup(const char* name)
|
||||
{
|
||||
return lookup(ll_safe_string(name));
|
||||
}
|
||||
@@ -186,7 +186,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type)
|
||||
}
|
||||
|
||||
// static
|
||||
LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name )
|
||||
LLAssetType::EType LLAssetType::lookupHumanReadable(const char* name)
|
||||
{
|
||||
return lookupHumanReadable(ll_safe_string(name));
|
||||
}
|
||||
@@ -208,12 +208,9 @@ LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string& readable_
|
||||
return AT_NONE;
|
||||
}
|
||||
|
||||
//NOTE: LLAssetType::lookupDragAndDropType & LLAssetType::generateDescriptionFor moved to newview/llviewerassettype.h
|
||||
|
||||
// static
|
||||
bool LLAssetType::lookupCanLink(EType asset_type)
|
||||
{
|
||||
//Check that enabling all these other types as linkable doesn't break things.
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
const AssetEntry *entry = dict->lookup(asset_type);
|
||||
if (entry)
|
||||
@@ -221,9 +218,6 @@ bool LLAssetType::lookupCanLink(EType asset_type)
|
||||
return entry->mCanLink;
|
||||
}
|
||||
return false;
|
||||
|
||||
/*return (asset_type == AT_CLOTHING || asset_type == AT_OBJECT || asset_type == AT_CATEGORY ||
|
||||
asset_type == AT_BODYPART || asset_type == AT_GESTURE);*/
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -268,4 +262,3 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "llerror.h"
|
||||
#include "lltypeinfolookup.h"
|
||||
#include "llstl.h"
|
||||
|
||||
namespace LLInitParam
|
||||
{
|
||||
@@ -212,14 +212,6 @@ namespace LLInitParam
|
||||
|
||||
public:
|
||||
|
||||
struct CompareTypeID
|
||||
{
|
||||
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
|
||||
{
|
||||
return lhs->before(*rhs);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<std::pair<std::string, bool> > name_stack_t;
|
||||
typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
|
||||
typedef std::vector<std::string> possible_values_t;
|
||||
@@ -228,9 +220,9 @@ namespace LLInitParam
|
||||
typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
|
||||
typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
|
||||
|
||||
typedef LLTypeInfoLookup<parser_read_func_t> parser_read_func_map_t;
|
||||
typedef LLTypeInfoLookup<parser_write_func_t> parser_write_func_map_t;
|
||||
typedef LLTypeInfoLookup<parser_inspect_func_t> parser_inspect_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t;
|
||||
typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t;
|
||||
|
||||
Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
|
||||
: mParseSilently(false),
|
||||
|
||||
@@ -174,6 +174,7 @@ public:
|
||||
F64 averageCount = curr.count + prevCount * (1.0 - timeInCurrent);
|
||||
return averageCount;
|
||||
}
|
||||
|
||||
// call each time the key wants use
|
||||
State noteAction(const T& id, S32 weight = 1)
|
||||
{
|
||||
|
||||
@@ -376,24 +376,24 @@ private:
|
||||
// uses the MSVC compiler intrinsics __cpuid() and __rdtsc().
|
||||
|
||||
// Delays for the specified amount of milliseconds
|
||||
static void _Delay(unsigned int ms)
|
||||
static void _Delay(unsigned int ms)
|
||||
{
|
||||
LARGE_INTEGER freq, c1, c2;
|
||||
__int64 x;
|
||||
LARGE_INTEGER freq, c1, c2;
|
||||
__int64 x;
|
||||
|
||||
// Get High-Res Timer frequency
|
||||
// Get High-Res Timer frequency
|
||||
if (!QueryPerformanceFrequency(&freq))
|
||||
return;
|
||||
|
||||
|
||||
// Convert ms to High-Res Timer value
|
||||
x = freq.QuadPart/1000*ms;
|
||||
|
||||
// Get first snapshot of High-Res Timer value
|
||||
// Get first snapshot of High-Res Timer value
|
||||
QueryPerformanceCounter(&c1);
|
||||
do
|
||||
{
|
||||
// Get second snapshot
|
||||
QueryPerformanceCounter(&c2);
|
||||
// Get second snapshot
|
||||
QueryPerformanceCounter(&c2);
|
||||
}while(c2.QuadPart-c1.QuadPart < x);
|
||||
// Loop while (second-first < x)
|
||||
}
|
||||
|
||||
@@ -52,5 +52,4 @@ private:
|
||||
LLProcessorInfoImpl* mImpl;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif // LLPROCESSOR_H
|
||||
|
||||
@@ -60,6 +60,9 @@ static const char LEGACY_NON_HEADER[] = "<llsd>";
|
||||
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
|
||||
const std::string LLSD_XML_HEADER("LLSD/XML");
|
||||
|
||||
//used to deflate a gzipped asset (currently used for navmeshes)
|
||||
#define windowBits 15
|
||||
#define ENABLE_ZLIB_GZIP 32
|
||||
/**
|
||||
* LLSDSerialize
|
||||
*/
|
||||
@@ -2172,3 +2175,80 @@ bool unzip_llsd(LLSD& data, std::istream& is, S32 size)
|
||||
free(result);
|
||||
return true;
|
||||
}
|
||||
//This unzip function will only work with a gzip header and trailer - while the contents
|
||||
//of the actual compressed data is the same for either format (gzip vs zlib ), the headers
|
||||
//and trailers are different for the formats.
|
||||
U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size )
|
||||
{
|
||||
U8* result = NULL;
|
||||
U32 cur_size = 0;
|
||||
z_stream strm;
|
||||
|
||||
const U32 CHUNK = 0x4000;
|
||||
|
||||
U8 *in = new U8[size];
|
||||
is.read((char*) in, size);
|
||||
|
||||
U8 out[CHUNK];
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = size;
|
||||
strm.next_in = in;
|
||||
|
||||
|
||||
S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
|
||||
do
|
||||
{
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
if (ret == Z_STREAM_ERROR)
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
delete [] in;
|
||||
valid = false;
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR;
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
delete [] in;
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
U32 have = CHUNK-strm.avail_out;
|
||||
|
||||
result = (U8*) realloc(result, cur_size + have);
|
||||
memcpy(result+cur_size, out, have);
|
||||
cur_size += have;
|
||||
|
||||
} while (ret == Z_OK);
|
||||
|
||||
inflateEnd(&strm);
|
||||
delete [] in;
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
free(result);
|
||||
valid = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//result now points to the decompressed LLSD block
|
||||
{
|
||||
outsize= cur_size;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -755,6 +755,9 @@ public:
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
|
||||
return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);
|
||||
}
|
||||
// Line oriented parser, 30% faster than fromXML(), but can
|
||||
// only be used when you know you have the complete XML
|
||||
// document available in the stream.
|
||||
static S32 fromXMLDocument(LLSD& sd, std::istream& str)
|
||||
{
|
||||
LLPointer<LLSDXMLParser> p = new LLSDXMLParser();
|
||||
@@ -791,4 +794,5 @@ public:
|
||||
//dirty little zip functions -- yell at davep
|
||||
LL_COMMON_API std::string zip_llsd(LLSD& data);
|
||||
LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size);
|
||||
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
|
||||
#endif // LL_LLSDSERIALIZE_H
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include "stdtypes.h" // llcommon/stdtypes.h, needed for S32 and U32.
|
||||
#include <typeinfo>
|
||||
|
||||
// Use to compare the first element only of a pair
|
||||
// e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t;
|
||||
@@ -477,4 +477,54 @@ llbind2nd(const _Operation& __oper, const _Tp& __x)
|
||||
return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare std::type_info* pointers a la std::less. We break this out as a
|
||||
* separate function for use in two different std::less specializations.
|
||||
*/
|
||||
inline
|
||||
bool before(const std::type_info* lhs, const std::type_info* rhs)
|
||||
{
|
||||
#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
|
||||
// If we're building on Linux with gcc, and it's either gcc 3.x or
|
||||
// 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on
|
||||
// Mac too, and some people build with gcc on Windows (cygwin or mingw).
|
||||
// On Linux, different load modules may produce different type_info*
|
||||
// pointers for the same type. Have to compare name strings to get good
|
||||
// results.
|
||||
return strcmp(lhs->name(), rhs->name()) < 0;
|
||||
#else // not Linux, or gcc 4.4+
|
||||
// Just use before(), as we normally would
|
||||
return lhs->before(*rhs);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialize std::less<std::type_info*> to use std::type_info::before().
|
||||
* See MAINT-1175. It is NEVER a good idea to directly compare std::type_info*
|
||||
* because, on Linux, you might get different std::type_info* pointers for the
|
||||
* same type (from different load modules)!
|
||||
*/
|
||||
namespace std
|
||||
{
|
||||
template <>
|
||||
struct less<const std::type_info*>:
|
||||
public std::binary_function<const std::type_info*, const std::type_info*, bool>
|
||||
{
|
||||
bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
|
||||
{
|
||||
return before(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct less<std::type_info*>:
|
||||
public std::binary_function<std::type_info*, std::type_info*, bool>
|
||||
{
|
||||
bool operator()(std::type_info* lhs, std::type_info* rhs) const
|
||||
{
|
||||
return before(lhs, rhs);
|
||||
}
|
||||
};
|
||||
} // std
|
||||
|
||||
#endif // LL_LLSTL_H
|
||||
|
||||
@@ -12,9 +12,49 @@
|
||||
#if ! defined(LL_LLTYPEINFOLOOKUP_H)
|
||||
#define LL_LLTYPEINFOLOOKUP_H
|
||||
|
||||
#include "llsortedvector.h"
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <functional> // std::binary_function
|
||||
#include <typeinfo>
|
||||
|
||||
/**
|
||||
* The following helper classes are based on the Boost.Unordered documentation:
|
||||
* http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Compute hash for a string passed as const char*
|
||||
*/
|
||||
struct const_char_star_hash: public std::unary_function<const char*, std::size_t>
|
||||
{
|
||||
std::size_t operator()(const char* str) const
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
for ( ; *str; ++str)
|
||||
{
|
||||
boost::hash_combine(seed, *str);
|
||||
}
|
||||
return seed;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute equality for strings passed as const char*
|
||||
*
|
||||
* I (nat) suspect that this is where the default behavior breaks for the
|
||||
* const char* values returned from std::type_info::name(). If you compare the
|
||||
* two const char* pointer values, as a naive, unspecialized implementation
|
||||
* will surely do, they'll compare unequal.
|
||||
*/
|
||||
struct const_char_star_equal: public std::binary_function<const char*, const char*, bool>
|
||||
{
|
||||
bool operator()(const char* lhs, const char* rhs) const
|
||||
{
|
||||
return strcmp(lhs, rhs) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* LLTypeInfoLookup is specifically designed for use cases for which you might
|
||||
* consider std::map<std::type_info*, VALUE>. We have several such data
|
||||
@@ -23,88 +63,55 @@
|
||||
* different load modules will produce different std::type_info*.
|
||||
* LLTypeInfoLookup contains a workaround to address this issue.
|
||||
*
|
||||
* Specifically, when we don't find the passed std::type_info*,
|
||||
* LLTypeInfoLookup performs a linear search over registered entries to
|
||||
* compare name() strings. Presuming that this succeeds, we cache the new
|
||||
* (previously unrecognized) std::type_info* to speed future lookups.
|
||||
*
|
||||
* This worst-case fallback search (linear search with string comparison)
|
||||
* should only happen the first time we look up a given type from a particular
|
||||
* load module other than the one from which we initially registered types.
|
||||
* (However, a lookup which wouldn't succeed anyway will always have
|
||||
* worst-case performance.) This class is probably best used with less than a
|
||||
* few dozen different types.
|
||||
* The API deliberately diverges from std::map in several respects:
|
||||
* * It avoids iterators, not only begin()/end() but also as return values
|
||||
* from insert() and find(). This bypasses transform_iterator overhead.
|
||||
* * Since we literally use compile-time types as keys, the essential insert()
|
||||
* and find() methods accept the key type as a @em template parameter,
|
||||
* accepting and returning value_type as a normal runtime value. This is to
|
||||
* permit future optimization (e.g. compile-time type hashing) without
|
||||
* changing the API.
|
||||
*/
|
||||
template <typename VALUE>
|
||||
class LLTypeInfoLookup
|
||||
{
|
||||
// Use this for our underlying implementation: lookup by
|
||||
// std::type_info::name() string. This is one of the rare cases in which I
|
||||
// dare use const char* directly, rather than std::string, because I'm
|
||||
// sure that every value returned by std::type_info::name() is static.
|
||||
// HOWEVER, specify our own hash + equality functors: naively comparing
|
||||
// distinct const char* values won't work.
|
||||
typedef boost::unordered_map<const char*, VALUE,
|
||||
const_char_star_hash, const_char_star_equal> impl_map_type;
|
||||
|
||||
public:
|
||||
typedef LLTypeInfoLookup<VALUE> self;
|
||||
typedef LLSortedVector<const std::type_info*, VALUE> vector_type;
|
||||
typedef typename vector_type::key_type key_type;
|
||||
typedef typename vector_type::mapped_type mapped_type;
|
||||
typedef typename vector_type::value_type value_type;
|
||||
typedef typename vector_type::iterator iterator;
|
||||
typedef typename vector_type::const_iterator const_iterator;
|
||||
typedef VALUE value_type;
|
||||
|
||||
LLTypeInfoLookup() {}
|
||||
|
||||
iterator begin() { return mVector.begin(); }
|
||||
iterator end() { return mVector.end(); }
|
||||
const_iterator begin() const { return mVector.begin(); }
|
||||
const_iterator end() const { return mVector.end(); }
|
||||
bool empty() const { return mVector.empty(); }
|
||||
std::size_t size() const { return mVector.size(); }
|
||||
bool empty() const { return mMap.empty(); }
|
||||
std::size_t size() const { return mMap.size(); }
|
||||
|
||||
std::pair<iterator, bool> insert(const std::type_info* key, const VALUE& value)
|
||||
template <typename KEY>
|
||||
bool insert(const value_type& value)
|
||||
{
|
||||
return insert(value_type(key, value));
|
||||
// Obtain and store the std::type_info::name() string as the key.
|
||||
// Return just the bool from std::map::insert()'s return pair.
|
||||
return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second;
|
||||
}
|
||||
|
||||
std::pair<iterator, bool> insert(const value_type& pair)
|
||||
template <typename KEY>
|
||||
boost::optional<value_type> find() const
|
||||
{
|
||||
return mVector.insert(pair);
|
||||
}
|
||||
|
||||
// const find() forwards to non-const find(): this can alter mVector!
|
||||
const_iterator find(const std::type_info* key) const
|
||||
{
|
||||
return const_cast<self*>(this)->find(key);
|
||||
}
|
||||
|
||||
// non-const find() caches previously-unknown type_info* to speed future
|
||||
// lookups.
|
||||
iterator find(const std::type_info* key)
|
||||
{
|
||||
iterator found = mVector.find(key);
|
||||
if (found != mVector.end())
|
||||
{
|
||||
// If LLSortedVector::find() found, great, we're done.
|
||||
return found;
|
||||
}
|
||||
// Here we didn't find the passed type_info*. On Linux, though, even
|
||||
// for the same type, typeid(sametype) produces a different type_info*
|
||||
// when used in different load modules. So the fact that we didn't
|
||||
// find the type_info* we seek doesn't mean this type isn't
|
||||
// registered. Scan for matching name() string.
|
||||
for (typename vector_type::iterator ti(mVector.begin()), tend(mVector.end());
|
||||
ti != tend; ++ti)
|
||||
{
|
||||
if (std::string(ti->first->name()) == key->name())
|
||||
{
|
||||
// This unrecognized 'key' is for the same type as ti->first.
|
||||
// To speed future lookups, insert a new entry that lets us
|
||||
// look up ti->second using this same 'key'.
|
||||
return insert(key, ti->second).first;
|
||||
}
|
||||
}
|
||||
// We simply have never seen a type with this type_info* from any load
|
||||
// module.
|
||||
return mVector.end();
|
||||
// Use the std::type_info::name() string as the key.
|
||||
typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name());
|
||||
if (found == mMap.end())
|
||||
return boost::optional<value_type>();
|
||||
return found->second;
|
||||
}
|
||||
|
||||
private:
|
||||
vector_type mVector;
|
||||
impl_map_type mMap;
|
||||
};
|
||||
|
||||
#endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
|
||||
// We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes.
|
||||
#if LL_WINDOWS
|
||||
# undef WIN32_LEAN_AND_MEAN
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "lldefs.h"
|
||||
@@ -452,7 +452,8 @@ static void get_random_bytes(void *buf, int nbytes)
|
||||
return;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
#if LL_WINDOWS
|
||||
|
||||
typedef struct _ASTAT_
|
||||
{
|
||||
ADAPTER_STATUS adapt;
|
||||
@@ -460,58 +461,44 @@ typedef struct _ASTAT_
|
||||
}ASTAT, * PASTAT;
|
||||
|
||||
// static
|
||||
S32 LLUUID::getNodeID(unsigned char *node_id)
|
||||
S32 LLUUID::getNodeID(unsigned char *node_id)
|
||||
{
|
||||
ASTAT Adapter;
|
||||
NCB Ncb;
|
||||
UCHAR uRetCode;
|
||||
LANA_ENUM lenum;
|
||||
int i;
|
||||
int retval = 0;
|
||||
ASTAT Adapter;
|
||||
NCB Ncb;
|
||||
UCHAR uRetCode;
|
||||
LANA_ENUM lenum;
|
||||
int i;
|
||||
int retval = 0;
|
||||
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBENUM;
|
||||
Ncb.ncb_buffer = (UCHAR *)&lenum;
|
||||
Ncb.ncb_length = sizeof(lenum);
|
||||
uRetCode = Netbios( &Ncb );
|
||||
// printf( "The NCBENUM return code is: 0x%x \n", uRetCode );
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBENUM;
|
||||
Ncb.ncb_buffer = (UCHAR *)&lenum;
|
||||
Ncb.ncb_length = sizeof(lenum);
|
||||
uRetCode = Netbios( &Ncb );
|
||||
|
||||
for(i=0; i < lenum.length ;i++)
|
||||
{
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBRESET;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
for(i=0; i < lenum.length ;i++)
|
||||
{
|
||||
memset( &Ncb, 0, sizeof(Ncb) );
|
||||
Ncb.ncb_command = NCBRESET;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
|
||||
uRetCode = Netbios( &Ncb );
|
||||
// printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
|
||||
// lenum.lana[i], uRetCode );
|
||||
uRetCode = Netbios( &Ncb );
|
||||
|
||||
memset( &Ncb, 0, sizeof (Ncb) );
|
||||
Ncb.ncb_command = NCBASTAT;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
memset( &Ncb, 0, sizeof (Ncb) );
|
||||
Ncb.ncb_command = NCBASTAT;
|
||||
Ncb.ncb_lana_num = lenum.lana[i];
|
||||
|
||||
strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */
|
||||
Ncb.ncb_buffer = (unsigned char *)&Adapter;
|
||||
Ncb.ncb_length = sizeof(Adapter);
|
||||
strcpy( (char *)Ncb.ncb_callname, "* " ); /* Flawfinder: ignore */
|
||||
Ncb.ncb_buffer = (unsigned char *)&Adapter;
|
||||
Ncb.ncb_length = sizeof(Adapter);
|
||||
|
||||
uRetCode = Netbios( &Ncb );
|
||||
// printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
|
||||
// lenum.lana[i], uRetCode );
|
||||
if ( uRetCode == 0 )
|
||||
{
|
||||
// printf( "The Ethernet Number on LANA %d is: %02x%02x%02x%02x%02x%02x\n",
|
||||
// lenum.lana[i],
|
||||
// Adapter.adapt.adapter_address[0],
|
||||
// Adapter.adapt.adapter_address[1],
|
||||
// Adapter.adapt.adapter_address[2],
|
||||
// Adapter.adapt.adapter_address[3],
|
||||
// Adapter.adapt.adapter_address[4],
|
||||
// Adapter.adapt.adapter_address[5] );
|
||||
uRetCode = Netbios( &Ncb );
|
||||
if ( uRetCode == 0 )
|
||||
{
|
||||
memcpy(node_id,Adapter.adapt.adapter_address,6); /* Flawfinder: ignore */
|
||||
retval = 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ public:
|
||||
|
||||
U8 mData[UUID_BYTES];
|
||||
};
|
||||
|
||||
typedef std::vector<LLUUID> uuid_vec_t;
|
||||
|
||||
// Construct
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "v3math.h"
|
||||
#include "llvector4a.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
|
||||
#define OCT_ERRS LL_ERRS("OctreeErrors")
|
||||
@@ -89,11 +88,12 @@ public:
|
||||
|
||||
typedef LLOctreeTraveler<T> oct_traveler;
|
||||
typedef LLTreeTraveler<T> tree_traveler;
|
||||
typedef typename std::set<LLPointer<T> > element_list;
|
||||
typedef typename element_list::iterator element_iter;
|
||||
typedef typename element_list::const_iterator const_element_iter;
|
||||
typedef LLPointer<T>* element_list;
|
||||
typedef LLPointer<T>* element_iter;
|
||||
typedef const LLPointer<T>* const_element_iter;
|
||||
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
|
||||
typedef typename std::vector<LLOctreeNode<T>* > child_list;
|
||||
typedef LLOctreeNode<T>** child_list;
|
||||
typedef LLOctreeNode<T>** child_iter;
|
||||
typedef LLTreeNode<T> BaseType;
|
||||
typedef LLOctreeNode<T> oct_node;
|
||||
typedef LLOctreeListener<T> oct_listener;
|
||||
@@ -115,6 +115,9 @@ public:
|
||||
: mParent((oct_node*)parent),
|
||||
mOctant(octant)
|
||||
{
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
|
||||
mCenter = center;
|
||||
mSize = size;
|
||||
|
||||
@@ -133,6 +136,16 @@ public:
|
||||
{
|
||||
BaseType::destroyListeners();
|
||||
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
{
|
||||
mData[i]->setBinIndex(-1);
|
||||
mData[i] = NULL;
|
||||
}
|
||||
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
delete getChild(i);
|
||||
@@ -229,12 +242,17 @@ public:
|
||||
}
|
||||
|
||||
void accept(oct_traveler* visitor) { visitor->visit(this); }
|
||||
virtual bool isLeaf() const { return mChild.empty(); }
|
||||
virtual bool isLeaf() const { return mChildCount == 0; }
|
||||
|
||||
U32 getElementCount() const { return mElementCount; }
|
||||
bool isEmpty() const { return mElementCount == 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; }
|
||||
|
||||
U32 getChildCount() const { return mChildCount; }
|
||||
oct_node* getChild(U32 index) { return mChild[index]; }
|
||||
const oct_node* getChild(U32 index) const { return mChild[index]; }
|
||||
@@ -299,7 +317,7 @@ public:
|
||||
|
||||
virtual bool insert(T* data)
|
||||
{
|
||||
if (data == NULL)
|
||||
if (data == NULL || data->getBinIndex() != -1)
|
||||
{
|
||||
OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << llendl;
|
||||
return false;
|
||||
@@ -309,22 +327,19 @@ public:
|
||||
//is it here?
|
||||
if (isInside(data->getPositionGroup()))
|
||||
{
|
||||
if (((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius())) ||
|
||||
if ((getElementCount() < gOctreeMaxCapacity && contains(data->getBinRadius()) ||
|
||||
(data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity)))
|
||||
{ //it belongs here
|
||||
#if LL_OCTREE_PARANOIA_CHECK
|
||||
//if this is a redundant insertion, error out (should never happen)
|
||||
if (mData.find(data) != mData.end())
|
||||
{
|
||||
llwarns << "Redundant octree insertion detected. " << data << llendl;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
mData.insert(data);
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
|
||||
mElementCount = mData.size();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -358,10 +373,16 @@ public:
|
||||
|
||||
if( lt == 0x7 )
|
||||
{
|
||||
mData.insert(data);
|
||||
BaseType::insert(data);
|
||||
mElementCount++;
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
|
||||
mElementCount = mData.size();
|
||||
//avoid unref on uninitialized memory
|
||||
memset(mData+mElementCount-1, 0, sizeof(LLPointer<T>));
|
||||
|
||||
mData[mElementCount-1] = data;
|
||||
mDataEnd = mData + mElementCount;
|
||||
data->setBinIndex(mElementCount-1);
|
||||
BaseType::insert(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -410,23 +431,59 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void _remove(T* data, S32 i)
|
||||
{ //precondition -- mElementCount > 0, idx is in range [0, mElementCount)
|
||||
|
||||
mElementCount--;
|
||||
data->setBinIndex(-1);
|
||||
|
||||
if (mElementCount > 0)
|
||||
{
|
||||
if (mElementCount != i)
|
||||
{
|
||||
mData[i] = mData[mElementCount]; //might unref data, do not access data after this point
|
||||
mData[i]->setBinIndex(i);
|
||||
}
|
||||
|
||||
mData[mElementCount] = NULL; //needed for unref
|
||||
mData = (element_list) realloc(mData, sizeof(LLPointer<T>)*mElementCount);
|
||||
mDataEnd = mData+mElementCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
mData[0] = NULL; //needed for unref
|
||||
free(mData);
|
||||
mData = NULL;
|
||||
mDataEnd = NULL;
|
||||
}
|
||||
|
||||
notifyRemoval(data);
|
||||
checkAlive();
|
||||
}
|
||||
|
||||
bool remove(T* data)
|
||||
{
|
||||
if (mData.find(data) != mData.end())
|
||||
{ //we have data
|
||||
mData.erase(data);
|
||||
mElementCount = mData.size();
|
||||
this->notifyRemoval(data);
|
||||
checkAlive();
|
||||
return true;
|
||||
S32 i = data->getBinIndex();
|
||||
|
||||
if (i >= 0 && i < (S32)mElementCount)
|
||||
{
|
||||
if (mData[i] == data)
|
||||
{ //found it
|
||||
_remove(data, i);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (isInside(data))
|
||||
|
||||
if (isInside(data))
|
||||
{
|
||||
oct_node* dest = getNodeAt(data);
|
||||
|
||||
if (dest != this)
|
||||
{
|
||||
return dest->remove(data);
|
||||
bool ret = dest->remove(data);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,19 +502,20 @@ public:
|
||||
//node is now root
|
||||
llwarns << "!!! OCTREE REMOVING FACE BY ADDRESS, SEVERE PERFORMANCE PENALTY |||" << llendl;
|
||||
node->removeByAddress(data);
|
||||
llassert(data->getBinIndex() == -1);
|
||||
return true;
|
||||
}
|
||||
|
||||
void removeByAddress(T* data)
|
||||
{
|
||||
if (mData.find(data) != mData.end())
|
||||
for (U32 i = 0; i < mElementCount; ++i)
|
||||
{
|
||||
mData.erase(data);
|
||||
mElementCount = mData.size();
|
||||
this->notifyRemoval(data);
|
||||
llwarns << "FOUND!" << llendl;
|
||||
checkAlive();
|
||||
return;
|
||||
if (mData[i] == data)
|
||||
{ //we have data
|
||||
_remove(data, i);
|
||||
llwarns << "FOUND!" << llendl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
@@ -469,8 +527,8 @@ public:
|
||||
|
||||
void clearChildren()
|
||||
{
|
||||
mChild.clear();
|
||||
mChildCount = 0;
|
||||
|
||||
U32* foo = (U32*) mChildMap;
|
||||
foo[0] = foo[1] = 0xFFFFFFFF;
|
||||
}
|
||||
@@ -532,7 +590,7 @@ public:
|
||||
|
||||
mChildMap[child->getOctant()] = mChildCount;
|
||||
|
||||
mChild.push_back(child);
|
||||
mChild[mChildCount] = child;
|
||||
++mChildCount;
|
||||
child->setParent(this);
|
||||
|
||||
@@ -561,9 +619,12 @@ public:
|
||||
mChild[index]->destroy();
|
||||
delete mChild[index];
|
||||
}
|
||||
mChild.erase(mChild.begin() + index);
|
||||
|
||||
--mChildCount;
|
||||
|
||||
mChild[index] = mChild[mChildCount];
|
||||
|
||||
|
||||
//rebuild child map
|
||||
U32* foo = (U32*) mChildMap;
|
||||
foo[0] = foo[1] = 0xFFFFFFFF;
|
||||
@@ -619,11 +680,12 @@ protected:
|
||||
oct_node* mParent;
|
||||
U8 mOctant;
|
||||
|
||||
child_list mChild;
|
||||
LLOctreeNode<T>* mChild[8];
|
||||
U8 mChildMap[8];
|
||||
U32 mChildCount;
|
||||
|
||||
element_list mData;
|
||||
element_iter mDataEnd;
|
||||
U32 mElementCount;
|
||||
|
||||
};
|
||||
|
||||
@@ -324,16 +324,16 @@ public:
|
||||
LLVector4a& min = node->mExtents[0];
|
||||
LLVector4a& max = node->mExtents[1];
|
||||
|
||||
if (!branch->getData().empty())
|
||||
if (!branch->isEmpty())
|
||||
{ //node has data, find AABB that binds data set
|
||||
const LLVolumeTriangle* tri = *(branch->getData().begin());
|
||||
const LLVolumeTriangle* tri = *(branch->getDataBegin());
|
||||
|
||||
//initialize min/max to first available vertex
|
||||
min = *(tri->mV[0]);
|
||||
max = *(tri->mV[0]);
|
||||
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
|
||||
branch->getData().begin(); iter != branch->getData().end(); ++iter)
|
||||
branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
|
||||
{ //for each triangle in node
|
||||
|
||||
//stretch by triangles in node
|
||||
@@ -348,7 +348,7 @@ public:
|
||||
max.setMax(max, *tri->mV[2]);
|
||||
}
|
||||
}
|
||||
else if (!branch->getChildren().empty())
|
||||
else if (!branch->isLeaf())
|
||||
{ //no data, but child nodes exist
|
||||
LLVolumeOctreeListener* child = (LLVolumeOctreeListener*) branch->getChild(0)->getListener(0);
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
|
||||
void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node)
|
||||
{
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
|
||||
node->getData().begin(); iter != node->getData().end(); ++iter)
|
||||
node->getDataBegin(); iter != node->getDataEnd(); ++iter)
|
||||
{
|
||||
const LLVolumeTriangle* tri = *iter;
|
||||
|
||||
@@ -236,8 +236,8 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
|
||||
}
|
||||
|
||||
//children fit, check data
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getData().begin();
|
||||
iter != branch->getData().end(); ++iter)
|
||||
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
|
||||
iter != branch->getDataEnd(); ++iter)
|
||||
{
|
||||
const LLVolumeTriangle* tri = *iter;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ class LLVolumeTriangle : public LLRefCount
|
||||
public:
|
||||
LLVolumeTriangle()
|
||||
{
|
||||
|
||||
mBinIndex = -1;
|
||||
}
|
||||
|
||||
LLVolumeTriangle(const LLVolumeTriangle& rhs)
|
||||
@@ -64,9 +64,14 @@ public:
|
||||
U16 mIndex[3];
|
||||
|
||||
F32 mRadius;
|
||||
mutable S32 mBinIndex;
|
||||
|
||||
|
||||
virtual const LLVector4a& getPositionGroup() const;
|
||||
virtual const F32& getBinRadius() const;
|
||||
|
||||
S32 getBinIndex() const { return mBinIndex; }
|
||||
void setBinIndex(S32 idx) const { mBinIndex = idx; }
|
||||
};
|
||||
|
||||
class LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,11 +42,8 @@
|
||||
#include "lliopipe.h"
|
||||
#include "llsd.h"
|
||||
#include "llthread.h"
|
||||
#include "llqueuedthread.h"
|
||||
#include "llframetimer.h"
|
||||
|
||||
class LLMutex;
|
||||
class LLCurlThread;
|
||||
|
||||
// For whatever reason, this is not typedef'd in curl.h
|
||||
typedef size_t (*curl_header_callback)(void *ptr, size_t size, size_t nmemb, void *stream);
|
||||
@@ -59,6 +56,8 @@ public:
|
||||
class Easy;
|
||||
class Multi;
|
||||
|
||||
static bool sMultiThreaded;
|
||||
|
||||
struct TransferInfo
|
||||
{
|
||||
TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
|
||||
@@ -125,7 +124,6 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public: /* but not really -- don't touch this */
|
||||
U32 mReferenceCount;
|
||||
|
||||
@@ -163,7 +161,7 @@ public:
|
||||
/**
|
||||
* @ brief Initialize LLCurl class
|
||||
*/
|
||||
static void initClass(F32 curl_reuest_timeout = 120.f, S32 max_number_handles = 256, bool multi_threaded = false);
|
||||
static void initClass(bool multi_threaded = false);
|
||||
|
||||
/**
|
||||
* @ brief Cleanup LLCurl class
|
||||
@@ -182,25 +180,10 @@ public:
|
||||
static void ssl_locking_callback(int mode, int type, const char *file, int line);
|
||||
static unsigned long ssl_thread_id(void);
|
||||
|
||||
static LLCurlThread* getCurlThread() { return sCurlThread ;}
|
||||
|
||||
static CURLM* newMultiHandle() ;
|
||||
static CURLMcode deleteMultiHandle(CURLM* handle) ;
|
||||
static CURL* newEasyHandle() ;
|
||||
static void deleteEasyHandle(CURL* handle) ;
|
||||
|
||||
private:
|
||||
static std::string sCAPath;
|
||||
static std::string sCAFile;
|
||||
static const unsigned int MAX_REDIRECTS;
|
||||
static LLCurlThread* sCurlThread;
|
||||
|
||||
static LLMutex* sHandleMutexp ;
|
||||
static S32 sTotalHandles ;
|
||||
static S32 sMaxHandles;
|
||||
public:
|
||||
static bool sNotQuitting;
|
||||
static F32 sCurlRequestTimeOut;
|
||||
};
|
||||
|
||||
class LLCurl::Easy
|
||||
@@ -209,7 +192,7 @@ class LLCurl::Easy
|
||||
|
||||
private:
|
||||
Easy();
|
||||
|
||||
|
||||
public:
|
||||
static Easy* getEasy();
|
||||
~Easy();
|
||||
@@ -218,41 +201,41 @@ public:
|
||||
|
||||
void setErrorBuffer();
|
||||
void setCA();
|
||||
|
||||
|
||||
void setopt(CURLoption option, S32 value);
|
||||
// These assume the setter does not free value!
|
||||
void setopt(CURLoption option, void* value);
|
||||
void setopt(CURLoption option, char* value);
|
||||
// Copies the string so that it is guaranteed to stick around
|
||||
// Copies the string so that it is gauranteed to stick around
|
||||
void setoptString(CURLoption option, const std::string& value);
|
||||
|
||||
|
||||
void slist_append(const char* str);
|
||||
void setHeaders();
|
||||
|
||||
|
||||
U32 report(CURLcode);
|
||||
void getTransferInfo(LLCurl::TransferInfo* info);
|
||||
|
||||
void prepRequest(const std::string& url, const std::vector<std::string>& headers, LLCurl::ResponderPtr, S32 time_out = 0, bool post = false);
|
||||
|
||||
void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false);
|
||||
|
||||
const char* getErrorBuffer();
|
||||
|
||||
std::stringstream& getInput() { return mInput; }
|
||||
std::stringstream& getHeaderOutput() { return mHeaderOutput; }
|
||||
LLIOPipe::buffer_ptr_t& getOutput() { return mOutput; }
|
||||
const LLChannelDescriptors& getChannels() { return mChannels; }
|
||||
|
||||
|
||||
void resetState();
|
||||
|
||||
static CURL* allocEasyHandle();
|
||||
static void releaseEasyHandle(CURL* handle);
|
||||
|
||||
private:
|
||||
private:
|
||||
friend class LLCurl;
|
||||
friend class LLCurl::Multi;
|
||||
|
||||
CURL* mCurlEasyHandle;
|
||||
struct curl_slist* mHeaders;
|
||||
|
||||
|
||||
std::stringstream mRequest;
|
||||
LLChannelDescriptors mChannels;
|
||||
LLIOPipe::buffer_ptr_t mOutput;
|
||||
@@ -262,125 +245,70 @@ private:
|
||||
|
||||
// Note: char*'s not strings since we pass pointers to curl
|
||||
std::vector<char*> mStrings;
|
||||
|
||||
LLCurl::ResponderPtr mResponder;
|
||||
|
||||
ResponderPtr mResponder;
|
||||
|
||||
static std::set<CURL*> sFreeHandles;
|
||||
static std::set<CURL*> sActiveHandles;
|
||||
static LLMutex* sHandleMutexp ;
|
||||
static LLMutex* sHandleMutex;
|
||||
static LLMutex* sMultiMutex;
|
||||
};
|
||||
|
||||
class LLCurl::Multi
|
||||
class LLCurl::Multi : public LLThread
|
||||
{
|
||||
LOG_CLASS(Multi);
|
||||
|
||||
friend class LLCurlThread ;
|
||||
|
||||
private:
|
||||
~Multi();
|
||||
|
||||
void markDead() ;
|
||||
bool doPerform();
|
||||
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATE_READY=0,
|
||||
STATE_PERFORMING=1,
|
||||
STATE_COMPLETED=2
|
||||
PERFORM_STATE_READY=0,
|
||||
PERFORM_STATE_PERFORMING=1,
|
||||
PERFORM_STATE_COMPLETED=2
|
||||
} ePerformState;
|
||||
|
||||
Multi(F32 idle_time_out = 0.f);
|
||||
Multi();
|
||||
~Multi();
|
||||
|
||||
LLCurl::Easy* allocEasy();
|
||||
bool addEasy(LLCurl::Easy* easy);
|
||||
void removeEasy(LLCurl::Easy* easy);
|
||||
Easy* allocEasy();
|
||||
bool addEasy(Easy* easy);
|
||||
|
||||
void lock() ;
|
||||
void unlock() ;
|
||||
|
||||
void setState(ePerformState state) ;
|
||||
ePerformState getState() ;
|
||||
|
||||
bool isCompleted() ;
|
||||
bool isValid() {return mCurlMultiHandle != NULL && mValid;}
|
||||
bool isDead() {return mDead;}
|
||||
|
||||
bool waitToComplete() ;
|
||||
void removeEasy(Easy* easy);
|
||||
|
||||
S32 process();
|
||||
void perform();
|
||||
void doPerform();
|
||||
|
||||
virtual void run();
|
||||
|
||||
CURLMsg* info_read(S32* msgs_in_queue);
|
||||
|
||||
S32 mQueued;
|
||||
S32 mErrorCount;
|
||||
|
||||
S32 mPerformState;
|
||||
|
||||
LLCondition* mSignal;
|
||||
bool mQuitting;
|
||||
bool mThreaded;
|
||||
|
||||
private:
|
||||
void easyFree(LLCurl::Easy*);
|
||||
void cleanup(bool deleted = false) ;
|
||||
void easyFree(Easy*);
|
||||
|
||||
CURLM* mCurlMultiHandle;
|
||||
|
||||
typedef std::set<LLCurl::Easy*> easy_active_list_t;
|
||||
typedef std::set<Easy*> easy_active_list_t;
|
||||
easy_active_list_t mEasyActiveList;
|
||||
typedef std::map<CURL*, LLCurl::Easy*> easy_active_map_t;
|
||||
typedef std::map<CURL*, Easy*> easy_active_map_t;
|
||||
easy_active_map_t mEasyActiveMap;
|
||||
typedef std::set<LLCurl::Easy*> easy_free_list_t;
|
||||
typedef std::set<Easy*> easy_free_list_t;
|
||||
easy_free_list_t mEasyFreeList;
|
||||
|
||||
LLQueuedThread::handle_t mHandle ;
|
||||
ePerformState mState;
|
||||
|
||||
BOOL mDead ;
|
||||
BOOL mValid ;
|
||||
LLMutex* mMutexp ;
|
||||
LLMutex* mDeletionMutexp ;
|
||||
LLMutex* mEasyMutexp ;
|
||||
LLFrameTimer mIdleTimer ;
|
||||
F32 mIdleTimeOut;
|
||||
};
|
||||
|
||||
class LLCurlThread : public LLQueuedThread
|
||||
namespace boost
|
||||
{
|
||||
public:
|
||||
|
||||
class CurlRequest : public LLQueuedThread::QueuedRequest
|
||||
{
|
||||
protected:
|
||||
virtual ~CurlRequest(); // use deleteRequest()
|
||||
|
||||
public:
|
||||
CurlRequest(handle_t handle, LLCurl::Multi* multi, LLCurlThread* curl_thread);
|
||||
|
||||
/*virtual*/ bool processRequest();
|
||||
/*virtual*/ void finishRequest(bool completed);
|
||||
|
||||
private:
|
||||
// input
|
||||
LLCurl::Multi* mMulti;
|
||||
LLCurlThread* mCurlThread;
|
||||
};
|
||||
friend class CurlRequest;
|
||||
|
||||
public:
|
||||
LLCurlThread(bool threaded = true) ;
|
||||
virtual ~LLCurlThread() ;
|
||||
|
||||
S32 update(F32 max_time_ms);
|
||||
|
||||
void addMulti(LLCurl::Multi* multi) ;
|
||||
void killMulti(LLCurl::Multi* multi) ;
|
||||
|
||||
private:
|
||||
bool doMultiPerform(LLCurl::Multi* multi) ;
|
||||
void deleteMulti(LLCurl::Multi* multi) ;
|
||||
void cleanupMulti(LLCurl::Multi* multi) ;
|
||||
} ;
|
||||
|
||||
|
||||
void intrusive_ptr_add_ref(LLCurl::Responder* p);
|
||||
void intrusive_ptr_release(LLCurl::Responder* p);
|
||||
void intrusive_ptr_add_ref(LLCurl::Responder* p);
|
||||
void intrusive_ptr_release(LLCurl::Responder* p);
|
||||
};
|
||||
|
||||
|
||||
class LLCurlRequest
|
||||
@@ -410,6 +338,7 @@ private:
|
||||
LLCurl::Multi* mActiveMulti;
|
||||
S32 mActiveRequestCount;
|
||||
BOOL mProcessing;
|
||||
U32 mThreadID; // debug
|
||||
};
|
||||
|
||||
class LLCurlEasyRequest
|
||||
@@ -427,11 +356,9 @@ public:
|
||||
void slist_append(const char* str);
|
||||
void sendRequest(const std::string& url);
|
||||
void requestComplete();
|
||||
void perform();
|
||||
bool getResult(CURLcode* result, LLCurl::TransferInfo* info = NULL);
|
||||
std::string getErrorString();
|
||||
bool isCompleted() {return mMulti->isCompleted() ;}
|
||||
bool wait() { return mMulti->waitToComplete(); }
|
||||
bool isValid() {return mMulti && mMulti->isValid(); }
|
||||
|
||||
LLCurl::Easy* getEasy() const { return mEasy; }
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
#include "llhttpclient.h"
|
||||
|
||||
#include "llassetstorage.h"
|
||||
@@ -40,9 +40,7 @@
|
||||
#include "message.h"
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f;
|
||||
LLURLRequest::SSLCertVerifyCallback LLHTTPClient::mCertVerifyCallback = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -160,7 +158,7 @@ namespace
|
||||
fstream.seekg(0, std::ios::end);
|
||||
U32 fileSize = (U32)fstream.tellg();
|
||||
fstream.seekg(0, std::ios::beg);
|
||||
std::vector<char> fileBuffer(fileSize);
|
||||
std::vector<char> fileBuffer(fileSize); //Mem leak fix'd
|
||||
fstream.read(&fileBuffer[0], fileSize);
|
||||
ostream.write(&fileBuffer[0], fileSize);
|
||||
fstream.close();
|
||||
@@ -189,11 +187,9 @@ namespace
|
||||
|
||||
LLVFile vfile(gVFS, mUUID, mAssetType, LLVFile::READ);
|
||||
S32 fileSize = vfile.getSize();
|
||||
U8* fileBuffer;
|
||||
fileBuffer = new U8 [fileSize];
|
||||
vfile.read(fileBuffer, fileSize);
|
||||
ostream.write((char*)fileBuffer, fileSize);
|
||||
delete [] fileBuffer;
|
||||
std::vector<U8> fileBuffer(fileSize);
|
||||
vfile.read(&fileBuffer[0], fileSize);
|
||||
ostream.write((char*)&fileBuffer[0], fileSize);
|
||||
eos = true;
|
||||
return STATUS_DONE;
|
||||
}
|
||||
@@ -202,23 +198,16 @@ namespace
|
||||
LLAssetType::EType mAssetType;
|
||||
};
|
||||
|
||||
|
||||
LLPumpIO* theClientPump = NULL;
|
||||
}
|
||||
|
||||
void LLHTTPClient::setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback)
|
||||
{
|
||||
LLHTTPClient::mCertVerifyCallback = callback;
|
||||
}
|
||||
|
||||
static void request(
|
||||
const std::string& url,
|
||||
LLURLRequest::ERequestAction method,
|
||||
Injector* body_injector,
|
||||
LLCurl::ResponderPtr responder,
|
||||
const F32 timeout = HTTP_REQUEST_EXPIRY_SECS,
|
||||
const LLSD& headers = LLSD()
|
||||
)
|
||||
const LLSD& headers = LLSD())
|
||||
{
|
||||
if (!LLHTTPClient::hasPump())
|
||||
{
|
||||
@@ -228,26 +217,12 @@ static void request(
|
||||
LLPumpIO::chain_t chain;
|
||||
|
||||
LLURLRequest* req = new LLURLRequest(method, url);
|
||||
if(!req->isValid())//failed
|
||||
{
|
||||
delete req ;
|
||||
return ;
|
||||
}
|
||||
|
||||
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
|
||||
|
||||
|
||||
lldebugs << LLURLRequest::actionAsVerb(method) << " " << url << " "
|
||||
<< headers << llendl;
|
||||
|
||||
// Insert custom headers if the caller sent any
|
||||
if (headers.isMap())
|
||||
{
|
||||
if (headers.has("Cookie"))
|
||||
{
|
||||
req->allowCookies();
|
||||
}
|
||||
req->checkRootCertificate(true);
|
||||
|
||||
// Insert custom headers is the caller sent any
|
||||
if (headers.isMap())
|
||||
{
|
||||
LLSD::map_const_iterator iter = headers.beginMap();
|
||||
LLSD::map_const_iterator end = headers.endMap();
|
||||
|
||||
@@ -429,16 +404,11 @@ static LLSD blocking_request(
|
||||
{
|
||||
lldebugs << "blockingRequest of " << url << llendl;
|
||||
char curl_error_buffer[CURL_ERROR_SIZE] = "\0";
|
||||
CURL* curlp = LLCurl::newEasyHandle();
|
||||
llassert_always(curlp != NULL) ;
|
||||
|
||||
CURL* curlp = curl_easy_init();
|
||||
LLHTTPBuffer http_buffer;
|
||||
std::string body_str;
|
||||
|
||||
// other request method checks root cert first, we skip?
|
||||
|
||||
// Apply configured proxy settings
|
||||
LLProxy::getInstance()->applyProxySettings(curlp);
|
||||
|
||||
// * Set curl handle options
|
||||
curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1); // don't use SIGALRM for timeouts
|
||||
@@ -447,7 +417,7 @@ static LLSD blocking_request(
|
||||
curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);
|
||||
curl_easy_setopt(curlp, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(curlp, CURLOPT_ERRORBUFFER, curl_error_buffer);
|
||||
|
||||
|
||||
// * Setup headers (don't forget to free them after the call!)
|
||||
curl_slist* headers_list = NULL;
|
||||
if (headers.isMap())
|
||||
@@ -525,7 +495,7 @@ static LLSD blocking_request(
|
||||
}
|
||||
|
||||
// * Cleanup
|
||||
LLCurl::deleteEasyHandle(curlp);
|
||||
curl_easy_cleanup(curlp);
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -625,8 +595,7 @@ bool LLHTTPClient::hasPump()
|
||||
return theClientPump != NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
LLPumpIO& LLHTTPClient::getPump()
|
||||
LLPumpIO &LLHTTPClient::getPump()
|
||||
{
|
||||
return *theClientPump;
|
||||
}
|
||||
|
||||
@@ -34,10 +34,11 @@
|
||||
#include <string>
|
||||
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include "llurlrequest.h"
|
||||
|
||||
#include "llassettype.h"
|
||||
#include "llcurl.h"
|
||||
#include "lliopipe.h"
|
||||
#include "llurlrequest.h"
|
||||
|
||||
extern const F32 HTTP_REQUEST_EXPIRY_SECS;
|
||||
|
||||
@@ -55,7 +56,6 @@ public:
|
||||
typedef LLCurl::Responder Responder;
|
||||
typedef LLCurl::ResponderPtr ResponderPtr;
|
||||
|
||||
|
||||
/** @name non-blocking API */
|
||||
//@{
|
||||
static void head(
|
||||
@@ -153,12 +153,6 @@ public:
|
||||
///< for testing
|
||||
static LLPumpIO &getPump();
|
||||
///< Hippo special
|
||||
|
||||
static void setCertVerifyCallback(LLURLRequest::SSLCertVerifyCallback callback);
|
||||
static LLURLRequest::SSLCertVerifyCallback getCertVerifyCallback() { return mCertVerifyCallback; }
|
||||
|
||||
protected:
|
||||
static LLURLRequest::SSLCertVerifyCallback mCertVerifyCallback;
|
||||
};
|
||||
|
||||
#endif // LL_LLHTTPCLIENT_H
|
||||
|
||||
@@ -32,17 +32,17 @@
|
||||
#include <algorithm>
|
||||
#include <openssl/x509_vfy.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "llcurl.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llioutil.h"
|
||||
#include "llmemtype.h"
|
||||
#include "llproxy.h"
|
||||
#include "llpumpio.h"
|
||||
#include "llsd.h"
|
||||
#include "llstring.h"
|
||||
#include "apr_env.h"
|
||||
#include "llapr.h"
|
||||
#include "llscopedvolatileaprpool.h"
|
||||
#include "llfasttimer.h"
|
||||
static const U32 HTTP_STATUS_PIPE_ERROR = 499;
|
||||
|
||||
/**
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
~LLURLRequestDetail();
|
||||
std::string mURL;
|
||||
LLCurlEasyRequest* mCurlRequest;
|
||||
LLIOPipe::buffer_ptr_t mResponseBuffer;
|
||||
LLBufferArray* mResponseBuffer;
|
||||
LLChannelDescriptors mChannels;
|
||||
U8* mLastRead;
|
||||
U32 mBodyLimit;
|
||||
@@ -77,60 +77,24 @@ public:
|
||||
|
||||
LLURLRequestDetail::LLURLRequestDetail() :
|
||||
mCurlRequest(NULL),
|
||||
mResponseBuffer(NULL),
|
||||
mLastRead(NULL),
|
||||
mBodyLimit(0),
|
||||
mByteAccumulator(0),
|
||||
mIsBodyLimitSet(false),
|
||||
mSSLVerifyCallback(NULL)
|
||||
mIsBodyLimitSet(false)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mCurlRequest = new LLCurlEasyRequest();
|
||||
|
||||
if(!mCurlRequest->isValid()) //failed.
|
||||
{
|
||||
delete mCurlRequest ;
|
||||
mCurlRequest = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
LLURLRequestDetail::~LLURLRequestDetail()
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
delete mCurlRequest;
|
||||
mResponseBuffer = NULL;
|
||||
mLastRead = NULL;
|
||||
}
|
||||
|
||||
void LLURLRequest::setSSLVerifyCallback(SSLCertVerifyCallback callback, void *param)
|
||||
{
|
||||
mDetail->mSSLVerifyCallback = callback;
|
||||
mDetail->mCurlRequest->setSSLCtxCallback(LLURLRequest::_sslCtxCallback, (void *)this);
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, true);
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYHOST, 2);
|
||||
}
|
||||
|
||||
|
||||
// _sslCtxFunction
|
||||
// Callback function called when an SSL Context is created via CURL
|
||||
// used to configure the context for custom cert validation
|
||||
|
||||
CURLcode LLURLRequest::_sslCtxCallback(CURL * curl, void *sslctx, void *param)
|
||||
{
|
||||
LLURLRequest *req = (LLURLRequest *)param;
|
||||
if(req == NULL || req->mDetail->mSSLVerifyCallback == NULL)
|
||||
{
|
||||
SSL_CTX_set_cert_verify_callback((SSL_CTX *)sslctx, NULL, NULL);
|
||||
return CURLE_OK;
|
||||
}
|
||||
SSL_CTX * ctx = (SSL_CTX *) sslctx;
|
||||
// disable any default verification for server certs
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
|
||||
// set the verification callback.
|
||||
SSL_CTX_set_cert_verify_callback(ctx, req->mDetail->mSSLVerifyCallback, (void *)req);
|
||||
// the calls are void
|
||||
return CURLE_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* class LLURLRequest
|
||||
*/
|
||||
@@ -189,13 +153,19 @@ std::string LLURLRequest::getURL() const
|
||||
{
|
||||
return mDetail->mURL;
|
||||
}
|
||||
|
||||
void LLURLRequest::addHeader(const char* header)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mDetail->mCurlRequest->slist_append(header);
|
||||
}
|
||||
|
||||
void LLURLRequest::checkRootCertificate(bool check)
|
||||
{
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_SSL_VERIFYPEER, (check? TRUE : FALSE));
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, "");
|
||||
}
|
||||
|
||||
|
||||
void LLURLRequest::setBodyLimit(U32 size)
|
||||
{
|
||||
mDetail->mBodyLimit = size;
|
||||
@@ -240,9 +210,9 @@ void LLURLRequest::useProxy(bool use_proxy)
|
||||
}
|
||||
}
|
||||
|
||||
lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl;
|
||||
LL_DEBUGS("Proxy") << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (!env_proxy.empty() ? env_proxy : "(null)") << LL_ENDL;
|
||||
|
||||
if (use_proxy)
|
||||
if (use_proxy && !env_proxy.empty())
|
||||
{
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy);
|
||||
}
|
||||
@@ -262,24 +232,12 @@ void LLURLRequest::allowCookies()
|
||||
mDetail->mCurlRequest->setoptString(CURLOPT_COOKIEFILE, "");
|
||||
}
|
||||
|
||||
//virtual
|
||||
bool LLURLRequest::isValid()
|
||||
{
|
||||
return mDetail->mCurlRequest && mDetail->mCurlRequest->isValid();
|
||||
}
|
||||
|
||||
// virtual
|
||||
LLIOPipe::EStatus LLURLRequest::handleError(
|
||||
LLIOPipe::EStatus status,
|
||||
LLPumpIO* pump)
|
||||
{
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
|
||||
if(!isValid())
|
||||
{
|
||||
return STATUS_EXPIRED ;
|
||||
}
|
||||
|
||||
if(mCompletionCallback && pump)
|
||||
{
|
||||
LLURLRequestComplete* complete = NULL;
|
||||
@@ -309,7 +267,8 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
//llinfos << "LLURLRequest::process_impl()" << llendl;
|
||||
if (!buffer) return STATUS_ERROR;
|
||||
|
||||
if (!mDetail) return STATUS_ERROR; //Seems to happen on occasion. Need to hunt down why.
|
||||
|
||||
// we're still waiting or prcessing, check how many
|
||||
// bytes we have accumulated.
|
||||
const S32 MIN_ACCUMULATION = 100000;
|
||||
@@ -348,7 +307,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
||||
|
||||
// *FIX: bit of a hack, but it should work. The configure and
|
||||
// callback method expect this information to be ready.
|
||||
mDetail->mResponseBuffer = buffer;
|
||||
mDetail->mResponseBuffer = buffer.get();
|
||||
mDetail->mChannels = channels;
|
||||
if(!configure())
|
||||
{
|
||||
@@ -367,10 +326,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl(
|
||||
static LLFastTimer::DeclareTimer FTM_URL_PERFORM("Perform");
|
||||
{
|
||||
LLFastTimer t(FTM_URL_PERFORM);
|
||||
if(!mDetail->mCurlRequest->wait())
|
||||
{
|
||||
return status ;
|
||||
}
|
||||
mDetail->mCurlRequest->perform();
|
||||
}
|
||||
|
||||
while(1)
|
||||
@@ -465,12 +421,6 @@ void LLURLRequest::initialize()
|
||||
LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST);
|
||||
mState = STATE_INITIALIZED;
|
||||
mDetail = new LLURLRequestDetail;
|
||||
|
||||
if(!isValid())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
mDetail->mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
|
||||
mDetail->mCurlRequest->setWriteCallback(&downCallback, (void*)this);
|
||||
mDetail->mCurlRequest->setReadCallback(&upCallback, (void*)this);
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "llerror.h"
|
||||
#include "llcurl.h"
|
||||
|
||||
|
||||
extern const std::string CONTEXT_REQUEST;
|
||||
extern const std::string CONTEXT_DEST_URI_SD_LABEL;
|
||||
extern const std::string CONTEXT_RESPONSE;
|
||||
@@ -143,9 +142,8 @@ public:
|
||||
* Set whether request will check that remote server
|
||||
* certificates are signed by a known root CA when using HTTPS.
|
||||
*/
|
||||
void setSSLVerifyCallback(SSLCertVerifyCallback callback, void * param);
|
||||
void checkRootCertificate(bool check);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return at most size bytes of body.
|
||||
*
|
||||
@@ -190,14 +188,11 @@ public:
|
||||
*/
|
||||
void allowCookies();
|
||||
|
||||
/*virtual*/ bool isValid() ;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Give this pipe a chance to handle a generated error
|
||||
*/
|
||||
virtual EStatus handleError(EStatus status, LLPumpIO* pump);
|
||||
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -223,11 +218,9 @@ protected:
|
||||
ERequestAction mAction;
|
||||
LLURLRequestDetail* mDetail;
|
||||
LLIOPipe::ptr_t mCompletionCallback;
|
||||
S32 mRequestTransferedBytes;
|
||||
S32 mResponseTransferedBytes;
|
||||
S32 mRequestTransferedBytes;
|
||||
S32 mResponseTransferedBytes;
|
||||
|
||||
static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Initialize the object. Called during construction.
|
||||
|
||||
@@ -945,7 +945,6 @@ char const* const _PREHASH_SysGPU = LLMessageStringTable::getInstance()->getStri
|
||||
char const* const _PREHASH_AvatarInterestsReply = LLMessageStringTable::getInstance()->getString("AvatarInterestsReply");
|
||||
char const* const _PREHASH_StartLure = LLMessageStringTable::getInstance()->getString("StartLure");
|
||||
char const* const _PREHASH_SysRAM = LLMessageStringTable::getInstance()->getString("SysRAM");
|
||||
char const* const _PREHASH_ObjectPosition = LLMessageStringTable::getInstance()->getString("ObjectPosition");
|
||||
char const* const _PREHASH_SitPosition = LLMessageStringTable::getInstance()->getString("SitPosition");
|
||||
char const* const _PREHASH_StartTime = LLMessageStringTable::getInstance()->getString("StartTime");
|
||||
char const* const _PREHASH_BornOn = LLMessageStringTable::getInstance()->getString("BornOn");
|
||||
@@ -1001,7 +1000,6 @@ char const* const _PREHASH_SnapshotID = LLMessageStringTable::getInstance()->get
|
||||
char const* const _PREHASH_Aspect = LLMessageStringTable::getInstance()->getString("Aspect");
|
||||
char const* const _PREHASH_ParamSize = LLMessageStringTable::getInstance()->getString("ParamSize");
|
||||
char const* const _PREHASH_VoteCast = LLMessageStringTable::getInstance()->getString("VoteCast");
|
||||
char const* const _PREHASH_CastsShadows = LLMessageStringTable::getInstance()->getString("CastsShadows");
|
||||
char const* const _PREHASH_EveryoneMask = LLMessageStringTable::getInstance()->getString("EveryoneMask");
|
||||
char const* const _PREHASH_ObjectSpinUpdate = LLMessageStringTable::getInstance()->getString("ObjectSpinUpdate");
|
||||
char const* const _PREHASH_MaturePublish = LLMessageStringTable::getInstance()->getString("MaturePublish");
|
||||
@@ -1050,7 +1048,6 @@ char const* const _PREHASH_SimIP = LLMessageStringTable::getInstance()->getStrin
|
||||
char const* const _PREHASH_GodID = LLMessageStringTable::getInstance()->getString("GodID");
|
||||
char const* const _PREHASH_TeleportMinPrice = LLMessageStringTable::getInstance()->getString("TeleportMinPrice");
|
||||
char const* const _PREHASH_VoteItem = LLMessageStringTable::getInstance()->getString("VoteItem");
|
||||
char const* const _PREHASH_ObjectRotation = LLMessageStringTable::getInstance()->getString("ObjectRotation");
|
||||
char const* const _PREHASH_SitRotation = LLMessageStringTable::getInstance()->getString("SitRotation");
|
||||
char const* const _PREHASH_SnapSelection = LLMessageStringTable::getInstance()->getString("SnapSelection");
|
||||
char const* const _PREHASH_SoundTrigger = LLMessageStringTable::getInstance()->getString("SoundTrigger");
|
||||
|
||||
@@ -945,7 +945,6 @@ extern char const* const _PREHASH_SysGPU;
|
||||
extern char const* const _PREHASH_AvatarInterestsReply;
|
||||
extern char const* const _PREHASH_StartLure;
|
||||
extern char const* const _PREHASH_SysRAM;
|
||||
extern char const* const _PREHASH_ObjectPosition;
|
||||
extern char const* const _PREHASH_SitPosition;
|
||||
extern char const* const _PREHASH_StartTime;
|
||||
extern char const* const _PREHASH_BornOn;
|
||||
@@ -1001,7 +1000,6 @@ extern char const* const _PREHASH_SnapshotID;
|
||||
extern char const* const _PREHASH_Aspect;
|
||||
extern char const* const _PREHASH_ParamSize;
|
||||
extern char const* const _PREHASH_VoteCast;
|
||||
extern char const* const _PREHASH_CastsShadows;
|
||||
extern char const* const _PREHASH_EveryoneMask;
|
||||
extern char const* const _PREHASH_ObjectSpinUpdate;
|
||||
extern char const* const _PREHASH_MaturePublish;
|
||||
@@ -1050,7 +1048,6 @@ extern char const* const _PREHASH_SimIP;
|
||||
extern char const* const _PREHASH_GodID;
|
||||
extern char const* const _PREHASH_TeleportMinPrice;
|
||||
extern char const* const _PREHASH_VoteItem;
|
||||
extern char const* const _PREHASH_ObjectRotation;
|
||||
extern char const* const _PREHASH_SitRotation;
|
||||
extern char const* const _PREHASH_SnapSelection;
|
||||
extern char const* const _PREHASH_SoundTrigger;
|
||||
|
||||
@@ -239,7 +239,7 @@ public:
|
||||
std::string getHoverText() const { return mHoverText; };
|
||||
std::string getHoverLink() const { return mHoverLink; };
|
||||
|
||||
std::string getMediaName() const { return mMediaName; };
|
||||
const std::string& getMediaName() const { return mMediaName; };
|
||||
std::string getMediaDescription() const { return mMediaDescription; };
|
||||
|
||||
// Crash the plugin. If you use this outside of a testbed, you will be punished.
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file object_flags.h
|
||||
* @brief Flags for object creation and transmission
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
@@ -34,43 +28,47 @@
|
||||
#define LL_OBJECT_FLAGS_H
|
||||
|
||||
// downstream flags from sim->viewer
|
||||
const U32 FLAGS_USE_PHYSICS = 0x00000001;
|
||||
const U32 FLAGS_CREATE_SELECTED = 0x00000002;
|
||||
const U32 FLAGS_OBJECT_MODIFY = 0x00000004;
|
||||
const U32 FLAGS_OBJECT_COPY = 0x00000008;
|
||||
const U32 FLAGS_OBJECT_ANY_OWNER = 0x00000010;
|
||||
const U32 FLAGS_OBJECT_YOU_OWNER = 0x00000020;
|
||||
const U32 FLAGS_SCRIPTED = 0x00000040;
|
||||
const U32 FLAGS_HANDLE_TOUCH = 0x00000080;
|
||||
const U32 FLAGS_OBJECT_MOVE = 0x00000100;
|
||||
const U32 FLAGS_TAKES_MONEY = 0x00000200;
|
||||
const U32 FLAGS_PHANTOM = 0x00000400;
|
||||
const U32 FLAGS_INVENTORY_EMPTY = 0x00000800;
|
||||
const U32 FLAGS_USE_PHYSICS = (1U << 0);
|
||||
const U32 FLAGS_CREATE_SELECTED = (1U << 1);
|
||||
const U32 FLAGS_OBJECT_MODIFY = (1U << 2);
|
||||
const U32 FLAGS_OBJECT_COPY = (1U << 3);
|
||||
const U32 FLAGS_OBJECT_ANY_OWNER = (1U << 4);
|
||||
const U32 FLAGS_OBJECT_YOU_OWNER = (1U << 5);
|
||||
const U32 FLAGS_SCRIPTED = (1U << 6);
|
||||
const U32 FLAGS_HANDLE_TOUCH = (1U << 7);
|
||||
const U32 FLAGS_OBJECT_MOVE = (1U << 8);
|
||||
const U32 FLAGS_TAKES_MONEY = (1U << 9);
|
||||
const U32 FLAGS_PHANTOM = (1U << 10);
|
||||
const U32 FLAGS_INVENTORY_EMPTY = (1U << 11);
|
||||
|
||||
const U32 FLAGS_JOINT_HINGE = 0x00001000;
|
||||
const U32 FLAGS_JOINT_P2P = 0x00002000;
|
||||
const U32 FLAGS_JOINT_LP2P = 0x00004000;
|
||||
// const U32 FLAGS_JOINT_WHEEL = 0x00008000;
|
||||
const U32 FLAGS_INCLUDE_IN_SEARCH = 0x00008000;
|
||||
const U32 FLAGS_AFFECTS_NAVMESH = (1U << 12);
|
||||
const U32 FLAGS_CHARACTER = (1U << 13);
|
||||
const U32 FLAGS_VOLUME_DETECT = (1U << 14);
|
||||
const U32 FLAGS_INCLUDE_IN_SEARCH = (1U << 15);
|
||||
|
||||
const U32 FLAGS_ALLOW_INVENTORY_DROP = 0x00010000;
|
||||
const U32 FLAGS_OBJECT_TRANSFER = 0x00020000;
|
||||
const U32 FLAGS_OBJECT_GROUP_OWNED = 0x00040000;
|
||||
//const U32 FLAGS_OBJECT_YOU_OFFICER = 0x00080000;
|
||||
const U32 FLAGS_ALLOW_INVENTORY_DROP = (1U << 16);
|
||||
const U32 FLAGS_OBJECT_TRANSFER = (1U << 17);
|
||||
const U32 FLAGS_OBJECT_GROUP_OWNED = (1U << 18);
|
||||
//const U32 FLAGS_UNUSED_000 = (1U << 19); // was FLAGS_OBJECT_YOU_OFFICER
|
||||
|
||||
const U32 FLAGS_CAMERA_DECOUPLED = 0x00100000;
|
||||
const U32 FLAGS_ANIM_SOURCE = 0x00200000;
|
||||
const U32 FLAGS_CAMERA_SOURCE = 0x00400000;
|
||||
const U32 FLAGS_CAMERA_DECOUPLED = (1U << 20);
|
||||
const U32 FLAGS_ANIM_SOURCE = (1U << 21);
|
||||
const U32 FLAGS_CAMERA_SOURCE = (1U << 22);
|
||||
|
||||
const U32 FLAGS_CAST_SHADOWS = 0x00800000;
|
||||
//const U32 FLAGS_UNUSED_001 = (1U << 23); // was FLAGS_CAST_SHADOWS
|
||||
|
||||
const U32 FLAGS_OBJECT_OWNER_MODIFY = 0x10000000;
|
||||
//const U32 FLAGS_UNUSED_002 = (1U << 24);
|
||||
//const U32 FLAGS_UNUSED_003 = (1U << 25);
|
||||
//const U32 FLAGS_UNUSED_004 = (1U << 26);
|
||||
//const U32 FLAGS_UNUSED_005 = (1U << 27);
|
||||
|
||||
const U32 FLAGS_TEMPORARY_ON_REZ = 0x20000000;
|
||||
const U32 FLAGS_TEMPORARY = 0x40000000;
|
||||
const U32 FLAGS_ZLIB_COMPRESSED = 0x80000000;
|
||||
const U32 FLAGS_OBJECT_OWNER_MODIFY = (1U << 28);
|
||||
|
||||
const U32 FLAGS_LOCAL = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
|
||||
const U32 FLAGS_TEMPORARY_ON_REZ = (1U << 29);
|
||||
const U32 FLAGS_TEMPORARY = (1U << 30);
|
||||
//const U32 FLAGS_UNUSED_007 = (1U << 31); // was FLAGS_ZLIB_COMPRESSED
|
||||
|
||||
const U32 FLAGS_LOCAL = FLAGS_ANIM_SOURCE | FLAGS_CAMERA_SOURCE;
|
||||
|
||||
typedef enum e_havok_joint_type
|
||||
{
|
||||
|
||||
@@ -2001,7 +2001,6 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
|
||||
|
||||
void LLImageGL::setCategory(S32 category)
|
||||
{
|
||||
#if 0 //turn this off temporarily because it is not in use now.
|
||||
if(!gAuditTexture)
|
||||
{
|
||||
return ;
|
||||
@@ -2022,7 +2021,6 @@ void LLImageGL::setCategory(S32 category)
|
||||
mCategory = -1 ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//for debug use
|
||||
@@ -2053,14 +2051,16 @@ S32 LLImageGL::getTextureCounterIndex(U32 val)
|
||||
void LLImageGL::incTextureCounter(U32 val, S32 ncomponents, S32 category)
|
||||
{
|
||||
sTextureLoadedCounter[getTextureCounterIndex(val)]++ ;
|
||||
sTextureMemByCategory[category] += (S32)val * ncomponents ;
|
||||
if(category > -1)
|
||||
sTextureMemByCategory[category] += (S32)val * ncomponents ;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLImageGL::decTextureCounter(U32 val, S32 ncomponents, S32 category)
|
||||
{
|
||||
sTextureLoadedCounter[getTextureCounterIndex(val)]-- ;
|
||||
sTextureMemByCategory[category] += (S32)val * ncomponents ;
|
||||
if(category > -1)
|
||||
sTextureMemByCategory[category] -= (S32)val * ncomponents ;
|
||||
}
|
||||
|
||||
void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size)
|
||||
|
||||
@@ -33,34 +33,247 @@
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llpostprocess.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llrender.h"
|
||||
#include "llvertexbuffer.h"
|
||||
|
||||
#include "lldir.h"
|
||||
#include "llgl.h"
|
||||
#include "llglslshader.h"
|
||||
#include "llrender.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsdutil_math.h"
|
||||
#include "llvertexbuffer.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
extern LLGLSLShader gPostColorFilterProgram;
|
||||
extern LLGLSLShader gPostNightVisionProgram;
|
||||
extern LLGLSLShader gPostGaussianBlurProgram;
|
||||
extern LLGLSLShader gPostPosterizeProgram;
|
||||
|
||||
static const unsigned int NOISE_SIZE = 512;
|
||||
|
||||
/// CALCULATING LUMINANCE (Using NTSC lum weights)
|
||||
/// http://en.wikipedia.org/wiki/Luma_%28video%29
|
||||
static const float LUMINANCE_R = 0.299f;
|
||||
static const float LUMINANCE_G = 0.587f;
|
||||
static const float LUMINANCE_B = 0.114f;
|
||||
|
||||
static const char * const XML_FILENAME = "postprocesseffects.xml";
|
||||
|
||||
LLPostProcess::LLPostProcess(void) :
|
||||
mVBO(NULL),
|
||||
mAllEffects(LLSD::emptyMap()),
|
||||
mScreenWidth(1), mScreenHeight(1)
|
||||
template<> LLSD LLPostProcessShader::LLShaderSetting<LLVector4>::getDefaultValue()
|
||||
{
|
||||
mSceneRenderTexture = NULL ;
|
||||
mNoiseTexture = NULL ;
|
||||
|
||||
return mDefault.getValue();
|
||||
}
|
||||
template<> void LLPostProcessShader::LLShaderSetting<LLVector4>::setValue(const LLSD& value)
|
||||
{
|
||||
mValue = ll_vector4_from_sd(value);
|
||||
}
|
||||
|
||||
LLSD LLPostProcessShader::getDefaults()
|
||||
{
|
||||
LLSD defaults;
|
||||
for(std::vector<LLShaderSettingBase*>::iterator it=mSettings.begin();it!=mSettings.end();++it)
|
||||
{
|
||||
defaults[(*it)->mSettingName]=(*it)->getDefaultValue();
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
void LLPostProcessShader::loadSettings(const LLSD& settings)
|
||||
{
|
||||
for(std::vector<LLShaderSettingBase*>::iterator it=mSettings.begin();it!=mSettings.end();++it)
|
||||
{
|
||||
LLSD value = settings[(*it)->mSettingName];
|
||||
(*it)->setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
class LLColorFilterShader : public LLPostProcessShader
|
||||
{
|
||||
private:
|
||||
LLShaderSetting<bool> mEnabled;
|
||||
LLShaderSetting<F32> mGamma, mBrightness, mContrast, mSaturation;
|
||||
LLShaderSetting<LLVector4> mContrastBase;
|
||||
public:
|
||||
LLColorFilterShader() :
|
||||
mEnabled("enable_color_filter",false),
|
||||
mGamma("gamma",1.f),
|
||||
mBrightness("brightness",1.f),
|
||||
mContrast("contrast",1.f),
|
||||
mSaturation("saturation",1.f),
|
||||
mContrastBase("contrast_base",LLVector4(1.f,1.f,1.f,0.5f))
|
||||
{
|
||||
mSettings.push_back(&mEnabled);
|
||||
mSettings.push_back(&mGamma);
|
||||
mSettings.push_back(&mBrightness);
|
||||
mSettings.push_back(&mContrast);
|
||||
mSettings.push_back(&mSaturation);
|
||||
mSettings.push_back(&mContrastBase);
|
||||
}
|
||||
|
||||
bool isEnabled() { return mEnabled && gPostColorFilterProgram.mProgramObject; }
|
||||
S32 getColorChannel() { return 0; }
|
||||
S32 getDepthChannel() { return -1; }
|
||||
|
||||
QuadType bind()
|
||||
{
|
||||
if(!isEnabled())
|
||||
return QUAD_NONE;
|
||||
|
||||
/// CALCULATING LUMINANCE (Using NTSC lum weights)
|
||||
/// http://en.wikipedia.org/wiki/Luma_%28video%29
|
||||
static const float LUMINANCE_R = 0.299f;
|
||||
static const float LUMINANCE_G = 0.587f;
|
||||
static const float LUMINANCE_B = 0.114f;
|
||||
|
||||
gPostColorFilterProgram.bind();
|
||||
|
||||
gPostColorFilterProgram.uniform1f("gamma", mGamma);
|
||||
gPostColorFilterProgram.uniform1f("brightness", mBrightness);
|
||||
gPostColorFilterProgram.uniform1f("contrast", mContrast);
|
||||
float baseI = (mContrastBase.mValue[VX] + mContrastBase.mValue[VY] + mContrastBase.mValue[VZ]) / 3.0f;
|
||||
baseI = mContrastBase.mValue[VW] / ((baseI < 0.001f) ? 0.001f : baseI);
|
||||
float baseR = mContrastBase.mValue[VX] * baseI;
|
||||
float baseG = mContrastBase.mValue[VY] * baseI;
|
||||
float baseB = mContrastBase.mValue[VZ] * baseI;
|
||||
gPostColorFilterProgram.uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV);
|
||||
gPostColorFilterProgram.uniform1f("saturation", mSaturation);
|
||||
gPostColorFilterProgram.uniform3fv("lumWeights", 1, LLVector3(LUMINANCE_R, LUMINANCE_G, LUMINANCE_B).mV);
|
||||
return QUAD_NORMAL;
|
||||
}
|
||||
bool draw(U32 pass) {return pass == 1;}
|
||||
void unbind()
|
||||
{
|
||||
gPostColorFilterProgram.unbind();
|
||||
}
|
||||
};
|
||||
|
||||
class LLNightVisionShader : public LLPostProcessShader
|
||||
{
|
||||
private:
|
||||
LLShaderSetting<bool> mEnabled;
|
||||
LLShaderSetting<F32> mBrightnessMult, mNoiseStrength;
|
||||
public:
|
||||
LLNightVisionShader() :
|
||||
mEnabled("enable_night_vision",false),
|
||||
mBrightnessMult("brightness_multiplier",3.f),
|
||||
mNoiseStrength("noise_strength",.4f)
|
||||
{
|
||||
mSettings.push_back(&mEnabled);
|
||||
mSettings.push_back(&mBrightnessMult);
|
||||
mSettings.push_back(&mNoiseStrength);
|
||||
}
|
||||
bool isEnabled() { return mEnabled && gPostNightVisionProgram.mProgramObject; }
|
||||
S32 getColorChannel() { return 0; }
|
||||
S32 getDepthChannel() { return -1; }
|
||||
QuadType bind()
|
||||
{
|
||||
if(!isEnabled())
|
||||
return QUAD_NONE;
|
||||
|
||||
gPostNightVisionProgram.bind();
|
||||
|
||||
LLPostProcess::getInstance()->bindNoise(1);
|
||||
|
||||
gPostNightVisionProgram.uniform1f("brightMult", mBrightnessMult);
|
||||
gPostNightVisionProgram.uniform1f("noiseStrength", mNoiseStrength);
|
||||
|
||||
return QUAD_NOISE;
|
||||
|
||||
}
|
||||
bool draw(U32 pass) {return pass == 1;}
|
||||
void unbind()
|
||||
{
|
||||
gPostNightVisionProgram.unbind();
|
||||
}
|
||||
};
|
||||
|
||||
class LLGaussBlurShader : public LLPostProcessShader
|
||||
{
|
||||
private:
|
||||
LLShaderSetting<bool> mEnabled;
|
||||
LLShaderSetting<S32> mNumPasses;
|
||||
GLint mPassLoc;
|
||||
public:
|
||||
LLGaussBlurShader() :
|
||||
mEnabled("enable_gauss_blur",false),
|
||||
mNumPasses("gauss_blur_passes",2),
|
||||
mPassLoc(0)
|
||||
{
|
||||
mSettings.push_back(&mEnabled);
|
||||
mSettings.push_back(&mNumPasses);
|
||||
}
|
||||
bool isEnabled() { return mEnabled && mNumPasses && gPostGaussianBlurProgram.mProgramObject; }
|
||||
S32 getColorChannel() { return 0; }
|
||||
S32 getDepthChannel() { return -1; }
|
||||
QuadType bind()
|
||||
{
|
||||
if(!isEnabled())
|
||||
return QUAD_NONE;
|
||||
|
||||
gPostGaussianBlurProgram.bind();
|
||||
|
||||
mPassLoc = gPostGaussianBlurProgram.getUniformLocation("horizontalPass");
|
||||
|
||||
return QUAD_NORMAL;
|
||||
}
|
||||
bool draw(U32 pass)
|
||||
{
|
||||
if((S32)pass > mNumPasses*2)
|
||||
return false;
|
||||
glUniform1iARB(mPassLoc, (pass-1) % 2);
|
||||
return true;
|
||||
}
|
||||
void unbind()
|
||||
{
|
||||
gPostGaussianBlurProgram.unbind();
|
||||
}
|
||||
};
|
||||
|
||||
class LLPosterizeShader : public LLPostProcessShader
|
||||
{
|
||||
private:
|
||||
LLShaderSetting<bool> mEnabled;
|
||||
LLShaderSetting<S32> mNumLayers;
|
||||
public:
|
||||
LLPosterizeShader() :
|
||||
mEnabled("enable_posterize",false),
|
||||
mNumLayers("posterize_layers",2)
|
||||
{
|
||||
mSettings.push_back(&mEnabled);
|
||||
mSettings.push_back(&mNumLayers);
|
||||
}
|
||||
bool isEnabled() { return mEnabled && gPostPosterizeProgram.mProgramObject; }
|
||||
S32 getColorChannel() { return 0; }
|
||||
S32 getDepthChannel() { return -1; }
|
||||
QuadType bind()
|
||||
{
|
||||
if(!isEnabled())
|
||||
return QUAD_NONE;
|
||||
|
||||
gPostPosterizeProgram.bind();
|
||||
|
||||
gPostPosterizeProgram.uniform1i("layerCount", mNumLayers);
|
||||
|
||||
return QUAD_NORMAL;
|
||||
}
|
||||
bool draw(U32 pass)
|
||||
{
|
||||
return pass == 1;
|
||||
}
|
||||
void unbind()
|
||||
{
|
||||
gPostPosterizeProgram.unbind();
|
||||
}
|
||||
};
|
||||
|
||||
LLPostProcess::LLPostProcess(void) :
|
||||
mVBO(NULL),
|
||||
mDepthTexture(0),
|
||||
mNoiseTexture(NULL),
|
||||
mScreenWidth(0),
|
||||
mScreenHeight(0),
|
||||
mNoiseTextureScale(0.f),
|
||||
mSelectedEffectInfo(LLSD::emptyMap()),
|
||||
mAllEffectInfo(LLSD::emptyMap())
|
||||
{
|
||||
mShaders.push_back(new LLColorFilterShader());
|
||||
mShaders.push_back(new LLNightVisionShader());
|
||||
mShaders.push_back(new LLGaussBlurShader());
|
||||
mShaders.push_back(new LLPosterizeShader());
|
||||
|
||||
/* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.*/
|
||||
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
|
||||
LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL;
|
||||
@@ -71,99 +284,43 @@ LLPostProcess::LLPostProcess(void) :
|
||||
{
|
||||
LLPointer<LLSDParser> parser = new LLSDXMLParser();
|
||||
|
||||
parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED);
|
||||
parser->parse(effectsXML, mAllEffectInfo, LLSDSerialize::SIZE_UNLIMITED);
|
||||
}
|
||||
|
||||
if (!mAllEffects.has("default"))
|
||||
if (!mAllEffectInfo.has("default"))
|
||||
mAllEffectInfo["default"] = LLSD::emptyMap();
|
||||
|
||||
LLSD& defaults = mAllEffectInfo["default"];
|
||||
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap());
|
||||
|
||||
/*defaultEffect["enable_night_vision"] = LLSD::Boolean(false);
|
||||
defaultEffect["enable_color_filter"] = LLSD::Boolean(false);*/
|
||||
|
||||
/// NVG Defaults
|
||||
defaultEffect["brightness_multiplier"] = 3.0;
|
||||
defaultEffect["noise_size"] = 25.0;
|
||||
defaultEffect["noise_strength"] = 0.4;
|
||||
|
||||
// TODO BTest potentially add this to tweaks?
|
||||
mNoiseTextureScale = 1.0f;
|
||||
|
||||
/// Color Filter Defaults
|
||||
defaultEffect["gamma"] = 1.0;
|
||||
defaultEffect["brightness"] = 1.0;
|
||||
defaultEffect["contrast"] = 1.0;
|
||||
defaultEffect["saturation"] = 1.0;
|
||||
|
||||
LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray());
|
||||
contrastBase.append(1.0);
|
||||
contrastBase.append(1.0);
|
||||
contrastBase.append(1.0);
|
||||
contrastBase.append(0.5);
|
||||
|
||||
defaultEffect["gauss_blur_passes"] = 2;
|
||||
LLSD shader_defaults = (*it)->getDefaults();
|
||||
for (LLSD::map_const_iterator it2 = defaults.beginMap();it2 != defaults.endMap();++it2)
|
||||
{
|
||||
if(!defaults.has(it2->first))
|
||||
defaults[it2->first]=it2->second;
|
||||
}
|
||||
}
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
(*it)->loadSettings(defaults);
|
||||
}
|
||||
|
||||
setSelectedEffect("default");
|
||||
// */
|
||||
}
|
||||
|
||||
LLPostProcess::~LLPostProcess(void)
|
||||
{
|
||||
invalidate() ;
|
||||
}
|
||||
|
||||
/*static*/void LLPostProcess::cleanupClass()
|
||||
{
|
||||
if(instanceExists())
|
||||
getInstance()->invalidate() ;
|
||||
}
|
||||
|
||||
void LLPostProcess::setSelectedEffect(std::string const & effectName)
|
||||
{
|
||||
mSelectedEffectName = effectName;
|
||||
static_cast<LLSD &>(tweaks) = mAllEffects[effectName];
|
||||
}
|
||||
|
||||
void LLPostProcess::saveEffect(std::string const & effectName)
|
||||
{
|
||||
mAllEffects[effectName] = tweaks;
|
||||
|
||||
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
|
||||
//llinfos << "Saving PostProcess Effects settings to " << pathName << llendl;
|
||||
|
||||
llofstream effectsXML(pathName);
|
||||
|
||||
LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
|
||||
|
||||
formatter->format(mAllEffects, effectsXML);
|
||||
}
|
||||
void LLPostProcess::invalidate()
|
||||
{
|
||||
mSceneRenderTexture = NULL ;
|
||||
mNoiseTexture = NULL ;
|
||||
mVBO = NULL ;
|
||||
}
|
||||
|
||||
void LLPostProcess::apply(unsigned int width, unsigned int height)
|
||||
{
|
||||
if(shadersEnabled())
|
||||
{
|
||||
if (mVBO.isNull() || width != mScreenWidth || height != mScreenHeight)
|
||||
{
|
||||
initialize(width, height);
|
||||
}
|
||||
doEffects();
|
||||
}
|
||||
destroyGL() ;
|
||||
}
|
||||
|
||||
void LLPostProcess::initialize(unsigned int width, unsigned int height)
|
||||
{
|
||||
invalidate();
|
||||
destroyGL();
|
||||
mScreenWidth = width;
|
||||
mScreenHeight = height;
|
||||
|
||||
createScreenTexture();
|
||||
createScreenTextures();
|
||||
createNoiseTexture();
|
||||
|
||||
//Setup our VBO.
|
||||
{
|
||||
@@ -185,127 +342,129 @@ void LLPostProcess::initialize(unsigned int width, unsigned int height)
|
||||
|
||||
mVBO->flush();
|
||||
}
|
||||
|
||||
checkError();
|
||||
createNoiseTexture();
|
||||
checkError();
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
inline bool LLPostProcess::shadersEnabled(void)
|
||||
void LLPostProcess::createScreenTextures()
|
||||
{
|
||||
return (tweaks.useColorFilter().asBoolean() ||
|
||||
tweaks.useNightVisionShader().asBoolean() ||
|
||||
tweaks.useGaussBlurFilter().asBoolean() );
|
||||
}
|
||||
const LLTexUnit::eTextureType type = LLTexUnit::TT_RECT_TEXTURE;
|
||||
|
||||
void LLPostProcess::applyShaders(void)
|
||||
{
|
||||
bool copy_buffer = false;
|
||||
if (tweaks.useColorFilter())
|
||||
mRenderTarget[0].allocate(mScreenWidth,mScreenHeight,GL_RGBA,FALSE,FALSE,type,FALSE);
|
||||
if(mRenderTarget[0].getFBO())//Only need pingpong between two rendertargets if FBOs are supported.
|
||||
mRenderTarget[1].allocate(mScreenWidth,mScreenHeight,GL_RGBA,FALSE,FALSE,type,FALSE);
|
||||
stop_glerror();
|
||||
|
||||
if(mDepthTexture)
|
||||
LLImageGL::deleteTextures(type, 0, 0, 1, &mDepthTexture, true);
|
||||
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
applyColorFilterShader();
|
||||
checkError();
|
||||
copy_buffer = true;
|
||||
}
|
||||
if (tweaks.useGaussBlurFilter())
|
||||
{
|
||||
/// If any of the above shaders have been called update the frame buffer;
|
||||
if (copy_buffer)
|
||||
copyFrameBuffer();
|
||||
applyGaussBlurShader();
|
||||
checkError();
|
||||
copy_buffer = true;
|
||||
}
|
||||
if (tweaks.useNightVisionShader())
|
||||
{
|
||||
/// If any of the above shaders have been called update the frame buffer;
|
||||
if (copy_buffer)
|
||||
copyFrameBuffer();
|
||||
applyNightVisionShader();
|
||||
checkError();
|
||||
copy_buffer = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLPostProcess::applyColorFilterShader(void)
|
||||
{
|
||||
if(gPostColorFilterProgram.mProgramObject == 0)
|
||||
return;
|
||||
|
||||
gPostColorFilterProgram.bind();
|
||||
|
||||
gGL.getTexUnit(0)->bind(mSceneRenderTexture);
|
||||
|
||||
gPostColorFilterProgram.uniform1f("gamma", tweaks.getGamma());
|
||||
gPostColorFilterProgram.uniform1f("brightness", tweaks.getBrightness());
|
||||
gPostColorFilterProgram.uniform1f("contrast", tweaks.getContrast());
|
||||
float baseI = (tweaks.getContrastBaseR() + tweaks.getContrastBaseG() + tweaks.getContrastBaseB()) / 3.0f;
|
||||
baseI = tweaks.getContrastBaseIntensity() / ((baseI < 0.001f) ? 0.001f : baseI);
|
||||
float baseR = tweaks.getContrastBaseR() * baseI;
|
||||
float baseG = tweaks.getContrastBaseG() * baseI;
|
||||
float baseB = tweaks.getContrastBaseB() * baseI;
|
||||
gPostColorFilterProgram.uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV);
|
||||
gPostColorFilterProgram.uniform1f("saturation", tweaks.getSaturation());
|
||||
gPostColorFilterProgram.uniform3fv("lumWeights", 1, LLVector3(LUMINANCE_R, LUMINANCE_G, LUMINANCE_B).mV);
|
||||
|
||||
/// Draw a screen space quad
|
||||
drawOrthoQuad(QUAD_NORMAL);
|
||||
gPostColorFilterProgram.unbind();
|
||||
}
|
||||
|
||||
void LLPostProcess::applyNightVisionShader(void)
|
||||
{
|
||||
if(gPostNightVisionProgram.mProgramObject == 0)
|
||||
return;
|
||||
|
||||
gPostNightVisionProgram.bind();
|
||||
|
||||
gGL.getTexUnit(0)->bind(mSceneRenderTexture);
|
||||
gGL.getTexUnit(1)->bind(mNoiseTexture);
|
||||
|
||||
gPostNightVisionProgram.uniform1f("brightMult", tweaks.getBrightMult());
|
||||
gPostNightVisionProgram.uniform1f("noiseStrength", tweaks.getNoiseStrength());
|
||||
mNoiseTextureScale = 0.001f + ((100.f - tweaks.getNoiseSize()) / 100.f);
|
||||
mNoiseTextureScale *= (mScreenHeight / NOISE_SIZE);
|
||||
|
||||
/// Draw a screen space quad
|
||||
drawOrthoQuad(QUAD_NOISE);
|
||||
gPostNightVisionProgram.unbind();
|
||||
}
|
||||
|
||||
void LLPostProcess::applyGaussBlurShader(void)
|
||||
{
|
||||
int pass_count = tweaks.getGaussBlurPasses();
|
||||
if(!pass_count || gPostGaussianBlurProgram.mProgramObject == 0)
|
||||
return;
|
||||
|
||||
gPostGaussianBlurProgram.bind();
|
||||
|
||||
gGL.getTexUnit(0)->bind(mSceneRenderTexture);
|
||||
|
||||
GLint horiz_pass = gPostGaussianBlurProgram.getUniformLocation("horizontalPass");
|
||||
for(int i = 0;i<pass_count;++i)
|
||||
{
|
||||
for(int j = 0;j<2;++j)
|
||||
if((*it)->getDepthChannel()>=0)
|
||||
{
|
||||
if(i || j)
|
||||
copyFrameBuffer();
|
||||
glUniform1iARB(horiz_pass, j);
|
||||
drawOrthoQuad(QUAD_NORMAL);
|
||||
LLImageGL::generateTextures(type, GL_DEPTH_COMPONENT24, 1, &mDepthTexture);
|
||||
gGL.getTexUnit(0)->bindManual(type, mDepthTexture);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(type), 0, GL_DEPTH_COMPONENT24, mScreenWidth, mScreenHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
|
||||
stop_glerror();
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
stop_glerror();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPostProcess::createNoiseTexture()
|
||||
{
|
||||
std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE);
|
||||
for (unsigned int i = 0; i < NOISE_SIZE; i++){
|
||||
for (unsigned int k = 0; k < NOISE_SIZE; k++){
|
||||
buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f);
|
||||
}
|
||||
}
|
||||
|
||||
mNoiseTexture = new LLImageGL(FALSE) ;
|
||||
if(mNoiseTexture->createGLTexture())
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseTexture->getTexName());
|
||||
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
|
||||
stop_glerror();
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPostProcess::destroyGL()
|
||||
{
|
||||
mRenderTarget[0].release();
|
||||
mRenderTarget[1].release();
|
||||
if(mDepthTexture)
|
||||
LLImageGL::deleteTextures(LLTexUnit::TT_RECT_TEXTURE, 0, 0, 1, &mDepthTexture, true);
|
||||
mDepthTexture=0;
|
||||
mNoiseTexture = NULL ;
|
||||
mVBO = NULL ;
|
||||
}
|
||||
|
||||
/*static*/void LLPostProcess::cleanupClass()
|
||||
{
|
||||
if(instanceExists())
|
||||
getInstance()->destroyGL() ;
|
||||
}
|
||||
|
||||
void LLPostProcess::copyFrameBuffer()
|
||||
{
|
||||
mRenderTarget[!!mRenderTarget[0].getFBO()].bindTexture(0,0);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB,0,0,0,0,0,mScreenWidth, mScreenHeight);
|
||||
|
||||
if(mDepthTexture)
|
||||
{
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
if((*it)->isEnabled() && (*it)->getDepthChannel()>=0)
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mDepthTexture);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB,0,0,0,0,0,mScreenWidth, mScreenHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLPostProcess::bindNoise(U32 channel)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bind(mNoiseTexture);
|
||||
}
|
||||
|
||||
void LLPostProcess::renderEffects(unsigned int width, unsigned int height)
|
||||
{
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
if((*it)->isEnabled())
|
||||
{
|
||||
if (mVBO.isNull() || width != mScreenWidth || height != mScreenHeight)
|
||||
{
|
||||
initialize(width, height);
|
||||
}
|
||||
doEffects();
|
||||
return;
|
||||
}
|
||||
}
|
||||
gPostGaussianBlurProgram.unbind();
|
||||
}
|
||||
|
||||
void LLPostProcess::doEffects(void)
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
mNoiseTextureScale = 0.001f + ((100.f - mSelectedEffectInfo["noise_size"].asFloat()) / 100.f);
|
||||
mNoiseTextureScale *= (mScreenHeight / NOISE_SIZE);
|
||||
|
||||
/// Copy the screen buffer to the render texture
|
||||
copyFrameBuffer();
|
||||
stop_glerror();
|
||||
|
||||
//Disable depth. Set blendmode to replace.
|
||||
LLGLDepthTest depth(GL_FALSE);
|
||||
LLGLDepthTest depth(GL_FALSE,GL_FALSE);
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
|
||||
@@ -319,7 +478,6 @@ void LLPostProcess::doEffects(void)
|
||||
gGL.loadIdentity();
|
||||
|
||||
applyShaders();
|
||||
checkError();
|
||||
|
||||
LLGLSLShader::bindNoShader();
|
||||
|
||||
@@ -333,13 +491,46 @@ void LLPostProcess::doEffects(void)
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA); //Restore blendstate. Alpha is ASSUMED for hud/ui render, etc.
|
||||
|
||||
gGL.getTexUnit(1)->disable();
|
||||
checkError();
|
||||
}
|
||||
|
||||
void LLPostProcess::copyFrameBuffer()
|
||||
void LLPostProcess::applyShaders(void)
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(mSceneRenderTexture->getTarget(), mSceneRenderTexture->getTexName());
|
||||
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, mScreenWidth, mScreenHeight, 0);
|
||||
QuadType quad;
|
||||
bool primary_rendertarget = 1;
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
if((quad = (*it)->bind()) != QUAD_NONE)
|
||||
{
|
||||
S32 color_channel = (*it)->getColorChannel();
|
||||
S32 depth_channel = (*it)->getDepthChannel();
|
||||
|
||||
if(depth_channel >= 0)
|
||||
gGL.getTexUnit(depth_channel)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mDepthTexture);
|
||||
|
||||
U32 pass = 1;
|
||||
|
||||
while((*it)->draw(pass++))
|
||||
{
|
||||
mRenderTarget[!primary_rendertarget].bindTarget();
|
||||
|
||||
if(color_channel >= 0)
|
||||
mRenderTarget[mRenderTarget[0].getFBO() ? primary_rendertarget : !primary_rendertarget].bindTexture(0,color_channel);
|
||||
|
||||
drawOrthoQuad(quad);
|
||||
mRenderTarget[!primary_rendertarget].flush();
|
||||
if(mRenderTarget[0].getFBO())
|
||||
primary_rendertarget = !primary_rendertarget;
|
||||
}
|
||||
(*it)->unbind();
|
||||
}
|
||||
}
|
||||
//Only need to copy to framebuffer if FBOs are supported, else we've already been drawing to the framebuffer to begin with.
|
||||
if(mRenderTarget[0].getFBO())
|
||||
{
|
||||
//copyContentsToFramebuffer also binds the main framebuffer.
|
||||
LLRenderTarget::copyContentsToFramebuffer(mRenderTarget[primary_rendertarget],0,0,mScreenWidth,mScreenHeight,0,0,mScreenWidth,mScreenHeight,GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
void LLPostProcess::drawOrthoQuad(QuadType type)
|
||||
@@ -364,64 +555,59 @@ void LLPostProcess::drawOrthoQuad(QuadType type)
|
||||
mVBO->drawArrays(LLRender::TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void LLPostProcess::createScreenTexture()
|
||||
void LLPostProcess::setSelectedEffect(std::string const & effectName)
|
||||
{
|
||||
std::vector<GLubyte> data(mScreenWidth * mScreenHeight * 3, 0) ;
|
||||
|
||||
mSceneRenderTexture = new LLImageGL(FALSE) ;
|
||||
if(mSceneRenderTexture->createGLTexture())
|
||||
mSelectedEffectName = effectName;
|
||||
mSelectedEffectInfo = mAllEffectInfo[effectName];
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mSceneRenderTexture->getTexName());
|
||||
LLImageGL::setManualImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, mScreenWidth, mScreenHeight, GL_RGB, GL_UNSIGNED_BYTE, &data[0]);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
(*it)->loadSettings(mSelectedEffectInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPostProcess::createNoiseTexture()
|
||||
{
|
||||
std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE);
|
||||
for (unsigned int i = 0; i < NOISE_SIZE; i++){
|
||||
for (unsigned int k = 0; k < NOISE_SIZE; k++){
|
||||
buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f);
|
||||
}
|
||||
}
|
||||
|
||||
mNoiseTexture = new LLImageGL(FALSE) ;
|
||||
if(mNoiseTexture->createGLTexture())
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseTexture->getTexName());
|
||||
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPostProcess::checkError(void)
|
||||
void LLPostProcess::setSelectedEffectValue(std::string const & setting, LLSD& value)
|
||||
{
|
||||
GLenum glErr;
|
||||
bool retCode = false;
|
||||
|
||||
glErr = glGetError();
|
||||
while (glErr != GL_NO_ERROR)
|
||||
{
|
||||
// shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl;
|
||||
char const * err_str_raw = (const char *) gluErrorString(glErr);
|
||||
|
||||
if(err_str_raw == NULL)
|
||||
{
|
||||
std::ostringstream err_builder;
|
||||
err_builder << "unknown error number " << glErr;
|
||||
mShaderErrorString = err_builder.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
mShaderErrorString = err_str_raw;
|
||||
}
|
||||
|
||||
retCode = true;
|
||||
glErr = glGetError();
|
||||
}
|
||||
return retCode;
|
||||
char buf[256];
|
||||
S32 elem=0;
|
||||
if(sscanf(setting.c_str(),"%255[^[][%d]", buf, &elem) == 2)
|
||||
{
|
||||
mSelectedEffectInfo[std::string(buf)][elem] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSelectedEffectInfo[setting] = value;
|
||||
}
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
(*it)->loadSettings(mSelectedEffectInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPostProcess::resetSelectedEffect()
|
||||
{
|
||||
if(!llsd_equals(mAllEffectInfo[mSelectedEffectName], mSelectedEffectInfo))
|
||||
{
|
||||
mSelectedEffectInfo = mAllEffectInfo[mSelectedEffectName];
|
||||
for(std::list<LLPointer<LLPostProcessShader> >::iterator it=mShaders.begin();it!=mShaders.end();++it)
|
||||
{
|
||||
(*it)->loadSettings(mSelectedEffectInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPostProcess::saveEffectAs(std::string const & effectName)
|
||||
{
|
||||
mAllEffectInfo[effectName] = mSelectedEffectInfo;
|
||||
|
||||
std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME));
|
||||
//llinfos << "Saving PostProcess Effects settings to " << pathName << llendl;
|
||||
|
||||
llofstream effectsXML(pathName);
|
||||
|
||||
LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
|
||||
|
||||
formatter->format(mAllEffectInfo, effectsXML);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -34,189 +34,123 @@
|
||||
#define LL_POSTPROCESS_H
|
||||
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include "llgl.h"
|
||||
#include "llglheaders.h"
|
||||
#include "llsd.h"
|
||||
#include "llrendertarget.h"
|
||||
|
||||
class LLSD;
|
||||
|
||||
typedef enum _QuadType {
|
||||
QUAD_NONE,
|
||||
QUAD_NORMAL,
|
||||
QUAD_NOISE
|
||||
} QuadType;
|
||||
|
||||
//LLPostProcessShader is an attempt to encapsulate the shaders a little better.
|
||||
class LLPostProcessShader : public LLRefCount //Abstract. PostProcess shaders derive off of this common base.
|
||||
{
|
||||
protected:
|
||||
//LLShaderSetting is used to associate key names to member variables to avoid LLSD lookups when drawing.
|
||||
//It also facilitates automating the assigning of defaults to, as well as parsing from, the effects LLSD list.
|
||||
//This replaces the entire old PostProcessTweaks structure. More will be done in the future to move into a more
|
||||
//xml-driven configuration.
|
||||
struct LLShaderSettingBase
|
||||
{
|
||||
LLShaderSettingBase(const char* name) : mSettingName(name) {}
|
||||
const char* mSettingName; //LLSD key names as found in postprocesseffects.xml. eg 'contrast_base'
|
||||
virtual LLSD getDefaultValue() = 0; //Converts the member variable as an LLSD. Used to set defaults absent in postprocesseffects.xml
|
||||
virtual void setValue(const LLSD& value) = 0; //Connects the LLSD element to the member variable. Used when loading effects (such as default)
|
||||
};
|
||||
template<typename T>
|
||||
struct LLShaderSetting : public LLShaderSettingBase
|
||||
{
|
||||
LLShaderSetting(const char* setting_name, T def) : LLShaderSettingBase(setting_name), mValue(def), mDefault(def) {}
|
||||
T mValue; //The member variable mentioned above.
|
||||
T mDefault; //Set via ctor. Value is inserted into the defaults LLSD list if absent from postprocesseffects.xml
|
||||
LLSD getDefaultValue() { return mDefault; } //See LLShaderSettingBase::getDefaultValue
|
||||
void setValue(const LLSD& value) { mValue = value; } //See LLShaderSettingBase::setValue
|
||||
operator T() { return mValue; } //Typecast operator overload so this object can be handled as if it was whatever T represents.
|
||||
};
|
||||
std::vector<LLShaderSettingBase*> mSettings; //Contains a list of all the 'settings' this shader uses. Manually add via push_back in ctor.
|
||||
public:
|
||||
virtual ~LLPostProcessShader() {};
|
||||
virtual bool isEnabled() = 0; //Returning false avoids bind/draw/unbind calls. If no shaders are enabled, framebuffer copying is skipped.
|
||||
virtual S32 getColorChannel() = 0; //If color buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer.
|
||||
virtual S32 getDepthChannel() = 0; //If depth buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer.
|
||||
virtual QuadType bind() = 0; //Bind shader and textures, set up attribs. Returns the 'type' of quad to be drawn.
|
||||
virtual bool draw(U32 pass) = 0; //returning false means finished. Used to update per-pass attributes and such. LLPostProcess will call
|
||||
//drawOrthoQuad when this returns true, increment pass, then call this again, and keep repeating this until false is returned.
|
||||
virtual void unbind() = 0; //Unbind shader and textures.
|
||||
|
||||
LLSD getDefaults(); //Returns a full LLSD kvp list filled with default values.
|
||||
void loadSettings(const LLSD& settings); //Parses the effects LLSD list and sets the member variables linked to them (via LLShaderSetting::setValue())
|
||||
};
|
||||
|
||||
//LLVector4 does not implicitly convert to and from LLSD, so template specilizations are necessary.
|
||||
template<> LLSD LLPostProcessShader::LLShaderSetting<LLVector4>::getDefaultValue();
|
||||
template<> void LLPostProcessShader::LLShaderSetting<LLVector4>::setValue(const LLSD& value);
|
||||
|
||||
class LLPostProcess : public LLSingleton<LLPostProcess>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum _QuadType {
|
||||
QUAD_NORMAL,
|
||||
QUAD_NOISE
|
||||
} QuadType;
|
||||
|
||||
/// GLSL Shader Encapsulation Struct
|
||||
//typedef std::map<const char *, GLuint> glslUniforms;
|
||||
|
||||
struct PostProcessTweaks : public LLSD {
|
||||
inline PostProcessTweaks() : LLSD(LLSD::emptyMap())
|
||||
{
|
||||
}
|
||||
|
||||
inline LLSD & brightMult() {
|
||||
return (*this)["brightness_multiplier"];
|
||||
}
|
||||
|
||||
inline LLSD & noiseStrength() {
|
||||
return (*this)["noise_strength"];
|
||||
}
|
||||
|
||||
inline LLSD & noiseSize() {
|
||||
return (*this)["noise_size"];
|
||||
}
|
||||
|
||||
inline LLSD & brightness() {
|
||||
return (*this)["brightness"];
|
||||
}
|
||||
|
||||
inline LLSD & contrast() {
|
||||
return (*this)["contrast"];
|
||||
}
|
||||
|
||||
inline LLSD & contrastBaseR() {
|
||||
return (*this)["contrast_base"][0];
|
||||
}
|
||||
|
||||
inline LLSD & contrastBaseG() {
|
||||
return (*this)["contrast_base"][1];
|
||||
}
|
||||
|
||||
inline LLSD & contrastBaseB() {
|
||||
return (*this)["contrast_base"][2];
|
||||
}
|
||||
|
||||
inline LLSD & contrastBaseIntensity() {
|
||||
return (*this)["contrast_base"][3];
|
||||
}
|
||||
|
||||
inline LLSD & saturation() {
|
||||
return (*this)["saturation"];
|
||||
}
|
||||
|
||||
inline LLSD & useNightVisionShader() {
|
||||
return (*this)["enable_night_vision"];
|
||||
}
|
||||
|
||||
inline LLSD & useColorFilter() {
|
||||
return (*this)["enable_color_filter"];
|
||||
}
|
||||
|
||||
inline LLSD & useGaussBlurFilter() {
|
||||
return (*this)["enable_gauss_blur"];
|
||||
}
|
||||
|
||||
inline F32 getBrightMult() const {
|
||||
return F32((*this)["brightness_multiplier"].asReal());
|
||||
}
|
||||
|
||||
inline F32 getNoiseStrength() const {
|
||||
return F32((*this)["noise_strength"].asReal());
|
||||
}
|
||||
|
||||
inline F32 getNoiseSize() const {
|
||||
return F32((*this)["noise_size"].asReal());
|
||||
}
|
||||
|
||||
inline F32 getGamma() const {
|
||||
return F32((*this)["gamma"].asReal());
|
||||
}
|
||||
|
||||
inline F32 getBrightness() const {
|
||||
return F32((*this)["brightness"].asReal());
|
||||
}
|
||||
|
||||
inline F32 getContrast() const {
|
||||
return F32((*this)["contrast"].asReal());
|
||||
}
|
||||
|
||||
inline F32 getContrastBaseR() const {
|
||||
return F32((*this)["contrast_base"][0].asReal());
|
||||
}
|
||||
|
||||
inline F32 getContrastBaseG() const {
|
||||
return F32((*this)["contrast_base"][1].asReal());
|
||||
}
|
||||
|
||||
inline F32 getContrastBaseB() const {
|
||||
return F32((*this)["contrast_base"][2].asReal());
|
||||
}
|
||||
|
||||
inline F32 getContrastBaseIntensity() const {
|
||||
return F32((*this)["contrast_base"][3].asReal());
|
||||
}
|
||||
|
||||
inline F32 getSaturation() const {
|
||||
return F32((*this)["saturation"].asReal());
|
||||
}
|
||||
|
||||
inline LLSD & getGaussBlurPasses() {
|
||||
return (*this)["gauss_blur_passes"];
|
||||
}
|
||||
};
|
||||
|
||||
PostProcessTweaks tweaks;
|
||||
|
||||
// the map of all availible effects
|
||||
LLSD mAllEffects;
|
||||
|
||||
private:
|
||||
std::list<LLPointer<LLPostProcessShader> > mShaders; //List of all registered LLPostProcessShader instances.
|
||||
|
||||
LLPointer<LLVertexBuffer> mVBO;
|
||||
LLPointer<LLImageGL> mSceneRenderTexture ;
|
||||
U32 mNextDrawTarget; //Need to pingpong between two rendertargets. Cannot sample target texture of currently bound FBO.
|
||||
// However this is ONLY the case if fbos are actually supported, else swapping isn't needed.
|
||||
LLRenderTarget mRenderTarget[2];
|
||||
U32 mDepthTexture;
|
||||
LLPointer<LLImageGL> mNoiseTexture ;
|
||||
|
||||
U32 mScreenWidth;
|
||||
U32 mScreenHeight;
|
||||
F32 mNoiseTextureScale;
|
||||
|
||||
// The name of currently selected effect in mAllEffectInfo
|
||||
std::string mSelectedEffectName;
|
||||
// The map of settings for currently selected effect.
|
||||
LLSD mSelectedEffectInfo;
|
||||
// The map of all availible effects
|
||||
LLSD mAllEffectInfo;
|
||||
|
||||
public:
|
||||
LLPostProcess(void);
|
||||
|
||||
~LLPostProcess(void);
|
||||
private:
|
||||
// OpenGL initialization
|
||||
void initialize(unsigned int width, unsigned int height); //Sets mScreenWidth and mScreenHeight
|
||||
// calls createScreenTextures and createNoiseTexture
|
||||
// creates VBO
|
||||
void createScreenTextures(); //Creates color texture and depth texture(if needed).
|
||||
void createNoiseTexture(); //Creates 'random' noise texture.
|
||||
|
||||
void apply(unsigned int width, unsigned int height);
|
||||
void invalidate() ;
|
||||
|
||||
// Cleanup of global data that's only inited once per class.
|
||||
public:
|
||||
// Teardown
|
||||
// Called on destroyGL or cleanupClass. Releases VBOs, rendertargets and textures.
|
||||
void destroyGL();
|
||||
// Cleanup of global data that's only inited once per class.
|
||||
static void cleanupClass();
|
||||
|
||||
void setSelectedEffect(std::string const & effectName);
|
||||
|
||||
inline std::string const & getSelectedEffect(void) const {
|
||||
return mSelectedEffectName;
|
||||
}
|
||||
|
||||
void saveEffect(std::string const & effectName);
|
||||
|
||||
private:
|
||||
/// read in from file
|
||||
std::string mShaderErrorString;
|
||||
unsigned int mScreenWidth;
|
||||
unsigned int mScreenHeight;
|
||||
|
||||
float mNoiseTextureScale;
|
||||
|
||||
// the name of currently selected effect in mAllEffects
|
||||
// invariant: tweaks == mAllEffects[mSelectedEffectName]
|
||||
std::string mSelectedEffectName;
|
||||
|
||||
/// General functions
|
||||
void initialize(unsigned int width, unsigned int height);
|
||||
void doEffects(void);
|
||||
void applyShaders(void);
|
||||
bool shadersEnabled(void);
|
||||
|
||||
/// Night Vision Functions
|
||||
void applyNightVisionShader(void);
|
||||
|
||||
/// Color Filter Functions
|
||||
void applyColorFilterShader(void);
|
||||
|
||||
/// Gaussian blur Filter Functions
|
||||
void applyGaussBlurShader(void);
|
||||
|
||||
/// OpenGL Helper Functions
|
||||
// Setup for draw.
|
||||
void copyFrameBuffer();
|
||||
void createScreenTexture();
|
||||
void createNoiseTexture();
|
||||
bool checkError(void);
|
||||
void drawOrthoQuad(QuadType type);
|
||||
void bindNoise(U32 channel);
|
||||
|
||||
// Draw
|
||||
void renderEffects(unsigned int width, unsigned int height); //Entry point for newview.
|
||||
private:
|
||||
void doEffects(void); //Sets up viewmatrix, blits the framebuffer, then calls applyShaders.
|
||||
void applyShaders(void); //Iterates over all active post shaders, manages binding, calls drawOrthoQuad for render.
|
||||
void drawOrthoQuad(QuadType type); //Finally draws fullscreen quad with the shader currently bound.
|
||||
|
||||
public:
|
||||
// UI interaction
|
||||
// Getters
|
||||
inline LLSD const & getAllEffectInfo(void) const { return mAllEffectInfo; }
|
||||
inline std::string const & getSelectedEffectName(void) const { return mSelectedEffectName; }
|
||||
inline LLSD const & getSelectedEffectInfo(void) const { return mSelectedEffectInfo; }
|
||||
// Setters
|
||||
void setSelectedEffect(std::string const & effectName);
|
||||
void setSelectedEffectValue(std::string const & setting, LLSD& value);
|
||||
void resetSelectedEffect();
|
||||
void saveEffectAs(std::string const & effectName);
|
||||
};
|
||||
#endif // LL_POSTPROCESS_H
|
||||
|
||||
@@ -1480,9 +1480,8 @@ void LLRender::translateUI(F32 x, F32 y, F32 z)
|
||||
llerrs << "Need to push a UI translation frame before offsetting" << llendl;
|
||||
}
|
||||
|
||||
mUIOffset.back().mV[0] += x;
|
||||
mUIOffset.back().mV[1] += y;
|
||||
mUIOffset.back().mV[2] += z;
|
||||
LLVector4a add(x,y,x);
|
||||
mUIOffset.back()->add(add);
|
||||
}
|
||||
|
||||
void LLRender::scaleUI(F32 x, F32 y, F32 z)
|
||||
@@ -1492,27 +1491,28 @@ void LLRender::scaleUI(F32 x, F32 y, F32 z)
|
||||
llerrs << "Need to push a UI transformation frame before scaling." << llendl;
|
||||
}
|
||||
|
||||
mUIScale.back().scaleVec(LLVector3(x,y,z));
|
||||
LLVector4a scale(x,y,z);
|
||||
mUIScale.back()->mul(scale);
|
||||
}
|
||||
|
||||
void LLRender::pushUIMatrix()
|
||||
{
|
||||
if (mUIOffset.empty())
|
||||
{
|
||||
mUIOffset.push_back(LLVector3(0,0,0));
|
||||
mUIOffset.push_back(new LLVector4a(0.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
mUIOffset.push_back(mUIOffset.back());
|
||||
mUIOffset.push_back(new LLVector4a(*mUIOffset.back()));
|
||||
}
|
||||
|
||||
if (mUIScale.empty())
|
||||
{
|
||||
mUIScale.push_back(LLVector3(1,1,1));
|
||||
mUIScale.push_back(new LLVector4a(1.f));
|
||||
}
|
||||
else
|
||||
{
|
||||
mUIScale.push_back(mUIScale.back());
|
||||
mUIScale.push_back(new LLVector4a(*mUIScale.back()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1522,7 +1522,9 @@ void LLRender::popUIMatrix()
|
||||
{
|
||||
llerrs << "UI offset stack blown." << llendl;
|
||||
}
|
||||
delete mUIOffset.back();
|
||||
mUIOffset.pop_back();
|
||||
delete mUIScale.back();
|
||||
mUIScale.pop_back();
|
||||
}
|
||||
|
||||
@@ -1532,7 +1534,7 @@ LLVector3 LLRender::getUITranslation()
|
||||
{
|
||||
return LLVector3(0,0,0);
|
||||
}
|
||||
return mUIOffset.back();
|
||||
return LLVector3(mUIOffset.back()->getF32ptr());
|
||||
}
|
||||
|
||||
LLVector3 LLRender::getUIScale()
|
||||
@@ -1541,7 +1543,7 @@ LLVector3 LLRender::getUIScale()
|
||||
{
|
||||
return LLVector3(1,1,1);
|
||||
}
|
||||
return mUIScale.back();
|
||||
return LLVector3(mUIOffset.back()->getF32ptr());
|
||||
}
|
||||
|
||||
|
||||
@@ -1551,8 +1553,8 @@ void LLRender::loadUIIdentity()
|
||||
{
|
||||
llerrs << "Need to push UI translation frame before clearing offset." << llendl;
|
||||
}
|
||||
mUIOffset.back().setVec(0,0,0);
|
||||
mUIScale.back().setVec(1,1,1);
|
||||
mUIOffset.back()->splat(0.f);
|
||||
mUIScale.back()->splat(1.f);
|
||||
}
|
||||
|
||||
void LLRender::setColorMask(bool writeColor, bool writeAlpha)
|
||||
@@ -1913,7 +1915,7 @@ void LLRender::flush()
|
||||
}
|
||||
}
|
||||
|
||||
void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
|
||||
void LLRender::vertex4a(const LLVector4a& vertex)
|
||||
{
|
||||
//the range of mVerticesp, mColorsp and mTexcoordsp is [0, 4095]
|
||||
if (mCount > 2048)
|
||||
@@ -1935,12 +1937,13 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
|
||||
|
||||
if (mUIOffset.empty())
|
||||
{
|
||||
mVerticesp[mCount] = LLVector3(x,y,z);
|
||||
mVerticesp[mCount]=vertex;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());
|
||||
mVerticesp[mCount] = vert;
|
||||
//LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back());
|
||||
mVerticesp[mCount].setAdd(vertex,*mUIOffset.back());
|
||||
mVerticesp[mCount].mul(*mUIScale.back());
|
||||
}
|
||||
|
||||
if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile)
|
||||
@@ -1968,7 +1971,7 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
|
||||
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
|
||||
}
|
||||
|
||||
void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
|
||||
void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
|
||||
{
|
||||
if (mCount + vert_count > 4094)
|
||||
{
|
||||
@@ -2025,7 +2028,7 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count)
|
||||
mVerticesp[mCount] = mVerticesp[mCount-1];
|
||||
}
|
||||
|
||||
void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count)
|
||||
void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count)
|
||||
{
|
||||
if (mCount + vert_count > 4094)
|
||||
{
|
||||
@@ -2083,7 +2086,7 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 v
|
||||
mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
|
||||
}
|
||||
|
||||
void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
|
||||
void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
|
||||
{
|
||||
if (mCount + vert_count > 4094)
|
||||
{
|
||||
@@ -2143,26 +2146,6 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLCol
|
||||
mColorsp[mCount] = mColorsp[mCount-1];
|
||||
}
|
||||
|
||||
void LLRender::vertex2i(const GLint& x, const GLint& y)
|
||||
{
|
||||
vertex3f((GLfloat) x, (GLfloat) y, 0);
|
||||
}
|
||||
|
||||
void LLRender::vertex2f(const GLfloat& x, const GLfloat& y)
|
||||
{
|
||||
vertex3f(x,y,0);
|
||||
}
|
||||
|
||||
void LLRender::vertex2fv(const GLfloat* v)
|
||||
{
|
||||
vertex3f(v[0], v[1], 0);
|
||||
}
|
||||
|
||||
void LLRender::vertex3fv(const GLfloat* v)
|
||||
{
|
||||
vertex3f(v[0], v[1], v[2]);
|
||||
}
|
||||
|
||||
void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
|
||||
{
|
||||
mTexcoordsp[mCount] = LLVector2(x,y);
|
||||
|
||||
@@ -364,12 +364,14 @@ public:
|
||||
|
||||
void begin(const GLuint& mode);
|
||||
void end();
|
||||
void vertex2i(const GLint& x, const GLint& y);
|
||||
void vertex2f(const GLfloat& x, const GLfloat& y);
|
||||
void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z);
|
||||
void vertex2fv(const GLfloat* v);
|
||||
void vertex3fv(const GLfloat* v);
|
||||
|
||||
|
||||
LL_FORCE_INLINE void vertex2i(const GLint& x, const GLint& y) { vertex4a(LLVector4a((GLfloat)x,(GLfloat)y,0.f)); }
|
||||
LL_FORCE_INLINE void vertex2f(const GLfloat& x, const GLfloat& y) { vertex4a(LLVector4a(x,y,0.f)); }
|
||||
LL_FORCE_INLINE void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) { vertex4a(LLVector4a(x,y,z)); }
|
||||
LL_FORCE_INLINE void vertex2fv(const GLfloat* v) { vertex4a(LLVector4a(v[0],v[1],0.f)); }
|
||||
LL_FORCE_INLINE void vertex3fv(const GLfloat* v) { vertex4a(LLVector4a(v[0],v[1],v[2])); }
|
||||
void vertex4a(const LLVector4a& v);
|
||||
|
||||
void texCoord2i(const GLint& x, const GLint& y);
|
||||
void texCoord2f(const GLfloat& x, const GLfloat& y);
|
||||
void texCoord2fv(const GLfloat* tc);
|
||||
@@ -387,9 +389,9 @@ public:
|
||||
void diffuseColor4fv(const F32* c);
|
||||
void diffuseColor4ubv(const U8* c);
|
||||
|
||||
void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count);
|
||||
void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
|
||||
|
||||
void setColorMask(bool writeColor, bool writeAlpha);
|
||||
void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
|
||||
@@ -449,7 +451,7 @@ private:
|
||||
F32 mCurrAlphaFuncVal;
|
||||
|
||||
LLPointer<LLVertexBuffer> mBuffer;
|
||||
LLStrider<LLVector3> mVerticesp;
|
||||
LLStrider<LLVector4a> mVerticesp;
|
||||
LLStrider<LLVector2> mTexcoordsp;
|
||||
LLStrider<LLColor4U> mColorsp;
|
||||
std::vector<LLTexUnit*> mTexUnits;
|
||||
@@ -463,8 +465,8 @@ private:
|
||||
|
||||
F32 mMaxAnisotropy;
|
||||
|
||||
std::vector<LLVector3> mUIOffset;
|
||||
std::vector<LLVector3> mUIScale;
|
||||
std::vector<LLVector4a*> mUIOffset;
|
||||
std::vector<LLVector4a*> mUIScale;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -76,6 +76,45 @@ LLRenderTarget::~LLRenderTarget()
|
||||
release();
|
||||
}
|
||||
|
||||
void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
|
||||
{
|
||||
//for accounting, get the number of pixels added/subtracted
|
||||
S32 pix_diff = (resx*resy)-(mResX*mResY);
|
||||
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
for (U32 i = 0; i < mTex.size(); ++i)
|
||||
{ //resize color attachments
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mTex[i]);
|
||||
LLImageGL::setManualImage(LLTexUnit::getInternalType(mUsage), 0, color_fmt, mResX, mResY, GL_RGBA, GL_UNSIGNED_BYTE, NULL, false);
|
||||
sBytesAllocated += pix_diff*4;
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{ //resize depth attachment
|
||||
if (mStencil && mFBO)
|
||||
{
|
||||
//use render buffers where stencil buffers are in play
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mResX, mResY);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
if(!mStencil)
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
|
||||
else
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH24_STENCIL8, mResX, mResY, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL, false);
|
||||
}
|
||||
|
||||
sBytesAllocated += pix_diff*4;
|
||||
}
|
||||
if(mSampleBuffer)
|
||||
mSampleBuffer->resize(resx,resy);
|
||||
}
|
||||
|
||||
void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
|
||||
{
|
||||
@@ -95,9 +134,10 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
|
||||
mUsage = usage;
|
||||
mUseDepth = depth;
|
||||
|
||||
|
||||
if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
|
||||
{
|
||||
glGenFramebuffers(1, (GLuint *) &mFBO);
|
||||
|
||||
if (depth)
|
||||
{
|
||||
if (!allocateDepth())
|
||||
@@ -107,8 +147,6 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
|
||||
}
|
||||
}
|
||||
|
||||
glGenFramebuffers(1, (GLuint *) &mFBO);
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
@@ -126,7 +164,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
@@ -219,7 +257,7 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt)
|
||||
|
||||
bool LLRenderTarget::allocateDepth()
|
||||
{
|
||||
if (mStencil)
|
||||
if (mStencil && mFBO)
|
||||
{
|
||||
//use render buffers where stencil buffers are in play
|
||||
glGenRenderbuffers(1, (GLuint *) &mDepth);
|
||||
@@ -231,24 +269,30 @@ bool LLRenderTarget::allocateDepth()
|
||||
}
|
||||
else
|
||||
{
|
||||
LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
|
||||
if(!mStencil)
|
||||
LLImageGL::generateTextures(mUsage, GL_DEPTH_COMPONENT24, 1, &mDepth);
|
||||
else
|
||||
LLImageGL::generateTextures(mUsage, GL_DEPTH24_STENCIL8, 1, &mDepth);
|
||||
gGL.getTexUnit(0)->bindManual(mUsage, mDepth);
|
||||
|
||||
U32 internal_type = LLTexUnit::getInternalType(mUsage);
|
||||
stop_glerror();
|
||||
clear_glerror();
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
|
||||
if(!mStencil)
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT24, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL, false);
|
||||
else
|
||||
LLImageGL::setManualImage(internal_type, 0, GL_DEPTH24_STENCIL8, mResX, mResY, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL, false);
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
|
||||
}
|
||||
|
||||
sBytesAllocated += mResX*mResY*4;
|
||||
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
llwarns << "Unable to allocate depth buffer for render target." << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
sBytesAllocated += mResX*mResY*4;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -301,7 +345,7 @@ void LLRenderTarget::release()
|
||||
{
|
||||
if (mDepth)
|
||||
{
|
||||
if (mStencil)
|
||||
if (mStencil && mFBO)
|
||||
{
|
||||
glDeleteRenderbuffers(1, (GLuint*) &mDepth);
|
||||
stop_glerror();
|
||||
@@ -309,7 +353,11 @@ void LLRenderTarget::release()
|
||||
else
|
||||
{
|
||||
//Release before delete.
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
if(mFBO)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
LLImageGL::deleteTextures(mUsage, 0, 0, 1, &mDepth, true);
|
||||
stop_glerror();
|
||||
}
|
||||
@@ -453,6 +501,7 @@ void LLRenderTarget::flush(bool fetch_depth)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY);
|
||||
stop_glerror();
|
||||
|
||||
if (fetch_depth)
|
||||
{
|
||||
@@ -461,8 +510,10 @@ void LLRenderTarget::flush(bool fetch_depth)
|
||||
allocateDepth();
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8, 0, 0, mResX, mResY, 0);
|
||||
gGL.getTexUnit(0)->bind(this,true);
|
||||
glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, 0, 0, 0, 0, mResX, mResY);
|
||||
stop_glerror();
|
||||
//glCopyTexImage2D(LLTexUnit::getInternalType(mUsage), 0, GL_DEPTH24_STENCIL8, 0, 0, mResX, mResY, 0);
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->disable();
|
||||
@@ -472,7 +523,7 @@ void LLRenderTarget::flush(bool fetch_depth)
|
||||
stop_glerror();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
stop_glerror();
|
||||
|
||||
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
LLGLEnable multisample(GL_MULTISAMPLE);
|
||||
@@ -482,7 +533,7 @@ void LLRenderTarget::flush(bool fetch_depth)
|
||||
check_framebuffer_status();
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleBuffer->mFBO);
|
||||
check_framebuffer_status();
|
||||
|
||||
|
||||
stop_glerror();
|
||||
if(gGLManager.mIsATI)
|
||||
{
|
||||
@@ -532,7 +583,6 @@ void LLRenderTarget::flush(bool fetch_depth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
|
||||
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
|
||||
{
|
||||
@@ -553,7 +603,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil)
|
||||
if (mask == GL_DEPTH_BUFFER_BIT && !mStencil && source.mStencil != mStencil)
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
@@ -642,7 +692,8 @@ void LLRenderTarget::getViewport(S32* viewport)
|
||||
// LLMultisampleBuffer implementation
|
||||
//==================================================
|
||||
LLMultisampleBuffer::LLMultisampleBuffer() :
|
||||
mSamples(0)
|
||||
mSamples(0),
|
||||
mColorFormat(0)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -743,6 +794,7 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
|
||||
mUsage = usage;
|
||||
mUseDepth = depth;
|
||||
mStencil = stencil;
|
||||
mColorFormat = color_fmt;
|
||||
|
||||
{
|
||||
|
||||
@@ -780,6 +832,42 @@ bool LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth
|
||||
return addColorAttachment(color_fmt);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::resize(U32 resx, U32 resy)
|
||||
{
|
||||
//for accounting, get the number of pixels added/subtracted
|
||||
S32 pix_diff = (resx*resy)-(mResX*mResY);
|
||||
|
||||
mResX = resx;
|
||||
mResY = resy;
|
||||
|
||||
for (U32 i = 0; i < mTex.size(); ++i)
|
||||
{ //resize color attachments
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mTex[i]);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, mColorFormat, mResX, mResY);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
sBytesAllocated += pix_diff*4;
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{ //resize depth attachment
|
||||
if (mStencil)
|
||||
{
|
||||
//use render buffers where stencil buffers are in play
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mDepth);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT24, mResX, mResY);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
}
|
||||
sBytesAllocated += pix_diff*4;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
|
||||
{
|
||||
if (color_fmt == 0)
|
||||
@@ -829,12 +917,13 @@ bool LLMultisampleBuffer::allocateDepth()
|
||||
clear_glerror();
|
||||
if (mStencil)
|
||||
{
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH24_STENCIL8, mResX, mResY);
|
||||
}
|
||||
else
|
||||
{
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT16_ARB, mResX, mResY);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, mSamples, GL_DEPTH_COMPONENT24, mResX, mResY);
|
||||
}
|
||||
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
llwarns << "Unable to allocate depth buffer for multisample render target." << llendl;
|
||||
@@ -845,4 +934,3 @@ bool LLMultisampleBuffer::allocateDepth()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,12 @@ public:
|
||||
//multiple calls will release previously allocated resources
|
||||
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE);
|
||||
|
||||
//resize existing attachments to use new resolution and color format
|
||||
// CAUTION: if the GL runs out of memory attempting to resize, this render target will be undefined
|
||||
// DO NOT use for screen space buffers or for scratch space for an image that might be uploaded
|
||||
// DO use for render targets that resize often and aren't likely to ruin someone's day if they break
|
||||
void resize(U32 resx, U32 resy, U32 color_fmt);
|
||||
|
||||
//provide this render target with a multisample resource.
|
||||
void setSampleBuffer(LLMultisampleBuffer* buffer);
|
||||
|
||||
@@ -145,6 +151,8 @@ public:
|
||||
//one renderable attachment (i.e. color buffer, depth buffer).
|
||||
bool isComplete() const;
|
||||
|
||||
U32 getFBO() const {return mFBO;}
|
||||
|
||||
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
|
||||
|
||||
protected:
|
||||
@@ -168,6 +176,7 @@ protected:
|
||||
class LLMultisampleBuffer : public LLRenderTarget
|
||||
{
|
||||
U32 mSamples;
|
||||
U32 mColorFormat;
|
||||
public:
|
||||
LLMultisampleBuffer();
|
||||
virtual ~LLMultisampleBuffer();
|
||||
@@ -180,6 +189,7 @@ public:
|
||||
bool allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples);
|
||||
virtual bool addColorAttachment(U32 color_fmt);
|
||||
virtual bool allocateDepth();
|
||||
void resize(U32 resx, U32 resy);
|
||||
};
|
||||
|
||||
#endif //!LL_MESA_HEADLESS
|
||||
|
||||
@@ -679,7 +679,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
|
||||
vec4 diffuseLookup(vec2 texcoord)
|
||||
{
|
||||
switch (vary_texture_index.r))
|
||||
switch (vary_texture_index))
|
||||
{
|
||||
case 0: ret = texture2D(tex0, texcoord); break;
|
||||
case 1: ret = texture2D(tex1, texcoord); break;
|
||||
@@ -703,7 +703,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
|
||||
if (texture_index_channels > 1)
|
||||
{
|
||||
text[count++] = strdup("VARYING_FLAT ivec4 vary_texture_index;\n");
|
||||
text[count++] = strdup("VARYING_FLAT int vary_texture_index;\n");
|
||||
}
|
||||
|
||||
text[count++] = strdup("vec4 diffuseLookup(vec2 texcoord)\n");
|
||||
@@ -721,7 +721,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
{ //switches are unreliable on some NVIDIA drivers
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string if_string = llformat("\t%sif (vary_texture_index.r == %d) { return texture2D(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i);
|
||||
std::string if_string = llformat("\t%sif (vary_texture_index == %d) { return texture2D(tex%d, texcoord); }\n", i > 0 ? "else " : "", i, i);
|
||||
text[count++] = strdup(if_string.c_str());
|
||||
}
|
||||
text[count++] = strdup("\treturn vec4(1,0,1,1);\n");
|
||||
@@ -730,13 +730,13 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
|
||||
else
|
||||
{
|
||||
text[count++] = strdup("\tvec4 ret = vec4(1,0,1,1);\n");
|
||||
text[count++] = strdup("\tswitch (vary_texture_index.r)\n");
|
||||
text[count++] = strdup("\tswitch (vary_texture_index)\n");
|
||||
text[count++] = strdup("\t{\n");
|
||||
|
||||
//switch body
|
||||
for (S32 i = 0; i < texture_index_channels; ++i)
|
||||
{
|
||||
std::string case_str = llformat("\t\tcase %d: ret = texture2D(tex%d, texcoord); break;\n", i, i);
|
||||
std::string case_str = llformat("\t\tcase %d: return texture2D(tex%d, texcoord);\n", i, i);
|
||||
text[count++] = strdup(case_str.c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -1249,7 +1249,7 @@ void LLVertexBuffer::setupVertexArray()
|
||||
1, //TYPE_WEIGHT,
|
||||
4, //TYPE_WEIGHT4,
|
||||
4, //TYPE_CLOTHWEIGHT,
|
||||
4, //TYPE_TEXTURE_INDEX
|
||||
1, //TYPE_TEXTURE_INDEX
|
||||
};
|
||||
|
||||
U32 attrib_type[] =
|
||||
@@ -1266,7 +1266,7 @@ void LLVertexBuffer::setupVertexArray()
|
||||
GL_FLOAT, //TYPE_WEIGHT,
|
||||
GL_FLOAT, //TYPE_WEIGHT4,
|
||||
GL_FLOAT, //TYPE_CLOTHWEIGHT,
|
||||
GL_UNSIGNED_BYTE, //TYPE_TEXTURE_INDEX
|
||||
GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX
|
||||
};
|
||||
|
||||
bool attrib_integer[] =
|
||||
@@ -2313,7 +2313,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask)
|
||||
#if !LL_DARWIN
|
||||
S32 loc = TYPE_TEXTURE_INDEX;
|
||||
void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12);
|
||||
glVertexAttribIPointer(loc, 4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
|
||||
glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr);
|
||||
#endif
|
||||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
|
||||
@@ -520,7 +520,7 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
|
||||
|
||||
const S32 NUM_VERTICES = 9 * 4; // 9 quads
|
||||
LLVector2 uv[NUM_VERTICES];
|
||||
LLVector3 pos[NUM_VERTICES];
|
||||
LLVector4a pos[NUM_VERTICES];
|
||||
|
||||
S32 index = 0;
|
||||
|
||||
@@ -528,157 +528,157 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex
|
||||
{
|
||||
// draw bottom left
|
||||
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
// draw bottom middle
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
// draw bottom right
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
// draw left
|
||||
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
// draw middle
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
// draw right
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
|
||||
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
// draw top left
|
||||
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
|
||||
pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
|
||||
pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
// draw top middle
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
// draw top right
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
|
||||
pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
|
||||
pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
|
||||
pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
|
||||
pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
|
||||
pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
|
||||
index++;
|
||||
|
||||
|
||||
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
|
||||
}
|
||||
gGL.end();
|
||||
@@ -720,7 +720,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
{
|
||||
const S32 NUM_VERTICES = 4; // 9 quads
|
||||
LLVector2 uv[NUM_VERTICES];
|
||||
LLVector3 pos[NUM_VERTICES];
|
||||
LLVector4a pos[NUM_VERTICES];
|
||||
|
||||
gGL.begin(LLRender::QUADS);
|
||||
{
|
||||
@@ -734,19 +734,19 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre
|
||||
S32 scaled_height = llround(height * ui_scale.mV[VY]);
|
||||
|
||||
uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
|
||||
pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
|
||||
pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
|
||||
pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
|
||||
pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
|
||||
pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
|
||||
pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
|
||||
index++;
|
||||
|
||||
uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
|
||||
pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
|
||||
pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
|
||||
index++;
|
||||
|
||||
gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
|
||||
|
||||
@@ -336,6 +336,7 @@ bool LLView::addChild(LLView* child, S32 tab_group)
|
||||
|
||||
// add to front of child list, as normal
|
||||
mChildList.push_front(child);
|
||||
mChildHashMap[child->getName()]=child;
|
||||
|
||||
// add to ctrl list if is LLUICtrl
|
||||
if (child->isCtrl())
|
||||
@@ -374,6 +375,14 @@ void LLView::removeChild(LLView* child)
|
||||
// if we are removing an item we are currently iterating over, that would be bad
|
||||
llassert(child->mInDraw == false);
|
||||
mChildList.remove( child );
|
||||
for(boost::unordered_map<const std::string, LLView*>::iterator it=mChildHashMap.begin(); it != mChildHashMap.end(); ++it)
|
||||
{
|
||||
if(it->second == child)
|
||||
{
|
||||
mChildHashMap.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
child->mParentView = NULL;
|
||||
if (child->isCtrl())
|
||||
{
|
||||
@@ -607,6 +616,7 @@ void LLView::deleteAllChildren()
|
||||
LLView* viewp = mChildList.front();
|
||||
delete viewp; // will remove the child from mChildList
|
||||
}
|
||||
mChildHashMap.clear();
|
||||
}
|
||||
|
||||
void LLView::setAllChildrenEnabled(BOOL b)
|
||||
@@ -1506,13 +1516,18 @@ LLView* LLView::getChildView(const std::string& name, BOOL recurse, BOOL create_
|
||||
//if(name.empty())
|
||||
// return NULL;
|
||||
// Look for direct children *first*
|
||||
BOOST_FOREACH(LLView* childp, mChildList)
|
||||
/*BOOST_FOREACH(LLView* childp, mChildList)
|
||||
{
|
||||
llassert(childp);
|
||||
if (childp->getName() == name)
|
||||
{
|
||||
return childp;
|
||||
}
|
||||
}*/
|
||||
boost::unordered_map<const std::string, LLView*>::const_iterator it = mChildHashMap.find(name);
|
||||
if(it != mChildHashMap.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
if (recurse)
|
||||
{
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "llcursortypes.h"
|
||||
#include "llinitparam.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
const U32 FOLLOWS_NONE = 0x00;
|
||||
const U32 FOLLOWS_LEFT = 0x01;
|
||||
@@ -186,6 +187,15 @@ public:
|
||||
|
||||
void initFromParams(const LLView::Params&);
|
||||
|
||||
template<typename T>
|
||||
struct CachedUICtrl
|
||||
{
|
||||
CachedUICtrl():mPtr(NULL){}
|
||||
T* connect(LLView* parent,const char* pName){return mPtr = parent->getChild<T>(pName);}
|
||||
T* operator->(){return mPtr;}
|
||||
operator T*() const{return mPtr;}
|
||||
T* mPtr;
|
||||
};
|
||||
protected:
|
||||
LLView(const LLView::Params&);
|
||||
//friend class LLUICtrlFactory;
|
||||
@@ -454,6 +464,7 @@ public:
|
||||
const child_list_t* getChildList() const { return &mChildList; }
|
||||
child_list_const_iter_t beginChild() const { return mChildList.begin(); }
|
||||
child_list_const_iter_t endChild() const { return mChildList.end(); }
|
||||
boost::unordered_map<const std::string, LLView*> mChildHashMap;
|
||||
|
||||
// LLMouseHandler functions
|
||||
// Default behavior is to pass events to children
|
||||
@@ -467,13 +478,17 @@ public:
|
||||
/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
|
||||
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect); // Display mToolTipMsg if no child handles it.
|
||||
/*virtual*/ const std::string& getName() const;
|
||||
/*virtual*/ const std::string& getName() const;
|
||||
/*virtual*/ void onMouseCaptureLost();
|
||||
/*virtual*/ BOOL hasMouseCapture();
|
||||
/*virtual*/ BOOL isView(); // Hack to support LLFocusMgr
|
||||
/*virtual*/ void screenPointToLocal(S32 screen_x, S32 screen_y, S32* local_x, S32* local_y) const;
|
||||
/*virtual*/ void localPointToScreen(S32 local_x, S32 local_y, S32* screen_x, S32* screen_y) const;
|
||||
|
||||
template <class T> T* findChild(const std::string& name)
|
||||
{
|
||||
return getChild<T>(name,true,false);
|
||||
}
|
||||
template <class T> T* getChild(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const
|
||||
{
|
||||
LLView* child = getChildView(name, recurse, FALSE);
|
||||
|
||||
@@ -244,6 +244,7 @@ set(viewer_SOURCE_FILES
|
||||
llfloaterpostprocess.cpp
|
||||
llfloaterpreference.cpp
|
||||
llfloaterproperties.cpp
|
||||
llfloaterregiondebugconsole.cpp
|
||||
llfloaterregioninfo.cpp
|
||||
llfloaterreporter.cpp
|
||||
llfloatersearchreplace.cpp
|
||||
@@ -373,6 +374,7 @@ set(viewer_SOURCE_FILES
|
||||
llpanelmsgs.cpp
|
||||
llpanelnetwork.cpp
|
||||
llpanelobject.cpp
|
||||
llpanelpathfindingrebakenavmesh.cpp
|
||||
llpanelpermissions.cpp
|
||||
llpanelpick.cpp
|
||||
llpanelplace.cpp
|
||||
@@ -381,6 +383,15 @@ set(viewer_SOURCE_FILES
|
||||
llpanelweb.cpp
|
||||
llparcelselection.cpp
|
||||
llpatchvertexarray.cpp
|
||||
llpathfindingcharacter.cpp
|
||||
llpathfindingcharacterlist.cpp
|
||||
llpathfindinglinkset.cpp
|
||||
llpathfindinglinksetlist.cpp
|
||||
llpathfindingmanager.cpp
|
||||
llpathfindingnavmesh.cpp
|
||||
llpathfindingnavmeshstatus.cpp
|
||||
llpathfindingobject.cpp
|
||||
llpathfindingobjectlist.cpp
|
||||
llphysicsmotion.cpp
|
||||
llphysicsshapebuilderutil.cpp
|
||||
llpolymesh.cpp
|
||||
@@ -736,6 +747,7 @@ set(viewer_HEADER_FILES
|
||||
llfloaterpreference.h
|
||||
llfloaterperms.h
|
||||
llfloaterproperties.h
|
||||
llfloaterregiondebugconsole.h
|
||||
llfloaterregioninfo.h
|
||||
llfloaterreporter.h
|
||||
llfloatersearchreplace.h
|
||||
@@ -858,7 +870,6 @@ set(viewer_HEADER_FILES
|
||||
llpanellandmedia.h
|
||||
llpanellandobjects.h
|
||||
llpanellandoptions.h
|
||||
llpanelLCD.h
|
||||
llpanellogin.h
|
||||
llpanelmaininventory.h
|
||||
llpanelmorph.h
|
||||
@@ -866,6 +877,7 @@ set(viewer_HEADER_FILES
|
||||
llpanelmsgs.h
|
||||
llpanelnetwork.h
|
||||
llpanelobject.h
|
||||
llpanelpathfindingrebakenavmesh.h
|
||||
llpanelpermissions.h
|
||||
llpanelpick.h
|
||||
llpanelplace.h
|
||||
@@ -874,6 +886,15 @@ set(viewer_HEADER_FILES
|
||||
llpanelweb.h
|
||||
llparcelselection.h
|
||||
llpatchvertexarray.h
|
||||
llpathfindingcharacter.h
|
||||
llpathfindingcharacterlist.h
|
||||
llpathfindinglinkset.h
|
||||
llpathfindinglinksetlist.h
|
||||
llpathfindingmanager.h
|
||||
llpathfindingnavmesh.h
|
||||
llpathfindingnavmeshstatus.h
|
||||
llpathfindingobject.h
|
||||
llpathfindingobjectlist.h
|
||||
llphysicsmotion.h
|
||||
llphysicsshapebuilderutil.h
|
||||
llpolymesh.h
|
||||
@@ -1572,6 +1593,14 @@ if (LINUX)
|
||||
|
||||
set(product ${VIEWER_BRANDING_NAME_CAMELCASE}-${ARCH}-${viewer_VERSION})
|
||||
|
||||
if (FMODEX)
|
||||
if(MANIFEST_LIBRARIES)
|
||||
set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|${FMODEX_LIBRARY}")
|
||||
else(MANIFEST_LIBRARIES)
|
||||
set(MANIFEST_LIBRARIES "--extra_libraries=${FMODEX_LIBRARY}")
|
||||
endif(MANIFEST_LIBRARIES)
|
||||
endif (FMODEX)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${product}.tar.bz2
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
@@ -1590,6 +1619,7 @@ if (LINUX)
|
||||
--dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
|
||||
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
|
||||
--buildtype=${CMAKE_BUILD_TYPE}
|
||||
${MANIFEST_LIBRARIES}
|
||||
DEPENDS secondlife-stripped ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
|
||||
)
|
||||
|
||||
|
||||
@@ -7242,6 +7242,17 @@
|
||||
<key>Value</key>
|
||||
<string>help/index.html</string>
|
||||
</map>
|
||||
<key>WebProfileURL</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>URL for Web Profiles</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>https://my.secondlife.com/[AGENT_NAME]</string>
|
||||
</map>
|
||||
<key>HighResSnapshot</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -13398,7 +13409,7 @@
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>10</integer>
|
||||
<integer>5</integer>
|
||||
</map>
|
||||
<key>SystemLanguage</key>
|
||||
<map>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @file colorFilterF.glsl
|
||||
*
|
||||
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
|
||||
* $License$
|
||||
*/
|
||||
|
||||
#extension GL_ARB_texture_rectangle : enable
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 gl_FragColor;
|
||||
#endif
|
||||
|
||||
uniform sampler2DRect tex0;
|
||||
uniform int layerCount;
|
||||
|
||||
VARYING vec2 vary_texcoord0;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec3 color = pow(floor(pow(vec3(texture2D(tex0, vary_texcoord0.st)),vec3(.6)) * layerCount)/layerCount,vec3(1.66666));
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -23,9 +23,9 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
ATTRIBUTE ivec4 texture_index;
|
||||
ATTRIBUTE int texture_index;
|
||||
|
||||
VARYING_FLAT ivec4 vary_texture_index;
|
||||
VARYING_FLAT int vary_texture_index;
|
||||
|
||||
void passTextureIndex()
|
||||
{
|
||||
|
||||
@@ -174,6 +174,8 @@
|
||||
<boolean>0</boolean>
|
||||
<key>enable_gauss_blur</key>
|
||||
<boolean>0</boolean>
|
||||
<key>enable_posterize</key>
|
||||
<boolean>0</boolean>
|
||||
<key>gauss_blur_passes</key>
|
||||
<integer>2</integer>
|
||||
<key>extract_high</key>
|
||||
@@ -186,6 +188,8 @@
|
||||
<real>0.40000000000000002</real>
|
||||
<key>saturation</key>
|
||||
<real>1</real>
|
||||
</map>
|
||||
<key>posterize_layers</key>
|
||||
<real>10</real>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
@@ -256,7 +256,7 @@ static void request(const std::string &url,
|
||||
LLPumpIO::chain_t chain;
|
||||
|
||||
LLURLRequest *req = new LLURLRequest(method, url);
|
||||
req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
|
||||
req->checkRootCertificate(true);
|
||||
|
||||
/*
|
||||
// Insert custom headers if the caller sent any
|
||||
|
||||
@@ -203,7 +203,7 @@ void ImportTracker::get_update(S32 newid, BOOL justCreated, BOOL createSelected)
|
||||
msg->addBOOLFast(_PREHASH_UsePhysics, gSavedSettings.getBOOL("EmeraldBuildPrefs_Physical"));
|
||||
msg->addBOOLFast(_PREHASH_IsTemporary, gSavedSettings.getBOOL("EmeraldBuildPrefs_Temporary"));
|
||||
msg->addBOOLFast(_PREHASH_IsPhantom, gSavedSettings.getBOOL("EmeraldBuildPrefs_Phantom") );
|
||||
msg->addBOOL("CastsShadows", true );
|
||||
msg->addBOOL("CastsShadows", false );
|
||||
msg->sendReliable(gAgent.getRegion()->getHost());
|
||||
|
||||
if(gSavedSettings.getBOOL("EmeraldBuildPrefs_EmbedItem"))
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "llmoveview.h"
|
||||
#include "llchatbar.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanelpathfindingrebakenavmesh.h"
|
||||
#include "llparcel.h"
|
||||
#include "llrendersphere.h"
|
||||
#include "llsdmessage.h"
|
||||
@@ -1874,6 +1875,8 @@ void LLAgent::endAnimationUpdateUI()
|
||||
gMenuBarView->setVisible(TRUE);
|
||||
gStatusBar->setVisibleForMouselook(true);
|
||||
|
||||
LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(TRUE);
|
||||
|
||||
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
|
||||
|
||||
|
||||
@@ -1962,6 +1965,7 @@ void LLAgent::endAnimationUpdateUI()
|
||||
// hide menus
|
||||
gMenuBarView->setVisible(FALSE);
|
||||
gStatusBar->setVisibleForMouselook(false);
|
||||
LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(FALSE);
|
||||
|
||||
// clear out camera lag effect
|
||||
gAgentCamera.clearCameraLag();
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
#include "llvector4a.h"
|
||||
#include "llfont.h"
|
||||
#include "llvocache.h"
|
||||
#include "llvopartgroup.h"
|
||||
#include "llfloaterteleporthistory.h"
|
||||
|
||||
#include "llweb.h"
|
||||
@@ -216,11 +217,6 @@
|
||||
|
||||
////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor
|
||||
//
|
||||
#if LL_WINDOWS && LL_LCD_COMPILE
|
||||
#include "lllcd.h"
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// viewer.cpp - these are only used in viewer, should be easily moved.
|
||||
|
||||
@@ -602,6 +598,10 @@ bool LLAppViewer::init()
|
||||
|
||||
// initialize SSE options
|
||||
LLVector4a::initClass();
|
||||
|
||||
//initialize particle index pool
|
||||
LLVOPartGroup::initClass();
|
||||
|
||||
// Need to do this initialization before we do anything else, since anything
|
||||
// that touches files should really go through the lldir API
|
||||
gDirUtilp->initAppDirs("SecondLife");
|
||||
@@ -637,9 +637,8 @@ bool LLAppViewer::init()
|
||||
mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling"));
|
||||
// *NOTE:Mani - LLCurl::initClass is not thread safe.
|
||||
// Called before threads are created.
|
||||
LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"),
|
||||
gSavedSettings.getS32("CurlMaximumNumberOfHandles"),
|
||||
gSavedSettings.getBOOL("CurlUseMultipleThreads"));
|
||||
LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"));
|
||||
|
||||
LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
|
||||
|
||||
initThreads();
|
||||
@@ -810,13 +809,6 @@ bool LLAppViewer::init()
|
||||
// call all self-registered classes
|
||||
LLInitClassList::instance().fireCallbacks();
|
||||
|
||||
#if LL_LCD_COMPILE
|
||||
// start up an LCD window on a logitech keyboard, if there is one
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
gLcdScreen = new LLLCD(hInstance);
|
||||
CreateLCDDebugWindows();
|
||||
#endif
|
||||
|
||||
LLFolderViewItem::initClass(); // SJB: Needs to happen after initWindow(), not sure why but related to fonts
|
||||
|
||||
gGLManager.getGLInfo(gDebugInfo);
|
||||
@@ -1198,11 +1190,6 @@ bool LLAppViewer::mainLoop()
|
||||
pingMainloopTimeout("Main:Snapshot");
|
||||
LLFloaterSnapshot::update(); // take snapshots
|
||||
gGLActive = FALSE;
|
||||
#if LL_LCD_COMPILE
|
||||
// update LCD Screen
|
||||
pingMainloopTimeout("Main:LCD");
|
||||
gLcdScreen->UpdateDisplay();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1570,12 +1557,6 @@ bool LLAppViewer::cleanup()
|
||||
// gDXHardware.cleanup();
|
||||
//#endif // LL_WINDOWS
|
||||
|
||||
#if LL_LCD_COMPILE
|
||||
// shut down the LCD window on a logitech keyboard, if there is one
|
||||
delete gLcdScreen;
|
||||
gLcdScreen = NULL;
|
||||
#endif
|
||||
|
||||
LLVolumeMgr* volume_manager = LLPrimitive::getVolumeManager();
|
||||
if (!volume_manager->cleanup())
|
||||
{
|
||||
@@ -1678,6 +1659,8 @@ bool LLAppViewer::cleanup()
|
||||
|
||||
writeDebugInfo();
|
||||
|
||||
if(!gDirUtilp->getLindenUserDir(true).empty())
|
||||
LLViewerMedia::saveCookieFile();
|
||||
// Stop the plugin read thread if it's running.
|
||||
LLPluginProcessParent::setUseReadThread(false);
|
||||
|
||||
|
||||
@@ -165,6 +165,9 @@ BOOL LLChatBar::postBuild()
|
||||
mInputEditor->setEnableLineHistory(TRUE);
|
||||
}
|
||||
|
||||
mHistoryBtn.connect(this,"History");
|
||||
mSayBtn.connect(this,"Say");
|
||||
|
||||
mIsBuilt = TRUE;
|
||||
|
||||
return TRUE;
|
||||
@@ -228,9 +231,9 @@ void LLChatBar::refresh()
|
||||
gAgent.stopTyping();
|
||||
}
|
||||
|
||||
childSetValue("History", LLFloaterChat::instanceVisible(LLSD()));
|
||||
mHistoryBtn->setValue(LLFloaterChat::instanceVisible(LLSD()));
|
||||
|
||||
childSetEnabled("Say", mInputEditor->getText().size() > 0);
|
||||
mSayBtn->setEnabled(mInputEditor->getText().size() > 0);
|
||||
//childSetEnabled("Shout", mInputEditor->getText().size() > 0); createDummyWidget Making Dummy -HgB
|
||||
|
||||
}
|
||||
|
||||
@@ -110,6 +110,9 @@ protected:
|
||||
LLComboBox* mGestureCombo;
|
||||
|
||||
LLChatBarGestureObserver* mObserver;
|
||||
|
||||
CachedUICtrl<LLButton> mHistoryBtn;
|
||||
CachedUICtrl<LLButton> mSayBtn;
|
||||
};
|
||||
|
||||
extern LLChatBar *gChatBar;
|
||||
|
||||
@@ -113,6 +113,7 @@ void LLDrawable::init()
|
||||
|
||||
mGeneration = -1;
|
||||
mBinRadius = 1.f;
|
||||
mBinIndex = -1;
|
||||
mSpatialBridge = NULL;
|
||||
}
|
||||
|
||||
@@ -790,19 +791,7 @@ void LLDrawable::updateTexture()
|
||||
|
||||
if (getVOVolume())
|
||||
{
|
||||
/*if (isActive())
|
||||
{
|
||||
if (isRoot())
|
||||
{
|
||||
mQuietCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
getParent()->mQuietCount = 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
getVOVolume()->mFaceMappingChanged = TRUE;
|
||||
//getVOVolume()->mFaceMappingChanged = TRUE;
|
||||
gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE);
|
||||
}
|
||||
}
|
||||
@@ -963,6 +952,12 @@ void LLDrawable::updateUVMinMax()
|
||||
{
|
||||
}
|
||||
|
||||
LLSpatialGroup* LLDrawable::getSpatialGroup() const
|
||||
{
|
||||
llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
|
||||
return mSpatialGroupp;
|
||||
}
|
||||
|
||||
void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
|
||||
{
|
||||
/*if (mSpatialGroupp && (groupp != mSpatialGroupp))
|
||||
@@ -985,6 +980,8 @@ void LLDrawable::setSpatialGroup(LLSpatialGroup *groupp)
|
||||
}
|
||||
|
||||
mSpatialGroupp = groupp;
|
||||
|
||||
llassert((mSpatialGroupp == NULL) ? getBinIndex() == -1 : getBinIndex() != -1);
|
||||
}
|
||||
|
||||
LLSpatialPartition* LLDrawable::getSpatialPartition()
|
||||
@@ -1107,6 +1104,8 @@ LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 dat
|
||||
mDrawable = root;
|
||||
root->setSpatialBridge(this);
|
||||
|
||||
mBinIndex = -1;
|
||||
|
||||
mRenderType = mDrawable->mRenderType;
|
||||
mDrawableType = mDrawable->mRenderType;
|
||||
|
||||
@@ -1500,7 +1499,13 @@ void LLSpatialBridge::cleanupReferences()
|
||||
LLDrawable::cleanupReferences();
|
||||
if (mDrawable)
|
||||
{
|
||||
mDrawable->setSpatialGroup(NULL);
|
||||
LLSpatialGroup* group = mDrawable->getSpatialGroup();
|
||||
if (group)
|
||||
{
|
||||
group->mOctreeNode->remove(mDrawable);
|
||||
mDrawable->setSpatialGroup(NULL);
|
||||
}
|
||||
|
||||
if (mDrawable->getVObj())
|
||||
{
|
||||
LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren();
|
||||
@@ -1511,7 +1516,12 @@ void LLSpatialBridge::cleanupReferences()
|
||||
LLDrawable* drawable = child->mDrawable;
|
||||
if (drawable)
|
||||
{
|
||||
drawable->setSpatialGroup(NULL);
|
||||
LLSpatialGroup* group = drawable->getSpatialGroup();
|
||||
if (group)
|
||||
{
|
||||
group->mOctreeNode->remove(drawable);
|
||||
drawable->setSpatialGroup(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,9 @@ public:
|
||||
F32 getIntensity() const { return llmin(mXform.getScale().mV[0], 4.f); }
|
||||
S32 getLOD() const { return mVObjp ? mVObjp->getLOD() : 1; }
|
||||
F32 getBinRadius() const { return mBinRadius; }
|
||||
S32 getBinIndex() const { return mBinIndex; }
|
||||
void setBinIndex(S32 index) const { mBinIndex = index; }
|
||||
|
||||
void getMinMax(LLVector3& min,LLVector3& max) const { mXform.getMinMax(min,max); }
|
||||
LLXformMatrix* getXform() { return &mXform; }
|
||||
|
||||
@@ -200,7 +203,7 @@ public:
|
||||
S32 findReferences(LLDrawable *drawablep); // Not const because of @#$! iterators...
|
||||
|
||||
void setSpatialGroup(LLSpatialGroup *groupp);
|
||||
LLSpatialGroup *getSpatialGroup() const { return mSpatialGroupp; }
|
||||
LLSpatialGroup *getSpatialGroup() const;
|
||||
LLSpatialPartition* getSpatialPartition();
|
||||
|
||||
// Statics
|
||||
@@ -321,6 +324,7 @@ private:
|
||||
mutable U32 mVisible;
|
||||
F32 mRadius;
|
||||
F32 mBinRadius;
|
||||
mutable S32 mBinIndex;
|
||||
S32 mGeneration;
|
||||
|
||||
LLVector3 mCurrentScale;
|
||||
|
||||
@@ -446,7 +446,7 @@ void LLRenderPass::renderTexture(U32 type, U32 mask)
|
||||
|
||||
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
|
||||
{
|
||||
for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
|
||||
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
|
||||
{
|
||||
LLDrawInfo* pparams = *i;
|
||||
if (pparams)
|
||||
|
||||
@@ -355,7 +355,7 @@ void LLDrawPoolAlpha::render(S32 pass)
|
||||
|
||||
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
|
||||
{
|
||||
for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
|
||||
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
|
||||
{
|
||||
LLSpatialGroup* group = *i;
|
||||
if (group->mSpatialPartition->mRenderByGroup &&
|
||||
@@ -392,7 +392,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
|
||||
|
||||
BOOL use_shaders = gPipeline.canUseVertexShaders();
|
||||
|
||||
for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
|
||||
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
|
||||
{
|
||||
LLSpatialGroup* group = *i;
|
||||
llassert(group);
|
||||
|
||||
@@ -1203,15 +1203,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
|
||||
if (pass >= 7 && pass < 9)
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
|
||||
LLRender::BF_ZERO,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
|
||||
|
||||
|
||||
if (pass == 7)
|
||||
{
|
||||
renderRiggedAlpha(avatarp);
|
||||
@@ -1227,20 +1218,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
|
||||
|
||||
if (pass == 9)
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
LLGLDisable test(GL_ALPHA_TEST);
|
||||
gGL.flush();
|
||||
|
||||
LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -1.0f);
|
||||
gGL.setSceneBlendType(LLRender::BT_ADD);
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
gGL.setColorMask(false, true);
|
||||
|
||||
renderRiggedGlow(avatarp);
|
||||
gGL.setColorMask(true, false);
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1640,17 +1619,56 @@ void LLDrawPoolAvatar::renderRiggedFullbrightShiny(LLVOAvatar* avatar)
|
||||
|
||||
void LLDrawPoolAvatar::renderRiggedAlpha(LLVOAvatar* avatar)
|
||||
{
|
||||
renderRigged(avatar, RIGGED_ALPHA);
|
||||
if (!mRiggedFace[RIGGED_ALPHA].empty())
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
|
||||
LLRender::BF_ZERO,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
|
||||
|
||||
renderRigged(avatar, RIGGED_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::renderRiggedFullbrightAlpha(LLVOAvatar* avatar)
|
||||
{
|
||||
renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
|
||||
if (!mRiggedFace[RIGGED_FULLBRIGHT_ALPHA].empty())
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
gGL.blendFunc(LLRender::BF_SOURCE_ALPHA,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA,
|
||||
LLRender::BF_ZERO,
|
||||
LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
|
||||
|
||||
renderRigged(avatar, RIGGED_FULLBRIGHT_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawPoolAvatar::renderRiggedGlow(LLVOAvatar* avatar)
|
||||
{
|
||||
renderRigged(avatar, RIGGED_GLOW, true);
|
||||
if (!mRiggedFace[RIGGED_GLOW].empty())
|
||||
{
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
LLGLDisable test(GL_ALPHA_TEST);
|
||||
gGL.flush();
|
||||
|
||||
LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -1.0f);
|
||||
gGL.setSceneBlendType(LLRender::BT_ADD);
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
|
||||
gGL.setColorMask(false, true);
|
||||
|
||||
renderRigged(avatar, RIGGED_GLOW, true);
|
||||
|
||||
gGL.setColorMask(true, false);
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -848,12 +848,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
|
||||
LLFastTimer ftm(FTM_RENDER_BUMP);
|
||||
|
||||
U32 type = LLRenderPass::PASS_BUMP;
|
||||
LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
|
||||
|
||||
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_BINORMAL | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
|
||||
|
||||
for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
@@ -1449,10 +1449,10 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
|
||||
|
||||
void LLDrawPoolBump::renderBump(U32 type, U32 mask)
|
||||
{
|
||||
LLCullResult::drawinfo_list_t::iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_list_t::iterator end = gPipeline.endRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
|
||||
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
|
||||
|
||||
for (LLCullResult::drawinfo_list_t::iterator i = begin; i != end; ++i)
|
||||
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
|
||||
{
|
||||
LLDrawInfo& params = **i;
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
|
||||
mAvatarp(avatarp),
|
||||
mWearablep(NULL)
|
||||
{
|
||||
mDefaultVec.clear();
|
||||
}
|
||||
|
||||
LLDriverParam::LLDriverParam(LLWearable *wearablep) :
|
||||
@@ -162,6 +163,7 @@ LLDriverParam::LLDriverParam(LLWearable *wearablep) :
|
||||
mAvatarp(NULL),
|
||||
mWearablep(wearablep)
|
||||
{
|
||||
mDefaultVec.clear();
|
||||
}
|
||||
|
||||
LLDriverParam::~LLDriverParam()
|
||||
@@ -341,18 +343,19 @@ F32 LLDriverParam::getTotalDistortion()
|
||||
return sum;
|
||||
}
|
||||
|
||||
const LLVector3 &LLDriverParam::getAvgDistortion()
|
||||
const LLVector4a &LLDriverParam::getAvgDistortion()
|
||||
{
|
||||
// It's not actually correct to take the average of averages, but it good enough here.
|
||||
LLVector3 sum;
|
||||
LLVector4a sum;
|
||||
sum.clear();
|
||||
S32 count = 0;
|
||||
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
|
||||
{
|
||||
LLDrivenEntry* driven = &(*iter);
|
||||
sum += driven->mParam->getAvgDistortion();
|
||||
sum.add(driven->mParam->getAvgDistortion());
|
||||
count++;
|
||||
}
|
||||
sum /= (F32)count;
|
||||
sum.mul( 1.f/(F32)count);
|
||||
|
||||
mDefaultVec = sum;
|
||||
return mDefaultVec;
|
||||
@@ -375,21 +378,22 @@ F32 LLDriverParam::getMaxDistortion()
|
||||
}
|
||||
|
||||
|
||||
LLVector3 LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
|
||||
LLVector4a LLDriverParam::getVertexDistortion(S32 index, LLPolyMesh *poly_mesh)
|
||||
{
|
||||
LLVector3 sum;
|
||||
LLVector4a sum;
|
||||
sum.clear();
|
||||
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
|
||||
{
|
||||
LLDrivenEntry* driven = &(*iter);
|
||||
sum += driven->mParam->getVertexDistortion( index, poly_mesh );
|
||||
sum.add(driven->mParam->getVertexDistortion( index, poly_mesh ));
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
|
||||
const LLVector4a* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh)
|
||||
{
|
||||
mCurrentDistortionParam = NULL;
|
||||
const LLVector3* v = NULL;
|
||||
const LLVector4a* v = NULL;
|
||||
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
|
||||
{
|
||||
LLDrivenEntry* driven = &(*iter);
|
||||
@@ -404,7 +408,7 @@ const LLVector3* LLDriverParam::getFirstDistortion(U32 *index, LLPolyMesh **poly
|
||||
return v;
|
||||
};
|
||||
|
||||
const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
|
||||
const LLVector4a* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_mesh)
|
||||
{
|
||||
llassert( mCurrentDistortionParam );
|
||||
if( !mCurrentDistortionParam )
|
||||
@@ -432,7 +436,7 @@ const LLVector3* LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly_
|
||||
}
|
||||
|
||||
// We're already in the middle of a param's distortions, so get the next one.
|
||||
const LLVector3* v = driven->mParam->getNextDistortion( index, poly_mesh );
|
||||
const LLVector4a* v = driven->mParam->getNextDistortion( index, poly_mesh );
|
||||
if( (!v) && (iter != mDriven.end()) )
|
||||
{
|
||||
// This param is finished, so start the next param. It might not have any
|
||||
|
||||
@@ -105,18 +105,18 @@ public:
|
||||
|
||||
// LLViewerVisualParam Virtual functions
|
||||
/*virtual*/ F32 getTotalDistortion();
|
||||
/*virtual*/ const LLVector3& getAvgDistortion();
|
||||
/*virtual*/ const LLVector4a& getAvgDistortion();
|
||||
/*virtual*/ F32 getMaxDistortion();
|
||||
/*virtual*/ LLVector3 getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
|
||||
/*virtual*/ const LLVector3* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
|
||||
/*virtual*/ const LLVector3* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
|
||||
/*virtual*/ LLVector4a getVertexDistortion(S32 index, LLPolyMesh *poly_mesh);
|
||||
/*virtual*/ const LLVector4a* getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
|
||||
/*virtual*/ const LLVector4a* getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
|
||||
|
||||
protected:
|
||||
F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
|
||||
void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
|
||||
|
||||
|
||||
LLVector3 mDefaultVec; // temp holder
|
||||
LLVector4a mDefaultVec; // temp holder
|
||||
typedef std::vector<LLDrivenEntry> entry_list_t;
|
||||
entry_list_t mDriven;
|
||||
LLViewerVisualParam* mCurrentDistortionParam;
|
||||
|
||||
@@ -169,19 +169,10 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
||||
mGeomCount = 0;
|
||||
mGeomIndex = 0;
|
||||
mIndicesCount = 0;
|
||||
if (drawablep->getRenderType() == LLPipeline::RENDER_TYPE_PARTICLES ||
|
||||
drawablep->getRenderType() == LLPipeline::RENDER_TYPE_HUD_PARTICLES
|
||||
#if ENABLE_CLASSIC_CLOUDS
|
||||
|| drawablep->getRenderType() == LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS
|
||||
#endif
|
||||
)
|
||||
{ //indicate to LLParticlePartition that this particle is uninitialized
|
||||
mIndicesIndex = 0xFFFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIndicesIndex = 0;
|
||||
}
|
||||
|
||||
//special value to indicate uninitialized position
|
||||
mIndicesIndex = 0xFFFFFFFF;
|
||||
|
||||
mIndexInTex = 0;
|
||||
mTexture = NULL;
|
||||
mTEOffset = -1;
|
||||
@@ -214,17 +205,10 @@ void LLFace::destroy()
|
||||
mTexture->removeFace(this) ;
|
||||
}
|
||||
|
||||
if (mDrawablep.notNull() &&
|
||||
(mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_PARTICLES ||
|
||||
mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_HUD_PARTICLES
|
||||
#if ENABLE_CLASSIC_CLOUDS
|
||||
|| mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS
|
||||
#endif
|
||||
) &&
|
||||
mIndicesIndex != 0xFFFFFFFF)
|
||||
if (isState(LLFace::PARTICLE))
|
||||
{
|
||||
LLVOPartGroup::freeVBSlot(getGeomIndex()/4);
|
||||
mIndicesIndex = 0xFFFFFFFF;
|
||||
clearState(LLFace::PARTICLE);
|
||||
}
|
||||
|
||||
if (mDrawPoolp)
|
||||
@@ -335,7 +319,20 @@ void LLFace::setTexture(LLViewerTexture* tex)
|
||||
|
||||
void LLFace::dirtyTexture()
|
||||
{
|
||||
gPipeline.markTextured(getDrawable());
|
||||
LLDrawable* drawablep = getDrawable();
|
||||
|
||||
if (mVObjp.notNull() && mVObjp->getVolume() &&
|
||||
mTexture.notNull() && mTexture->getComponents() == 4)
|
||||
{ //dirty texture on an alpha object should be treated as an LoD update
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
if (vobj)
|
||||
{
|
||||
vobj->mLODChanged = TRUE;
|
||||
}
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
|
||||
}
|
||||
|
||||
gPipeline.markTextured(drawablep);
|
||||
}
|
||||
|
||||
void LLFace::switchTexture(LLViewerTexture* new_texture)
|
||||
@@ -1209,19 +1206,25 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
{
|
||||
if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())
|
||||
{
|
||||
llwarns << "Index buffer overflow!" << llendl;
|
||||
llwarns << "Indices Count: " << mIndicesCount
|
||||
<< " VF Num Indices: " << num_indices
|
||||
<< " Indices Index: " << mIndicesIndex
|
||||
<< " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
|
||||
llwarns << " Face Index: " << f
|
||||
<< " Pool Type: " << mPoolType << llendl;
|
||||
if (gDebugGL)
|
||||
{
|
||||
llwarns << "Index buffer overflow!" << llendl;
|
||||
llwarns << "Indices Count: " << mIndicesCount
|
||||
<< " VF Num Indices: " << num_indices
|
||||
<< " Indices Index: " << mIndicesIndex
|
||||
<< " VB Num Indices: " << mVertexBuffer->getNumIndices() << llendl;
|
||||
llwarns << " Face Index: " << f
|
||||
<< " Pool Type: " << mPoolType << llendl;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (num_vertices + mGeomIndex > mVertexBuffer->getNumVerts())
|
||||
{
|
||||
llwarns << "Vertex buffer overflow!" << llendl;
|
||||
if (gDebugGL)
|
||||
{
|
||||
llwarns << "Vertex buffer overflow!" << llendl;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1632,7 +1635,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
if (!do_xform)
|
||||
{
|
||||
LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM);
|
||||
LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32));
|
||||
S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
|
||||
LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1853,15 +1857,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
|
||||
|
||||
LLVector4a texIdx;
|
||||
|
||||
U8 index = mTextureIndex < 255 ? mTextureIndex : 0;
|
||||
S32 index = mTextureIndex < 255 ? mTextureIndex : 0;
|
||||
|
||||
F32 val = 0.f;
|
||||
U8* vp = (U8*) &val;
|
||||
vp[0] = index;
|
||||
vp[1] = 0;
|
||||
vp[2] = 0;
|
||||
vp[3] = 0;
|
||||
|
||||
S32* vp = (S32*) &val;
|
||||
*vp = index;
|
||||
|
||||
llassert(index <= LLGLSLShader::sIndexedTextureChannels-1);
|
||||
|
||||
LLVector4Logical mask;
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
USE_FACE_COLOR = 0x0010,
|
||||
TEXTURE_ANIM = 0x0020,
|
||||
RIGGED = 0x0040,
|
||||
PARTICLE = 0x0080,
|
||||
};
|
||||
|
||||
static void initClass();
|
||||
|
||||
@@ -255,50 +255,28 @@ void LLVolumeImplFlexible::onSetVolume(const LLVolumeParams &volume_params, cons
|
||||
{
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// This calculates the physics of the flexible object. Note that it has to be 0
|
||||
// updated every time step. In the future, perhaps there could be an
|
||||
// optimization similar to what Havok does for objects that are stationary.
|
||||
//---------------------------------------------------------------------------------
|
||||
static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
|
||||
BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
|
||||
|
||||
void LLVolumeImplFlexible::updateRenderRes()
|
||||
{
|
||||
if (mVO->mDrawable.isNull())
|
||||
{
|
||||
// Don't do anything until we have a drawable
|
||||
return FALSE; // (we are not initialized or updated)
|
||||
}
|
||||
LLDrawable* drawablep = mVO->mDrawable;
|
||||
|
||||
BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
|
||||
|
||||
//flexible objects never go static
|
||||
mVO->mDrawable->mQuietCount = 0;
|
||||
if (!mVO->mDrawable->isRoot())
|
||||
{
|
||||
LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
|
||||
parent->mDrawable->mQuietCount = 0;
|
||||
}
|
||||
|
||||
LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
|
||||
|
||||
S32 new_res = mAttributes->getSimulateLOD();
|
||||
|
||||
//number of segments only cares about z axis
|
||||
F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, mVO->mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
|
||||
#if 1 //optimal approximation of previous behavior that doesn't rely on atan2
|
||||
F32 app_angle = mVO->getScale().mV[2]/drawablep->mDistanceWRTCamera;
|
||||
|
||||
// Rendering sections increases with visible angle on the screen
|
||||
mRenderRes = (S32) (12.f*app_angle);
|
||||
#else //legacy behavior
|
||||
//number of segments only cares about z axis
|
||||
F32 app_angle = llround((F32) atan2( mVO->getScale().mV[2]*2.f, drawablep->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
|
||||
|
||||
// Rendering sections increases with visible angle on the screen
|
||||
mRenderRes = (S32)(FLEXIBLE_OBJECT_MAX_SECTIONS*4*app_angle*DEG_TO_RAD/LLViewerCamera::getInstance()->getView());
|
||||
if (mRenderRes > FLEXIBLE_OBJECT_MAX_SECTIONS)
|
||||
{
|
||||
mRenderRes = FLEXIBLE_OBJECT_MAX_SECTIONS;
|
||||
}
|
||||
|
||||
|
||||
// Bottom cap at 1/4 the original number of sections
|
||||
if (mRenderRes < mAttributes->getSimulateLOD()-1)
|
||||
{
|
||||
mRenderRes = mAttributes->getSimulateLOD()-1;
|
||||
}
|
||||
#endif
|
||||
|
||||
mRenderRes = llclamp(mRenderRes, new_res-1, (S32) FLEXIBLE_OBJECT_MAX_SECTIONS);
|
||||
|
||||
// Throttle back simulation of segments we're not rendering
|
||||
if (mRenderRes < new_res)
|
||||
{
|
||||
@@ -311,43 +289,67 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6
|
||||
setAttributesOfAllSections();
|
||||
mInitialized = TRUE;
|
||||
}
|
||||
if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
|
||||
{
|
||||
return FALSE; // (we are not initialized or updated)
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
// This calculates the physics of the flexible object. Note that it has to be 0
|
||||
// updated every time step. In the future, perhaps there could be an
|
||||
// optimization similar to what Havok does for objects that are stationary.
|
||||
//---------------------------------------------------------------------------------
|
||||
static LLFastTimer::DeclareTimer FTM_FLEXIBLE_UPDATE("Update Flexies");
|
||||
void LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
|
||||
{
|
||||
LLDrawable* drawablep = mVO->mDrawable;
|
||||
|
||||
bool visible = mVO->mDrawable->isVisible();
|
||||
|
||||
if (force_update && visible)
|
||||
if (drawablep)
|
||||
{
|
||||
gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
}
|
||||
else if (visible &&
|
||||
!mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) &&
|
||||
mVO->getPixelArea() > 256.f)
|
||||
{
|
||||
U32 id;
|
||||
F32 pixel_area = mVO->getPixelArea();
|
||||
//LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
|
||||
|
||||
if (mVO->isRootEdit())
|
||||
//flexible objects never go static
|
||||
drawablep->mQuietCount = 0;
|
||||
if (!drawablep->isRoot())
|
||||
{
|
||||
id = mID;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
|
||||
id = parent->getVolumeInterfaceID();
|
||||
LLViewerObject* parent = (LLViewerObject*) mVO->getParent();
|
||||
parent->mDrawable->mQuietCount = 0;
|
||||
}
|
||||
|
||||
U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
|
||||
|
||||
if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
|
||||
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
|
||||
{
|
||||
gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
}
|
||||
bool visible = drawablep->isVisible();
|
||||
|
||||
if ((mSimulateRes == 0) && visible)
|
||||
{
|
||||
updateRenderRes();
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
}
|
||||
else if (visible &&
|
||||
!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
|
||||
mVO->getPixelArea() > 256.f)
|
||||
{
|
||||
U32 id;
|
||||
F32 pixel_area = mVO->getPixelArea();
|
||||
|
||||
if (mVO->isRootEdit())
|
||||
{
|
||||
id = mID;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
|
||||
id = parent->getVolumeInterfaceID();
|
||||
}
|
||||
|
||||
U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1;
|
||||
|
||||
if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
|
||||
{
|
||||
updateRenderRes();
|
||||
gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!mInitialized)
|
||||
updateRenderRes();
|
||||
}
|
||||
|
||||
return force_update;
|
||||
}
|
||||
|
||||
inline S32 log2(S32 x)
|
||||
@@ -368,8 +370,11 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
|
||||
LLPath *path = &volume->getPath();
|
||||
if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible())
|
||||
{
|
||||
//mVO->markForUpdate(TRUE);
|
||||
if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0))
|
||||
BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
|
||||
|
||||
doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0);
|
||||
|
||||
if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
|
||||
{
|
||||
return; // we did not get updated or initialized, proceeding without can be dangerous
|
||||
}
|
||||
|
||||
@@ -84,7 +84,8 @@ class LLVolumeImplFlexible : public LLVolumeInterface
|
||||
LLVector3 getFramePosition() const;
|
||||
LLQuaternion getFrameRotation() const;
|
||||
LLVolumeInterfaceType getInterfaceType() const { return INTERFACE_FLEXIBLE; }
|
||||
BOOL doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
|
||||
void updateRenderRes();
|
||||
void doIdleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
|
||||
BOOL doUpdateGeometry(LLDrawable *drawable);
|
||||
LLVector3 getPivotPosition() const;
|
||||
void onSetVolume(const LLVolumeParams &volume_params, const S32 detail);
|
||||
|
||||
@@ -353,6 +353,13 @@ BOOL LLPanelActiveSpeakers::postBuild()
|
||||
childSetCommitCallback("moderator_allow_text", onModeratorMuteText, this);
|
||||
childSetCommitCallback("moderation_mode", onChangeModerationMode, this);
|
||||
|
||||
mVolumeSlider.connect(this,"speaker_volume");
|
||||
mModeratorCtrlLbl.connect(this,"moderator_controls_label");
|
||||
mModeratorAllowVoiceCheckbox.connect(this,"moderator_allow_voice");
|
||||
mModeratorAllowTextCheckbox.connect(this,"moderator_allow_text");
|
||||
mModeratorModePanel.connect(this,"moderation_mode_panel");
|
||||
mModeratorControlsPanel.connect(this,"moderator_controls");
|
||||
|
||||
// update speaker UI
|
||||
handleSpeakerSelect();
|
||||
|
||||
@@ -625,25 +632,21 @@ void LLPanelActiveSpeakers::refreshSpeakers()
|
||||
//&& !LLMuteList::getInstance()->isLinden(selected_speakerp->mDisplayName));
|
||||
&& !LLMuteList::getInstance()->isLinden(selected_speakerp->mLegacyName));
|
||||
}
|
||||
childSetValue("speaker_volume", gVoiceClient->getUserVolume(selected_id));
|
||||
childSetEnabled("speaker_volume", LLVoiceClient::voiceEnabled()
|
||||
mVolumeSlider->setValue(gVoiceClient->getUserVolume(selected_id));
|
||||
mVolumeSlider->setEnabled(LLVoiceClient::voiceEnabled()
|
||||
&& gVoiceClient->getVoiceEnabled(selected_id)
|
||||
&& selected_id.notNull()
|
||||
&& selected_id != gAgent.getID()
|
||||
&& (selected_speakerp.notNull() && (selected_speakerp->mType == LLSpeaker::SPEAKER_AGENT || selected_speakerp->mType == LLSpeaker::SPEAKER_EXTERNAL)));
|
||||
|
||||
childSetEnabled(
|
||||
"moderator_controls_label",
|
||||
selected_id.notNull());
|
||||
mModeratorCtrlLbl->setEnabled(selected_id.notNull());
|
||||
|
||||
childSetEnabled(
|
||||
"moderator_allow_voice",
|
||||
mModeratorAllowVoiceCheckbox->setEnabled(
|
||||
selected_id.notNull()
|
||||
&& mSpeakerMgr->isVoiceActive()
|
||||
&& gVoiceClient->getVoiceEnabled(selected_id));
|
||||
|
||||
childSetEnabled(
|
||||
"moderator_allow_text",
|
||||
mModeratorAllowTextCheckbox->setEnabled(
|
||||
selected_id.notNull());
|
||||
|
||||
if (mProfileBtn)
|
||||
@@ -668,8 +671,8 @@ void LLPanelActiveSpeakers::refreshSpeakers()
|
||||
LLPointer<LLSpeaker> self_speakerp = mSpeakerMgr->findSpeaker(gAgent.getID());
|
||||
if(self_speakerp)
|
||||
{
|
||||
childSetVisible("moderation_mode_panel", self_speakerp->mIsModerator && mSpeakerMgr->isVoiceActive());
|
||||
childSetVisible("moderator_controls", self_speakerp->mIsModerator);
|
||||
mModeratorModePanel->setVisible(self_speakerp->mIsModerator && mSpeakerMgr->isVoiceActive());
|
||||
mModeratorControlsPanel->setVisible(self_speakerp->mIsModerator);
|
||||
}
|
||||
|
||||
// keep scroll value stable
|
||||
|
||||
@@ -46,6 +46,9 @@ class LLButton;
|
||||
class LLPanelActiveSpeakers;
|
||||
class LLSpeakerMgr;
|
||||
class LLVoiceChannel;
|
||||
class LLSlider;
|
||||
class LLTextBox;
|
||||
class LLCheckBoxCtrl;
|
||||
|
||||
|
||||
// data for a given participant in a voice channel
|
||||
@@ -296,6 +299,13 @@ protected:
|
||||
LLPointer<SpeakerAddListener> mSpeakerAddListener;
|
||||
LLPointer<SpeakerRemoveListener> mSpeakerRemoveListener;
|
||||
LLPointer<SpeakerClearListener> mSpeakerClearListener;
|
||||
|
||||
CachedUICtrl<LLUICtrl> mVolumeSlider;
|
||||
CachedUICtrl<LLTextBox> mModeratorCtrlLbl;
|
||||
CachedUICtrl<LLCheckBoxCtrl> mModeratorAllowVoiceCheckbox;
|
||||
CachedUICtrl<LLCheckBoxCtrl> mModeratorAllowTextCheckbox;
|
||||
CachedUICtrl<LLPanel> mModeratorModePanel;
|
||||
CachedUICtrl<LLPanel> mModeratorControlsPanel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "llcommandhandler.h"
|
||||
#include "llpanelavatar.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llweb.h"
|
||||
|
||||
// linden library includes
|
||||
#include "llinventory.h"
|
||||
@@ -293,3 +294,13 @@ LLPreview::EAssetStatus LLFloaterAvatarInfo::getAssetStatus()
|
||||
}
|
||||
return mAssetStatus;
|
||||
}
|
||||
|
||||
std::string getProfileURL(const std::string& agent_name)
|
||||
{
|
||||
std::string url = gSavedSettings.getString("WebProfileURL");
|
||||
LLSD subs;
|
||||
subs["AGENT_NAME"] = agent_name;
|
||||
url = LLWeb::expandURLSubstitutions(url,subs);
|
||||
LLStringUtil::toLower(url);
|
||||
return url;
|
||||
}
|
||||
|
||||
@@ -101,5 +101,6 @@ private:
|
||||
EOnlineStatus mSuggestedOnlineStatus;
|
||||
};
|
||||
|
||||
std::string getProfileURL(const std::string& agent_name);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -135,9 +135,9 @@ void LLFloaterChat::draw()
|
||||
{
|
||||
// enable say and shout only when text available
|
||||
|
||||
childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
|
||||
mToggleActiveSpeakersBtn->setValue(mPanel->getVisible());
|
||||
|
||||
LLChatBar* chat_barp = getChild<LLChatBar>("chat_panel", TRUE);
|
||||
LLChatBar* chat_barp = mChatPanel;
|
||||
if (chat_barp)
|
||||
{
|
||||
chat_barp->refresh();
|
||||
@@ -156,6 +156,9 @@ BOOL LLFloaterChat::postBuild()
|
||||
{
|
||||
chat_barp->setGestureCombo(getChild<LLComboBox>( "Gesture"));
|
||||
}
|
||||
|
||||
mToggleActiveSpeakersBtn.connect(this,"toggle_active_speakers_btn");
|
||||
mChatPanel.connect(this,"chat_panel");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -452,20 +455,6 @@ void LLFloaterChat::addChat(const LLChat& chat,
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
#if LL_LCD_COMPILE
|
||||
// add into LCD displays
|
||||
if (!invisible_script_debug_chat)
|
||||
{
|
||||
if (!from_instant_message)
|
||||
{
|
||||
AddNewChatToLCD(chat.mText);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddNewIMToLCD(chat.mText);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!invisible_script_debug_chat
|
||||
&& !chat.mMuted
|
||||
&& gConsole
|
||||
|
||||
@@ -50,6 +50,7 @@ class LLUUID;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLPanelActiveSpeakers;
|
||||
class LLLogChat;
|
||||
class LLChatBar;
|
||||
|
||||
class LLFloaterChat
|
||||
: public LLFloater, public LLUISingleton<LLFloaterChat, LLFloaterChat>
|
||||
@@ -95,6 +96,9 @@ public:
|
||||
|
||||
LLPanelActiveSpeakers* mPanel;
|
||||
BOOL mScrolledToEnd;
|
||||
|
||||
CachedUICtrl<LLButton> mToggleActiveSpeakersBtn;
|
||||
CachedUICtrl<LLChatBar> mChatPanel;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
#include "lldaycyclemanager.h"
|
||||
#include "llwlparamset.h"
|
||||
#include "llwlparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
#include "llfloaterwindlight.h"
|
||||
|
||||
|
||||
|
||||
@@ -80,8 +80,6 @@
|
||||
// <dogmode> stuff for Contact groups
|
||||
#include "ascentfloatercontactgroups.h"
|
||||
|
||||
//Maximum number of people you can select to do an operation on at once.
|
||||
#define MAX_FRIEND_SELECT 20
|
||||
#define DEFAULT_PERIOD 5.0
|
||||
#define RIGHTS_CHANGE_TIMEOUT 5.0
|
||||
#define OBSERVER_TIMEOUT 0.5
|
||||
@@ -368,8 +366,6 @@ void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data)
|
||||
BOOL LLPanelFriends::postBuild()
|
||||
{
|
||||
mFriendsList = getChild<LLScrollListCtrl>("friend_list");
|
||||
mFriendsList->setMaxSelectable(MAX_FRIEND_SELECT);
|
||||
mFriendsList->setMaximumSelectCallback(onMaximumSelect);
|
||||
mFriendsList->setCommitOnSelectionChange(TRUE);
|
||||
childSetCommitCallback("friend_list", onSelectName, this);
|
||||
childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this);
|
||||
@@ -816,14 +812,6 @@ void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLPanelFriends::onMaximumSelect(void* user_data)
|
||||
{
|
||||
LLSD args;
|
||||
args["MAX_SELECT"] = llformat("%d", MAX_FRIEND_SELECT);
|
||||
LLNotificationsUtil::add("MaxListSelectMessage", args);
|
||||
};
|
||||
|
||||
// static
|
||||
void LLPanelFriends::onClickProfile(void* user_data)
|
||||
{
|
||||
|
||||
@@ -135,7 +135,6 @@ private:
|
||||
static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
|
||||
static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
|
||||
static void onPickAvatar(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data);
|
||||
static void onMaximumSelect(void* user_data);
|
||||
static void onContactSearchEdit(const std::string& search_string, void* user_data);
|
||||
static void onClickIM(void* user_data);
|
||||
static void onClickAssign(void* user_data);
|
||||
|
||||
@@ -115,17 +115,8 @@ LLFloaterPostProcess* LLFloaterPostProcess::instance()
|
||||
|
||||
void LLFloaterPostProcess::onControlChanged(LLUICtrl* ctrl, void* userData)
|
||||
{
|
||||
char const *VariableName = (char const *)userData;
|
||||
char buf[256];
|
||||
S32 elem=0;
|
||||
if(sscanf(VariableName,"%255[^[][%d]", buf, &elem) == 2)
|
||||
{
|
||||
LLPostProcess::getInstance()->tweaks[(const char*)buf][elem] = ctrl->getValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPostProcess::getInstance()->tweaks[VariableName] = ctrl->getValue();
|
||||
}
|
||||
LLSD v = ctrl->getValue();
|
||||
LLPostProcess::getInstance()->setSelectedEffectValue((char const *)userData, v);
|
||||
}
|
||||
|
||||
void LLFloaterPostProcess::onLoadEffect(void* userData)
|
||||
@@ -145,7 +136,7 @@ void LLFloaterPostProcess::onSaveEffect(void* userData)
|
||||
|
||||
std::string effectName(editBox->getValue().asString());
|
||||
|
||||
if (LLPostProcess::getInstance()->mAllEffects.has(effectName))
|
||||
if (LLPostProcess::getInstance()->getAllEffectInfo().has(effectName))
|
||||
{
|
||||
LLSD payload;
|
||||
payload["effect_name"] = effectName;
|
||||
@@ -153,7 +144,7 @@ void LLFloaterPostProcess::onSaveEffect(void* userData)
|
||||
}
|
||||
else
|
||||
{
|
||||
LLPostProcess::getInstance()->saveEffect(effectName);
|
||||
LLPostProcess::getInstance()->saveEffectAs(effectName);
|
||||
sPostProcess->syncMenu();
|
||||
}
|
||||
}
|
||||
@@ -175,7 +166,7 @@ bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLS
|
||||
// if they choose save, do it. Otherwise, don't do anything
|
||||
if (option == 0)
|
||||
{
|
||||
LLPostProcess::getInstance()->saveEffect(notification["payload"]["effect_name"].asString());
|
||||
LLPostProcess::getInstance()->saveEffectAs(notification["payload"]["effect_name"].asString());
|
||||
|
||||
sPostProcess->syncMenu();
|
||||
}
|
||||
@@ -209,17 +200,17 @@ void LLFloaterPostProcess::syncMenu()
|
||||
comboBox->removeall();
|
||||
|
||||
LLSD::map_const_iterator currEffect;
|
||||
for(currEffect = LLPostProcess::getInstance()->mAllEffects.beginMap();
|
||||
currEffect != LLPostProcess::getInstance()->mAllEffects.endMap();
|
||||
for(currEffect = LLPostProcess::getInstance()->getAllEffectInfo().beginMap();
|
||||
currEffect != LLPostProcess::getInstance()->getAllEffectInfo().endMap();
|
||||
++currEffect)
|
||||
{
|
||||
comboBox->add(currEffect->first);
|
||||
}
|
||||
|
||||
// set the current effect as selected.
|
||||
comboBox->selectByValue(LLPostProcess::getInstance()->getSelectedEffect());
|
||||
comboBox->selectByValue(LLPostProcess::getInstance()->getSelectedEffectName());
|
||||
|
||||
LLSD &tweaks = LLPostProcess::getInstance()->tweaks;
|
||||
const LLSD &tweaks = LLPostProcess::getInstance()->getSelectedEffectInfo();
|
||||
//Iterate down all uniforms handled by post-process shaders. Update any linked ui elements.
|
||||
for (LLSD::map_const_iterator it = tweaks.beginMap(); it != tweaks.endMap(); ++it)
|
||||
{
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
#include "llpanelgeneral.h"
|
||||
#include "llpanelinput.h"
|
||||
#include "llpanellogin.h"
|
||||
#include "llpanelLCD.h"
|
||||
#include "llpanelmsgs.h"
|
||||
#include "llpanelweb.h"
|
||||
#include "llpanelskins.h"
|
||||
@@ -178,20 +177,6 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def
|
||||
mTabContainer->addTabPanel(mPrefsIM->getPanel(), mPrefsIM->getPanel()->getLabel());
|
||||
mPrefsIM->getPanel()->setDefaultBtn(default_btn);
|
||||
|
||||
#if LL_LCD_COMPILE
|
||||
|
||||
// only add this option if we actually have a logitech keyboard / speaker set
|
||||
if (gLcdScreen->Enabled())
|
||||
{
|
||||
mLCDPanel = new LLPanelLCD();
|
||||
mTabContainer->addTabPanel(mLCDPanel, mLCDPanel->getLabel());
|
||||
mLCDPanel->setDefaultBtn(default_btn);
|
||||
}
|
||||
|
||||
#else
|
||||
mLCDPanel = NULL;
|
||||
#endif
|
||||
|
||||
mMsgPanel = new LLPanelMsgs();
|
||||
mTabContainer->addTabPanel(mMsgPanel, mMsgPanel->getLabel());
|
||||
mMsgPanel->setDefaultBtn(default_btn);
|
||||
@@ -318,14 +303,6 @@ void LLPreferenceCore::apply()
|
||||
mPrefsAscentVan->apply();
|
||||
|
||||
mWebPanel->apply();
|
||||
#if LL_LCD_COMPILE
|
||||
// only add this option if we actually have a logitech keyboard / speaker set
|
||||
if (gLcdScreen->Enabled())
|
||||
{
|
||||
mLCDPanel->apply();
|
||||
}
|
||||
#endif
|
||||
// mWebPanel->apply();
|
||||
}
|
||||
|
||||
|
||||
@@ -347,14 +324,6 @@ void LLPreferenceCore::cancel()
|
||||
mPrefsAscentVan->cancel();
|
||||
|
||||
mWebPanel->cancel();
|
||||
#if LL_LCD_COMPILE
|
||||
// only add this option if we actually have a logitech keyboard / speaker set
|
||||
if (gLcdScreen->Enabled())
|
||||
{
|
||||
mLCDPanel->cancel();
|
||||
}
|
||||
#endif
|
||||
// mWebPanel->cancel();
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
237
indra/newview/llfloaterregiondebugconsole.cpp
Normal file
237
indra/newview/llfloaterregiondebugconsole.cpp
Normal file
@@ -0,0 +1,237 @@
|
||||
/**
|
||||
* @file llfloaterregiondebugconsole.h
|
||||
* @author Brad Kittenbrink <brad@lindenlab.com>
|
||||
* @brief Quick and dirty console for region debug settings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloaterregiondebugconsole.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "llhttpnode.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "lltexteditor.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
// Two versions of the sim console API are supported.
|
||||
//
|
||||
// SimConsole capability (deprecated):
|
||||
// This is the initial implementation that is supported by some versions of the
|
||||
// simulator. It is simple and straight forward, just POST a command and the
|
||||
// body of the response has the result. This API is deprecated because it
|
||||
// doesn't allow the sim to use any asynchronous API.
|
||||
//
|
||||
// SimConsoleAsync capability:
|
||||
// This capability replaces the original SimConsole capability. It is similar
|
||||
// in that the command is POSTed to the SimConsoleAsync cap, but the response
|
||||
// comes in through the event poll, which gives the simulator more flexibility
|
||||
// and allows it to perform complex operations without blocking any frames.
|
||||
//
|
||||
// We will assume the SimConsoleAsync capability is available, and fall back to
|
||||
// the SimConsole cap if it is not. The simulator will only support one or the
|
||||
// other.
|
||||
|
||||
namespace
|
||||
{
|
||||
// Signal used to notify the floater of responses from the asynchronous
|
||||
// API.
|
||||
console_reply_signal_t sConsoleReplySignal;
|
||||
|
||||
const std::string PROMPT("\n\n> ");
|
||||
const std::string UNABLE_TO_SEND_COMMAND(
|
||||
"ERROR: The last command was not received by the server.");
|
||||
const std::string CONSOLE_UNAVAILABLE(
|
||||
"ERROR: No console available for this region/simulator.");
|
||||
const std::string CONSOLE_NOT_SUPPORTED(
|
||||
"This region does not support the simulator console.");
|
||||
|
||||
// This responder handles the initial response. Unless error() is called
|
||||
// we assume that the simulator has received our request. Error will be
|
||||
// called if this request times out.
|
||||
class AsyncConsoleResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
/* virtual */
|
||||
void error(U32 status, const std::string& reason)
|
||||
{
|
||||
sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
|
||||
}
|
||||
};
|
||||
|
||||
class ConsoleResponder : public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
ConsoleResponder(LLTextEditor *output) : mOutput(output)
|
||||
{
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void error(U32 status, const std::string& reason)
|
||||
{
|
||||
if (mOutput)
|
||||
{
|
||||
mOutput->appendText(
|
||||
UNABLE_TO_SEND_COMMAND + PROMPT,
|
||||
false, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void result(const LLSD& content)
|
||||
{
|
||||
if (mOutput)
|
||||
{
|
||||
mOutput->appendText(
|
||||
content.asString() + PROMPT, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
LLTextEditor * mOutput;
|
||||
};
|
||||
|
||||
// This handles responses for console commands sent via the asynchronous
|
||||
// API.
|
||||
class ConsoleResponseNode : public LLHTTPNode
|
||||
{
|
||||
public:
|
||||
/* virtual */
|
||||
void post(
|
||||
LLHTTPNode::ResponsePtr reponse,
|
||||
const LLSD& context,
|
||||
const LLSD& input) const
|
||||
{
|
||||
llinfos << "Received response from the debug console: "
|
||||
<< input << llendl;
|
||||
sConsoleReplySignal(input["body"].asString());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
boost::signals2::connection LLFloaterRegionDebugConsole::setConsoleReplyCallback(const console_reply_signal_t::slot_type& cb)
|
||||
{
|
||||
return sConsoleReplySignal.connect(cb);
|
||||
}
|
||||
|
||||
LLFloaterRegionDebugConsole::LLFloaterRegionDebugConsole()
|
||||
: LLFloater(), mOutput(NULL)
|
||||
{
|
||||
mReplySignalConnection = sConsoleReplySignal.connect(
|
||||
boost::bind(
|
||||
&LLFloaterRegionDebugConsole::onReplyReceived,
|
||||
this,
|
||||
_1));
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_region_debug_console.xml");
|
||||
}
|
||||
|
||||
LLFloaterRegionDebugConsole::~LLFloaterRegionDebugConsole()
|
||||
{
|
||||
mReplySignalConnection.disconnect();
|
||||
}
|
||||
|
||||
BOOL LLFloaterRegionDebugConsole::postBuild()
|
||||
{
|
||||
LLLineEditor* input = getChild<LLLineEditor>("region_debug_console_input");
|
||||
input->setEnableLineHistory(true);
|
||||
input->setCommitCallback(boost::bind(&LLFloaterRegionDebugConsole::onInput, this, _1, _2));
|
||||
input->setFocus(true);
|
||||
input->setCommitOnFocusLost(false);
|
||||
|
||||
mOutput = getChild<LLTextEditor>("region_debug_console_output");
|
||||
|
||||
std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync");
|
||||
if (url.empty())
|
||||
{
|
||||
// Fall back to see if the old API is supported.
|
||||
url = gAgent.getRegion()->getCapability("SimConsole");
|
||||
if (url.empty())
|
||||
{
|
||||
mOutput->appendText(
|
||||
CONSOLE_NOT_SUPPORTED + PROMPT,
|
||||
false, false);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
mOutput->appendText("> ", false, false);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterRegionDebugConsole::onClose(bool app_quitting)
|
||||
{
|
||||
LLFloater::onClose(app_quitting);
|
||||
|
||||
if (!app_quitting)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param)
|
||||
{
|
||||
LLLineEditor* input = static_cast<LLLineEditor*>(ctrl);
|
||||
std::string text = input->getText() + "\n";
|
||||
|
||||
std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync");
|
||||
if (url.empty())
|
||||
{
|
||||
// Fall back to the old API
|
||||
url = gAgent.getRegion()->getCapability("SimConsole");
|
||||
if (url.empty())
|
||||
{
|
||||
text += CONSOLE_UNAVAILABLE + PROMPT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Using SimConsole (deprecated)
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
LLSD(input->getText()),
|
||||
new ConsoleResponder(mOutput));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Using SimConsoleAsync
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
LLSD(input->getText()),
|
||||
new AsyncConsoleResponder);
|
||||
}
|
||||
|
||||
mOutput->appendText(text, false, false);
|
||||
input->clear();
|
||||
}
|
||||
|
||||
void LLFloaterRegionDebugConsole::onReplyReceived(const std::string& output)
|
||||
{
|
||||
mOutput->appendText(output + PROMPT, false, false);
|
||||
}
|
||||
|
||||
LLHTTPRegistration<ConsoleResponseNode>
|
||||
gHTTPRegistrationMessageDebugConsoleResponse(
|
||||
"/message/SimConsoleResponse");
|
||||
63
indra/newview/llfloaterregiondebugconsole.h
Normal file
63
indra/newview/llfloaterregiondebugconsole.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file llfloaterregiondebugconsole.h
|
||||
* @author Brad Kittenbrink <brad@lindenlab.com>
|
||||
* @brief Quick and dirty console for region debug settings
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERREGIONDEBUGCONSOLE_H
|
||||
#define LL_LLFLOATERREGIONDEBUGCONSOLE_H
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llhttpclient.h"
|
||||
|
||||
class LLTextEditor;
|
||||
|
||||
typedef boost::signals2::signal<
|
||||
void (const std::string& output)> console_reply_signal_t;
|
||||
|
||||
class LLFloaterRegionDebugConsole : public LLFloater, public LLHTTPClient::Responder, public LLSingleton<LLFloaterRegionDebugConsole>
|
||||
{
|
||||
public:
|
||||
LLFloaterRegionDebugConsole();
|
||||
virtual ~LLFloaterRegionDebugConsole();
|
||||
|
||||
// virtual
|
||||
BOOL postBuild();
|
||||
void onClose(bool app_quitting);
|
||||
|
||||
void onInput(LLUICtrl* ctrl, const LLSD& param);
|
||||
|
||||
LLTextEditor * mOutput;
|
||||
|
||||
static boost::signals2::connection setConsoleReplyCallback(const console_reply_signal_t::slot_type& cb);
|
||||
|
||||
private:
|
||||
void onReplyReceived(const std::string& output);
|
||||
|
||||
boost::signals2::connection mReplySignalConnection;
|
||||
};
|
||||
|
||||
#endif // LL_LLFLOATERREGIONDEBUGCONSOLE_H
|
||||
@@ -110,9 +110,6 @@ void click_popup_minimize(void*);
|
||||
void click_popup_grab_drag(LLUICtrl *, void*);
|
||||
void click_popup_grab_lift(LLUICtrl *, void*);
|
||||
void click_popup_grab_spin(LLUICtrl *, void*);
|
||||
void click_popup_rotate_left(void*);
|
||||
void click_popup_rotate_reset(void*);
|
||||
void click_popup_rotate_right(void*);
|
||||
void click_popup_dozer_mode(LLUICtrl *, void *user);
|
||||
void commit_slider_dozer_size(LLUICtrl *, void*);
|
||||
void commit_slider_dozer_force(LLUICtrl *, void*);
|
||||
@@ -947,25 +944,6 @@ void commit_slider_zoom(LLUICtrl *ctrl, void*)
|
||||
gAgentCamera.setCameraZoomFraction(zoom_level);
|
||||
}
|
||||
|
||||
void click_popup_rotate_left(void*)
|
||||
{
|
||||
LLSelectMgr::getInstance()->selectionRotateAroundZ( 45.f );
|
||||
dialog_refresh_all();
|
||||
}
|
||||
|
||||
void click_popup_rotate_reset(void*)
|
||||
{
|
||||
LLSelectMgr::getInstance()->selectionResetRotation();
|
||||
dialog_refresh_all();
|
||||
}
|
||||
|
||||
void click_popup_rotate_right(void*)
|
||||
{
|
||||
LLSelectMgr::getInstance()->selectionRotateAroundZ( -45.f );
|
||||
dialog_refresh_all();
|
||||
}
|
||||
|
||||
|
||||
void click_popup_dozer_mode(LLUICtrl *, void *user)
|
||||
{
|
||||
S32 mode = (S32)(intptr_t) user;
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
|
||||
#include "llwaterparamset.h"
|
||||
#include "llwaterparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
|
||||
#undef max
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
|
||||
#include "llwlparamset.h"
|
||||
#include "llwlparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
|
||||
#undef max
|
||||
|
||||
|
||||
@@ -118,20 +118,20 @@ public:
|
||||
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
|
||||
virtual BOOL addFolder( LLFolderViewFolder* folder);
|
||||
|
||||
// Finds width and height of this object and it's children. Also
|
||||
// makes sure that this view and it's children are the right size.
|
||||
// Find width and height of this object and its children. Also
|
||||
// makes sure that this view and its children are the right size.
|
||||
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
|
||||
|
||||
void arrangeAll() { mArrangeGeneration++; }
|
||||
S32 getArrangeGeneration() { return mArrangeGeneration; }
|
||||
|
||||
// applies filters to control visibility of inventory items
|
||||
// Apply filters to control visibility of inventory items
|
||||
virtual void filter( LLInventoryFilter& filter);
|
||||
|
||||
// get the last selected item
|
||||
// Get the last selected item
|
||||
virtual LLFolderViewItem* getCurSelectedItem( void );
|
||||
|
||||
// Record the selected item and pass it down the hierachy.
|
||||
// Record the selected item and pass it down the hierarchy.
|
||||
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
|
||||
BOOL take_keyboard_focus);
|
||||
|
||||
@@ -141,13 +141,13 @@ public:
|
||||
// Called once a frame to update the selection if mSelectThisID has been set
|
||||
void updateSelection();
|
||||
|
||||
// This method is used to toggle the selection of an item. Walks
|
||||
// children, and keeps track of selected objects.
|
||||
// This method is used to toggle the selection of an item.
|
||||
// Walks children and keeps track of selected objects.
|
||||
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
|
||||
|
||||
virtual std::set<LLUUID> getSelectionList() const;
|
||||
|
||||
// make sure if ancestor is selected, descendents are not
|
||||
// Make sure if ancestor is selected, descendents are not
|
||||
void sanitizeSelection();
|
||||
void clearSelection();
|
||||
void addToSelectionList(LLFolderViewItem* item);
|
||||
@@ -158,21 +158,21 @@ public:
|
||||
void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
|
||||
LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
|
||||
|
||||
// deletion functionality
|
||||
// Deletion functionality
|
||||
void removeSelectedItems();
|
||||
|
||||
// open the selected item.
|
||||
// Open the selected item
|
||||
void openSelectedItems( void );
|
||||
void propertiesSelectedItems( void );
|
||||
|
||||
// change the folder type
|
||||
// Change the folder type
|
||||
void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
|
||||
|
||||
void autoOpenItem(LLFolderViewFolder* item);
|
||||
void closeAutoOpenedFolders();
|
||||
BOOL autoOpenTest(LLFolderViewFolder* item);
|
||||
|
||||
// copy & paste
|
||||
// Copy & paste
|
||||
virtual void copy();
|
||||
virtual BOOL canCopy() const;
|
||||
|
||||
@@ -185,7 +185,7 @@ public:
|
||||
virtual void doDelete();
|
||||
virtual BOOL canDoDelete() const;
|
||||
|
||||
// public rename functionality - can only start the process
|
||||
// Public rename functionality - can only start the process
|
||||
void startRenamingSelectedItem( void );
|
||||
|
||||
// These functions were used when there was only one folderview,
|
||||
|
||||
@@ -408,7 +408,7 @@ void LLHoverView::updateText()
|
||||
LLViewerObject *parent = (LLViewerObject *)object->getParent();
|
||||
|
||||
if (object &&
|
||||
(object->usePhysics() ||
|
||||
(object->flagUsePhysics() ||
|
||||
object->flagScripted() ||
|
||||
object->flagHandleTouch() || (parent && parent->flagHandleTouch()) ||
|
||||
object->flagTakesMoney() || (parent && parent->flagTakesMoney()) ||
|
||||
@@ -423,7 +423,7 @@ void LLHoverView::updateText()
|
||||
line.append(LLTrans::getString("TooltipFlagScript") + " ");
|
||||
}
|
||||
|
||||
if (object->usePhysics())
|
||||
if (object->flagUsePhysics())
|
||||
{
|
||||
line.append(LLTrans::getString("TooltipFlagPhysics") + " ");
|
||||
}
|
||||
@@ -456,7 +456,7 @@ void LLHoverView::updateText()
|
||||
line.append(LLTrans::getString("TooltipFlagTemporary") + " ");
|
||||
}
|
||||
|
||||
if (object->usePhysics() ||
|
||||
if (object->flagUsePhysics() ||
|
||||
object->flagHandleTouch() ||
|
||||
(parent && parent->flagHandleTouch()) )
|
||||
{
|
||||
|
||||
@@ -1411,6 +1411,15 @@ BOOL LLFloaterIMPanel::postBuild()
|
||||
}
|
||||
|
||||
setDefaultBtn("send_btn");
|
||||
|
||||
mActiveSpeakersPanel.connect(this,"active_speakers_panel");
|
||||
mToggleActiveSpeakersBtn.connect(this,"toggle_active_speakers_btn");
|
||||
mVolumeSlider.connect(this,"speaker_volume");
|
||||
mEndCallBtn.connect(this,"end_call_btn");
|
||||
mStartCallBtn.connect(this,"start_call_btn");
|
||||
mSendBtn.connect(this,"send_btn");
|
||||
mMuteBtn.connect(this,"mute_btn");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1466,10 +1475,10 @@ void LLFloaterIMPanel::draw()
|
||||
&& mCallBackEnabled;
|
||||
|
||||
// hide/show start call and end call buttons
|
||||
childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
|
||||
childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
|
||||
childSetEnabled("start_call_btn", enable_connect);
|
||||
childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
|
||||
mEndCallBtn->setVisible(LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
|
||||
mStartCallBtn->setVisible(LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
|
||||
mStartCallBtn->setEnabled(enable_connect);
|
||||
mSendBtn->setEnabled(!childGetValue("chat_editor").asString().empty());
|
||||
|
||||
LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
|
||||
if(!mTextIMPossible)
|
||||
@@ -1497,10 +1506,10 @@ void LLFloaterIMPanel::draw()
|
||||
// show speakers window when voice first connects
|
||||
if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
|
||||
{
|
||||
childSetVisible("active_speakers_panel", TRUE);
|
||||
mActiveSpeakersPanel->setVisible(true);
|
||||
mShowSpeakersOnConnect = FALSE;
|
||||
}
|
||||
childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
|
||||
mToggleActiveSpeakersBtn->setValue(mActiveSpeakersPanel->getVisible());
|
||||
|
||||
if (mTyping)
|
||||
{
|
||||
@@ -1531,11 +1540,11 @@ void LLFloaterIMPanel::draw()
|
||||
else
|
||||
{
|
||||
// refresh volume and mute checkbox
|
||||
childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
|
||||
childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
|
||||
mVolumeSlider->setVisible(LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
|
||||
mVolumeSlider->setValue(gVoiceClient->getUserVolume(mOtherParticipantUUID));
|
||||
|
||||
childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
|
||||
childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
|
||||
mMuteBtn->setValue(LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
|
||||
mMuteBtn->setVisible(LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
|
||||
}
|
||||
LLFloater::draw();
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ class LLInventoryItem;
|
||||
class LLInventoryCategory;
|
||||
class LLIMSpeakerMgr;
|
||||
class LLPanelActiveSpeakers;
|
||||
class LLPanel;
|
||||
class LLButton;
|
||||
|
||||
class LLVoiceChannel : public LLVoiceClientStatusObserver
|
||||
{
|
||||
@@ -385,6 +387,13 @@ private:
|
||||
boost::signals2::connection mFocusLostSignal;
|
||||
|
||||
|
||||
CachedUICtrl<LLPanel> mActiveSpeakersPanel;
|
||||
CachedUICtrl<LLButton> mToggleActiveSpeakersBtn;
|
||||
CachedUICtrl<LLUICtrl> mVolumeSlider;
|
||||
CachedUICtrl<LLButton> mEndCallBtn;
|
||||
CachedUICtrl<LLButton> mStartCallBtn;
|
||||
CachedUICtrl<LLButton> mSendBtn;
|
||||
CachedUICtrl<LLButton> mMuteBtn;
|
||||
|
||||
void disableWhileSessionStarting();
|
||||
|
||||
|
||||
@@ -484,9 +484,12 @@ BOOL LLManipRotate::handleMouseUp(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject* object = selectNode->getObject();
|
||||
LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
|
||||
|
||||
// have permission to move and object is root of selection or individually selected
|
||||
if (object->permMove() && (object->isRootEdit() || selectNode->mIndividualSelection))
|
||||
if (object->permMove() && !object->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
(object->isRootEdit() || selectNode->mIndividualSelection))
|
||||
{
|
||||
object->mUnselectedChildrenPositions.clear() ;
|
||||
}
|
||||
@@ -572,9 +575,12 @@ void LLManipRotate::drag( S32 x, S32 y )
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject* object = selectNode->getObject();
|
||||
LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
|
||||
|
||||
// have permission to move and object is root of selection or individually selected
|
||||
if (object->permMove() && (object->isRootEdit() || selectNode->mIndividualSelection))
|
||||
if (object->permMove() && !object->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
(object->isRootEdit() || selectNode->mIndividualSelection))
|
||||
{
|
||||
if (!object->isRootEdit())
|
||||
{
|
||||
@@ -626,9 +632,11 @@ void LLManipRotate::drag( S32 x, S32 y )
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject* object = selectNode->getObject();
|
||||
LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
|
||||
|
||||
// to avoid cumulative position changes we calculate the objects new position using its saved position
|
||||
if (object && object->permMove())
|
||||
if (object && object->permMove() && !object->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()))
|
||||
{
|
||||
LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
|
||||
|
||||
@@ -709,7 +717,10 @@ void LLManipRotate::drag( S32 x, S32 y )
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject*cur = selectNode->getObject();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isAvatar())
|
||||
LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
!cur->isAvatar())
|
||||
{
|
||||
selectNode->mLastRotation = cur->getRotation();
|
||||
selectNode->mLastPositionLocal = cur->getPosition();
|
||||
@@ -1876,7 +1887,10 @@ BOOL LLManipRotate::canAffectSelection()
|
||||
{
|
||||
virtual bool apply(LLViewerObject* objectp)
|
||||
{
|
||||
return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
|
||||
return objectp->permMove() && !objectp->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
(objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
}
|
||||
} func;
|
||||
can_rotate = mObjectSelection->applyToObjects(&func);
|
||||
|
||||
@@ -825,7 +825,10 @@ void LLManipScale::drag( S32 x, S32 y )
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject*cur = selectNode->getObject();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isAvatar())
|
||||
LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
!cur->isAvatar())
|
||||
{
|
||||
selectNode->mLastScale = cur->getScale();
|
||||
selectNode->mLastPositionLocal = cur->getPosition();
|
||||
@@ -972,7 +975,10 @@ void LLManipScale::dragCorner( S32 x, S32 y )
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject* cur = selectNode->getObject();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isAvatar() )
|
||||
LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
!cur->isAvatar() )
|
||||
{
|
||||
const LLVector3& scale = selectNode->mSavedScale;
|
||||
|
||||
@@ -994,7 +1000,10 @@ void LLManipScale::dragCorner( S32 x, S32 y )
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject* cur = selectNode->getObject();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isAvatar() && cur->isRootEdit() )
|
||||
LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
!cur->isAvatar() && cur->isRootEdit() )
|
||||
{
|
||||
const LLVector3& scale = selectNode->mSavedScale;
|
||||
cur->setScale( scale_factor * scale );
|
||||
@@ -1042,7 +1051,10 @@ void LLManipScale::dragCorner( S32 x, S32 y )
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject*cur = selectNode->getObject();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isAvatar() && !cur->isRootEdit() )
|
||||
LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
!cur->isAvatar() && !cur->isRootEdit() )
|
||||
{
|
||||
const LLVector3& scale = selectNode->mSavedScale;
|
||||
cur->setScale( scale_factor * scale, FALSE );
|
||||
@@ -1250,7 +1262,10 @@ void LLManipScale::stretchFace( const LLVector3& drag_start_agent, const LLVecto
|
||||
{
|
||||
LLSelectNode* selectNode = *iter;
|
||||
LLViewerObject*cur = selectNode->getObject();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isAvatar() )
|
||||
LLViewerObject *root_object = (cur == NULL) ? NULL : cur->getRootEdit();
|
||||
if( cur->permModify() && cur->permMove() && !cur->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
!cur->isAvatar() )
|
||||
{
|
||||
LLBBox cur_bbox = cur->getBoundingBoxAgent();
|
||||
LLVector3 start_local = cur_bbox.agentToLocal( drag_start_agent );
|
||||
@@ -2057,7 +2072,10 @@ BOOL LLManipScale::canAffectSelection()
|
||||
{
|
||||
virtual bool apply(LLViewerObject* objectp)
|
||||
{
|
||||
return objectp->permModify() && objectp->permMove() && !objectp->isSeat();
|
||||
LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
|
||||
return objectp->permModify() && objectp->permMove() && !objectp->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
!objectp->isSeat();
|
||||
}
|
||||
} func;
|
||||
can_scale = mObjectSelection->applyToObjects(&func);
|
||||
|
||||
@@ -705,7 +705,9 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
|
||||
}
|
||||
}
|
||||
|
||||
if (object->permMove())
|
||||
LLViewerObject* root_object = (object == NULL) ? NULL : object->getRootEdit();
|
||||
if (object->permMove() && !object->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()))
|
||||
{
|
||||
// handle attachments in local space
|
||||
if (object->isAttachment() && object->mDrawable.notNull())
|
||||
@@ -2328,7 +2330,10 @@ BOOL LLManipTranslate::canAffectSelection()
|
||||
{
|
||||
virtual bool apply(LLViewerObject* objectp)
|
||||
{
|
||||
return objectp->permMove() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
LLViewerObject *root_object = (objectp == NULL) ? NULL : objectp->getRootEdit();
|
||||
return objectp->permMove() && !objectp->isPermanentEnforced() &&
|
||||
((root_object == NULL) || !root_object->isPermanentEnforced()) &&
|
||||
(objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
}
|
||||
} func;
|
||||
can_move = mObjectSelection->applyToObjects(&func);
|
||||
|
||||
@@ -170,7 +170,7 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
|
||||
|
||||
if (mMediaSource)
|
||||
{
|
||||
mMediaSource->mouseMove(x, y);
|
||||
mMediaSource->mouseMove(x, y, mask);
|
||||
|
||||
gViewerWindow->setCursor(mLastSetCursor);
|
||||
}
|
||||
@@ -198,7 +198,7 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
|
||||
|
||||
if (mMediaSource)
|
||||
{
|
||||
mMediaSource->mouseUp(x, y);
|
||||
mMediaSource->mouseUp(x, y, mask);
|
||||
|
||||
/*// *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup,
|
||||
// in addition to the onFocusReceived() call below. Undo this. JC
|
||||
@@ -222,7 +222,7 @@ BOOL LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
|
||||
convertInputCoords(x, y);
|
||||
|
||||
if (mMediaSource)
|
||||
mMediaSource->mouseDown(x, y);
|
||||
mMediaSource->mouseDown(x, y, mask);
|
||||
|
||||
gFocusMgr.setMouseCapture( this );
|
||||
|
||||
@@ -265,11 +265,11 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
|
||||
{
|
||||
if (LLUICtrl::handleRightMouseDown(x, y, mask)) return TRUE;
|
||||
|
||||
/*S32 media_x = x, media_y = y;
|
||||
S32 media_x = x, media_y = y;
|
||||
convertInputCoords(media_x, media_y);
|
||||
|
||||
if (mMediaSource)
|
||||
mMediaSource->mouseDown(media_x, media_y);
|
||||
mMediaSource->mouseDown(media_x, media_y, mask, 1);
|
||||
|
||||
gFocusMgr.setMouseCapture( this );
|
||||
|
||||
@@ -277,7 +277,7 @@ BOOL LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
|
||||
{
|
||||
setFocus( TRUE );
|
||||
}
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ BOOL LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask )
|
||||
convertInputCoords(x, y);
|
||||
|
||||
if (mMediaSource)
|
||||
mMediaSource->mouseLeftDoubleClick( x, y);
|
||||
mMediaSource->mouseDoubleClick( x, y, mask);
|
||||
|
||||
gFocusMgr.setMouseCapture( this );
|
||||
|
||||
@@ -916,20 +916,16 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
|
||||
|
||||
case MEDIA_EVENT_NAVIGATE_BEGIN:
|
||||
{
|
||||
LL_INFOS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
|
||||
if(mMediaSource && mHideLoading)
|
||||
{
|
||||
mMediaSource->suspendUpdates(true);
|
||||
}
|
||||
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
|
||||
};
|
||||
break;
|
||||
|
||||
case MEDIA_EVENT_NAVIGATE_COMPLETE:
|
||||
{
|
||||
LL_INFOS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL;
|
||||
if(mMediaSource && mHideLoading)
|
||||
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL;
|
||||
if(mHidingInitialLoad)
|
||||
{
|
||||
mMediaSource->suspendUpdates(false);
|
||||
mHidingInitialLoad = false;
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
@@ -177,6 +177,7 @@ class LLMediaCtrl :
|
||||
bool mStretchToFill;
|
||||
bool mMaintainAspectRatio;
|
||||
bool mHideLoading;
|
||||
bool mHidingInitialLoad;
|
||||
bool mDecoupleTextureSize;
|
||||
S32 mTextureWidth;
|
||||
S32 mTextureHeight;
|
||||
|
||||
@@ -89,6 +89,16 @@ BOOL LLMediaRemoteCtrl::postBuild()
|
||||
childSetAction("media_pause",LLOverlayBar::toggleMediaPlay,this);
|
||||
childSetAction("music_pause",LLOverlayBar::toggleMusicPlay,this);
|
||||
|
||||
mMusicPlayBtn.connect(this,"music_play");
|
||||
mMusicStopBtn.connect(this,"music_stop");
|
||||
mMusicPauseBtn.connect(this,"music_pause");
|
||||
mMediaPlayBtn.connect(this,"media_play");
|
||||
mMediaStopBtn.connect(this,"media_stop");
|
||||
mMediaPauseBtn.connect(this,"media_pause");
|
||||
mMediaIcon.connect(this,"media_icon");
|
||||
mMusicIcon.connect(this,"music_icon");
|
||||
mExpandBtn.connect(this,"expand");
|
||||
|
||||
childSetAction("expand", onClickExpandBtn, this);
|
||||
|
||||
LLButton *pause = getChild<LLButton>("music_pause");
|
||||
@@ -101,7 +111,7 @@ void LLMediaRemoteCtrl::draw()
|
||||
{
|
||||
enableMediaButtons();
|
||||
|
||||
LLButton* expand_button = getChild<LLButton>("expand");
|
||||
LLButton* expand_button = mExpandBtn;
|
||||
if (expand_button)
|
||||
{
|
||||
if (expand_button->getToggleState())
|
||||
@@ -147,8 +157,8 @@ void LLMediaRemoteCtrl::setToolTip(const std::string& msg)
|
||||
std::string tool_tip = LLMIMETypes::findToolTip(mime_type);
|
||||
std::string play_tip = LLMIMETypes::findPlayTip(mime_type);
|
||||
// childSetToolTip("media_stop", mControls->getString("stop_label") + "\n" + tool_tip);
|
||||
childSetToolTip("media_icon", tool_tip);
|
||||
childSetToolTip("media_play", play_tip);
|
||||
mMediaIcon->setToolTip(tool_tip);
|
||||
mMediaIcon->setToolTip(play_tip);
|
||||
}
|
||||
|
||||
void LLMediaRemoteCtrl::enableMediaButtons()
|
||||
@@ -227,13 +237,13 @@ void LLMediaRemoteCtrl::enableMediaButtons()
|
||||
// Don't test the mime-type: this is not updated in a consistent basis. The existence of a valid gAudiop is enough guarantee.
|
||||
}
|
||||
const std::string media_icon_name = LLMIMETypes::findIcon(media_type);
|
||||
LLButton* music_play_btn = getChild<LLButton>("music_play");
|
||||
LLButton* music_stop_btn = getChild<LLButton>("music_stop");
|
||||
LLButton* music_pause_btn = getChild<LLButton>("music_pause");
|
||||
LLButton* media_play_btn = getChild<LLButton>("media_play");
|
||||
LLButton* media_stop_btn = getChild<LLButton>("media_stop");
|
||||
LLButton* media_pause_btn = getChild<LLButton>("media_pause");
|
||||
LLIconCtrl* media_icon = getChild<LLIconCtrl>("media_icon");
|
||||
LLButton* music_play_btn = mMusicPlayBtn;
|
||||
LLButton* music_stop_btn = mMusicStopBtn;
|
||||
LLButton* music_pause_btn = mMusicPauseBtn;
|
||||
LLButton* media_play_btn = mMediaPlayBtn;
|
||||
LLButton* media_stop_btn = mMediaPlayBtn;
|
||||
LLButton* media_pause_btn = mMediaPauseBtn;
|
||||
LLIconCtrl* media_icon = mMediaIcon;
|
||||
|
||||
music_play_btn->setEnabled(play_music_enabled);
|
||||
music_stop_btn->setEnabled(stop_music_enabled);
|
||||
@@ -262,7 +272,7 @@ void LLMediaRemoteCtrl::enableMediaButtons()
|
||||
music_pause_btn->setToolTip(mCachedPauseTip);
|
||||
}
|
||||
|
||||
childSetColor("music_icon", music_icon_color);
|
||||
mMusicIcon->setColor(music_icon_color);
|
||||
if(!media_icon_name.empty())
|
||||
{
|
||||
media_icon->setImage(media_icon_name);
|
||||
@@ -273,7 +283,7 @@ void LLMediaRemoteCtrl::enableMediaButtons()
|
||||
media_pause_btn->setEnabled(media_show_pause);
|
||||
media_pause_btn->setVisible(media_show_pause);
|
||||
media_play_btn->setVisible(! media_show_pause);
|
||||
childSetColor("media_icon", media_icon_color);
|
||||
mMediaIcon->setColor(media_icon_color);
|
||||
|
||||
setToolTip(media_url);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLButton;
|
||||
class LLIconCtrl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@@ -61,6 +62,16 @@ protected:
|
||||
void build();
|
||||
|
||||
std::string mCachedPauseTip;
|
||||
|
||||
CachedUICtrl<LLButton> mMusicPlayBtn;
|
||||
CachedUICtrl<LLButton> mMusicStopBtn;
|
||||
CachedUICtrl<LLButton> mMusicPauseBtn;
|
||||
CachedUICtrl<LLButton> mMediaPlayBtn;
|
||||
CachedUICtrl<LLButton> mMediaStopBtn;
|
||||
CachedUICtrl<LLButton> mMediaPauseBtn;
|
||||
CachedUICtrl<LLButton> mExpandBtn;
|
||||
CachedUICtrl<LLIconCtrl> mMediaIcon;
|
||||
CachedUICtrl<LLIconCtrl> mMusicIcon;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
@@ -189,7 +191,16 @@ BOOL LLOverlayBar::postBuild()
|
||||
setFocusRoot(TRUE);
|
||||
mBuilt = true;
|
||||
|
||||
mOriginalIMLabel = getChild<LLButton>("New IM")->getLabelSelected();
|
||||
mChatbarAndButtons.connect(this,"chatbar_and_buttons");
|
||||
mNewIM.connect(this,"New IM");
|
||||
mNotBusy.connect(this,"Set Not Busy");
|
||||
mMouseLook.connect(this,"Mouselook");
|
||||
mStandUp.connect(this,"Stand Up");
|
||||
mFlyCam.connect(this,"Flycam");
|
||||
mChatBar.connect(this,"chat_bar");
|
||||
mVoiceRemoteContainer.connect(this,"voice_remote_container");
|
||||
|
||||
mOriginalIMLabel = mNewIM->getLabelSelected();
|
||||
|
||||
layoutButtons();
|
||||
|
||||
@@ -203,6 +214,7 @@ BOOL LLOverlayBar::postBuild()
|
||||
childSetVisible("AdvSettings_container_exp", sAdvSettingsPopup);
|
||||
childSetVisible("ao_remote_container", gSavedSettings.getBOOL("EnableAORemote"));
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -214,6 +226,12 @@ LLOverlayBar::~LLOverlayBar()
|
||||
// virtual
|
||||
void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
S32 delta_width = width - getRect().getWidth();
|
||||
S32 delta_height = height - getRect().getHeight();
|
||||
|
||||
if (!delta_width && !delta_height && !sForceReshape)
|
||||
return;
|
||||
|
||||
LLView::reshape(width, height, called_from_parent);
|
||||
|
||||
if (mBuilt)
|
||||
@@ -224,53 +242,60 @@ void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
|
||||
void LLOverlayBar::layoutButtons()
|
||||
{
|
||||
LLView* state_buttons_panel = getChildView("state_buttons");
|
||||
LLView* state_buttons_panel = getChildView("state_management_buttons_container");
|
||||
|
||||
if (state_buttons_panel->getVisible())
|
||||
{
|
||||
LLViewQuery query;
|
||||
LLWidgetTypeFilter<LLButton> widget_filter;
|
||||
query.addPreFilter(LLEnabledFilter::getInstance());
|
||||
query.addPreFilter(&widget_filter);
|
||||
U32 required_width=0;
|
||||
const child_list_t& view_list = *(state_buttons_panel->getChildList());
|
||||
BOOST_FOREACH(LLView* viewp, view_list)
|
||||
{
|
||||
required_width+=viewp->getRect().getWidth();
|
||||
}
|
||||
|
||||
child_list_t button_list = query(state_buttons_panel);
|
||||
const S32 MAX_BAR_WIDTH = 800;
|
||||
//const S32 MAX_BUTTON_WIDTH = 150;
|
||||
|
||||
const S32 MAX_BAR_WIDTH = 600;
|
||||
S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH);
|
||||
|
||||
// calculate button widths
|
||||
const S32 MAX_BUTTON_WIDTH = 150;
|
||||
S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH);
|
||||
S32 btn_width = segment_width - gSavedSettings.getS32("StatusBarPad");
|
||||
static LLCachedControl<S32> status_bar_pad("StatusBarPad",10);
|
||||
S32 usable_bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH) - (view_list.size()-1) * status_bar_pad;
|
||||
F32 element_scale = (F32)usable_bar_width / (F32)required_width;
|
||||
|
||||
// Evenly space all buttons, starting from left
|
||||
S32 left = 0;
|
||||
S32 bottom = 1;
|
||||
|
||||
for (child_list_reverse_iter_t child_iter = button_list.rbegin();
|
||||
child_iter != button_list.rend(); ++child_iter)
|
||||
BOOST_REVERSE_FOREACH(LLView* viewp, view_list)
|
||||
{
|
||||
LLView *view = *child_iter;
|
||||
LLRect r = view->getRect();
|
||||
r.setOriginAndSize(left, bottom, btn_width, r.getHeight());
|
||||
view->setRect(r);
|
||||
left += segment_width;
|
||||
LLRect r = viewp->getRect();
|
||||
S32 new_width = r.getWidth() * element_scale;
|
||||
//if(dynamic_cast<LLButton*>(viewp))
|
||||
// new_width = llclamp(new_width,0,MAX_BUTTON_WIDTH);
|
||||
r.setOriginAndSize(left, bottom, new_width, r.getHeight());
|
||||
viewp->setShape(r,false);
|
||||
left += viewp->getRect().getWidth() + status_bar_pad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLButton* LLOverlayBar::updateButtonVisiblity(LLButton* button, bool visible)
|
||||
{
|
||||
if (button && (bool)button->getVisible() != visible)
|
||||
{
|
||||
button->setVisible(visible);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
// Per-frame updates of visibility
|
||||
void LLOverlayBar::refresh()
|
||||
{
|
||||
BOOL buttons_changed = FALSE;
|
||||
bool buttons_changed = FALSE;
|
||||
|
||||
BOOL im_received = gIMMgr->getIMReceived();
|
||||
int unread_count = gIMMgr->getIMUnreadCount();
|
||||
LLButton* button = getChild<LLButton>("New IM");
|
||||
|
||||
if ((button && button->getVisible() != im_received) ||
|
||||
(button && button->getVisible()))
|
||||
if(LLButton* button = updateButtonVisiblity(mNewIM,gIMMgr->getIMReceived()))
|
||||
{
|
||||
int unread_count = gIMMgr->getIMUnreadCount();
|
||||
if (unread_count > 0)
|
||||
{
|
||||
if (unread_count > 1)
|
||||
@@ -284,86 +309,16 @@ void LLOverlayBar::refresh()
|
||||
button->setLabel("1 " + mOriginalIMLabel);
|
||||
}
|
||||
}
|
||||
button->setVisible(im_received);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
buttons_changed = true;
|
||||
}
|
||||
|
||||
BOOL busy = gAgent.getBusy();
|
||||
button = getChild<LLButton>("Set Not Busy");
|
||||
if (button && button->getVisible() != busy)
|
||||
{
|
||||
button->setVisible(busy);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL flycam = LLViewerJoystick::getInstance()->getOverrideCamera();
|
||||
button = getChild<LLButton>("Flycam");
|
||||
if (button && button->getVisible() != flycam)
|
||||
{
|
||||
button->setVisible(flycam);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL mouselook_grabbed;
|
||||
mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX)
|
||||
|| gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX);
|
||||
button = getChild<LLButton>("Mouselook");
|
||||
|
||||
if (button && button->getVisible() != mouselook_grabbed)
|
||||
{
|
||||
button->setVisible(mouselook_grabbed);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL sitting = FALSE;
|
||||
if (gAgentAvatarp)
|
||||
{
|
||||
// sitting = gAgentAvatarp->isSitting();
|
||||
buttons_changed |= updateButtonVisiblity(mNotBusy,gAgent.getBusy()) != NULL;
|
||||
buttons_changed |= updateButtonVisiblity(mFlyCam,LLViewerJoystick::getInstance()->getOverrideCamera()) != NULL;
|
||||
buttons_changed |= updateButtonVisiblity(mMouseLook,gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX)||gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX)) != NULL;
|
||||
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
|
||||
sitting = gAgentAvatarp->isSitting() && !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT);
|
||||
// buttons_changed |= updateButtonVisiblity("Stand Up", isAgentAvatarValid() && gAgentAvatarp->isSitting()) != NULL;
|
||||
buttons_changed |= updateButtonVisiblity(mStandUp,isAgentAvatarValid() && gAgentAvatarp->isSitting() && !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) != NULL;
|
||||
// [/RLVa:KB]
|
||||
}
|
||||
button = getChild<LLButton>("Stand Up");
|
||||
|
||||
if (button && button->getVisible() != sitting)
|
||||
{
|
||||
button->setVisible(sitting);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
|
||||
BOOL teleporting = FALSE;
|
||||
if ((gAgent.getTeleportState() == LLAgent::TELEPORT_START) ||
|
||||
(gAgent.getTeleportState() == LLAgent::TELEPORT_REQUESTED) ||
|
||||
(gAgent.getTeleportState() == LLAgent::TELEPORT_MOVING) ||
|
||||
(gAgent.getTeleportState() == LLAgent::TELEPORT_START))
|
||||
{
|
||||
teleporting = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
teleporting = FALSE;
|
||||
}
|
||||
|
||||
|
||||
button = getChild<LLButton>("Cancel TP");
|
||||
|
||||
if (button && button->getVisible() != teleporting)
|
||||
{
|
||||
button->setVisible(teleporting);
|
||||
sendChildToFront(button);
|
||||
moveChildToBackOfTabGroup(button);
|
||||
buttons_changed = TRUE;
|
||||
}
|
||||
buttons_changed |= updateButtonVisiblity(mCancelBtn,(gAgent.getTeleportState() >= LLAgent::TELEPORT_START) && (gAgent.getTeleportState() <= LLAgent::TELEPORT_MOVING)) != NULL;
|
||||
|
||||
moveChildToBackOfTabGroup(mAORemote);
|
||||
moveChildToBackOfTabGroup(mMediaRemote);
|
||||
@@ -384,7 +339,7 @@ void LLOverlayBar::refresh()
|
||||
childSetVisible("AdvSettings_container", FALSE);
|
||||
childSetVisible("AdvSettings_container_exp", FALSE);
|
||||
childSetVisible("ao_remote_container", FALSE);
|
||||
childSetVisible("state_buttons", FALSE);
|
||||
childSetVisible("state_management_buttons_container", FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -394,15 +349,15 @@ void LLOverlayBar::refresh()
|
||||
childSetVisible("AdvSettings_container", !sAdvSettingsPopup);//!gSavedSettings.getBOOL("wlfAdvSettingsPopup"));
|
||||
childSetVisible("AdvSettings_container_exp", sAdvSettingsPopup);//gSavedSettings.getBOOL("wlfAdvSettingsPopup"));
|
||||
childSetVisible("ao_remote_container", gSavedSettings.getBOOL("EnableAORemote"));
|
||||
childSetVisible("state_buttons", TRUE);
|
||||
childSetVisible("state_management_buttons_container", TRUE);
|
||||
}
|
||||
}
|
||||
if(!in_mouselook)
|
||||
childSetVisible("voice_remote_container", LLVoiceClient::voiceEnabled());
|
||||
mVoiceRemoteContainer->setVisible(LLVoiceClient::voiceEnabled());
|
||||
|
||||
// always let user toggle into and out of chatbar
|
||||
static const LLCachedControl<bool> chat_visible("ChatVisible",true);
|
||||
childSetVisible("chat_bar", chat_visible);
|
||||
mChatBar->setVisible(chat_visible);
|
||||
|
||||
if (buttons_changed)
|
||||
{
|
||||
|
||||
@@ -52,6 +52,7 @@ class LLSlider;
|
||||
class LLVoiceRemoteCtrl;
|
||||
class wlfPanel_AdvSettings;
|
||||
class AORemoteCtrl;
|
||||
class LLChatBar;
|
||||
|
||||
class LLOverlayBar
|
||||
: public LLPanel
|
||||
@@ -64,10 +65,14 @@ public:
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ BOOL postBuild();
|
||||
|
||||
LLButton* updateButtonVisiblity(LLButton* button, bool visible);
|
||||
|
||||
void layoutButtons();
|
||||
|
||||
// helpers for returning desired state
|
||||
BOOL musicPlaying() { return mMusicState == PLAYING; }
|
||||
|
||||
LLView* getChatbarAndButtons() const {return mChatbarAndButtons;}
|
||||
|
||||
static void onClickIMReceived(void* data);
|
||||
static void onClickSetNotBusy(void* data);
|
||||
@@ -114,7 +119,14 @@ protected:
|
||||
S32 mMusicState;
|
||||
std::string mOriginalIMLabel;
|
||||
|
||||
|
||||
CachedUICtrl<LLView> mChatbarAndButtons;
|
||||
CachedUICtrl<LLButton> mNewIM;
|
||||
CachedUICtrl<LLButton> mNotBusy;
|
||||
CachedUICtrl<LLButton> mMouseLook;
|
||||
CachedUICtrl<LLButton> mStandUp;
|
||||
CachedUICtrl<LLButton> mFlyCam;
|
||||
CachedUICtrl<LLChatBar> mChatBar;
|
||||
CachedUICtrl<LLPanel> mVoiceRemoteContainer;
|
||||
private:
|
||||
|
||||
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/**
|
||||
* @file llpanellcd.cpp
|
||||
* @brief lcd options panel
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelLCD.h"
|
||||
|
||||
// linden library includes
|
||||
#include "llerror.h"
|
||||
#include "llrect.h"
|
||||
#include "llfontgl.h"
|
||||
#include "message.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
// project includes
|
||||
#include "llviewerwindow.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llradiogroup.h"
|
||||
#include "llresmgr.h"
|
||||
#include "lltextbox.h"
|
||||
#include "llui.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
//Ventrella
|
||||
#include "llagent.h"
|
||||
//end Ventrella
|
||||
|
||||
// for Logitech LCD keyboards / speakers
|
||||
#ifndef LL_LCD_H
|
||||
#include "lllcd.h"
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
//
|
||||
// Static functions
|
||||
//
|
||||
|
||||
|
||||
LLPanelLCD::LLPanelLCD()
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_lcd.xml");
|
||||
}
|
||||
|
||||
BOOL LLPanelLCD::postBuild()
|
||||
{
|
||||
requires<LLRadioGroup>("LCDDestination");
|
||||
requires<LLCheckBoxCtrl>("DisplayLinden");
|
||||
requires<LLCheckBoxCtrl>("DisplayDebug");
|
||||
requires<LLCheckBoxCtrl>("DisplayDebugConsole");
|
||||
requires<LLCheckBoxCtrl>("DisplayRegion");
|
||||
requires<LLCheckBoxCtrl>("DisplayChat");
|
||||
requires<LLCheckBoxCtrl>("DisplayIM");
|
||||
|
||||
if (!checkRequirements())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
refresh();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
LLPanelLCD::~LLPanelLCD()
|
||||
{
|
||||
// Children all cleaned up by default view destructor.
|
||||
}
|
||||
|
||||
void LLPanelLCD::refresh()
|
||||
{
|
||||
mLCDDestination = gSavedSettings.getS32("LCDDestination");
|
||||
mDisplayChat = gSavedSettings.getBOOL("DisplayChat");
|
||||
mDisplayIM = gSavedSettings.getBOOL("DisplayIM");
|
||||
mDisplayRegion = gSavedSettings.getBOOL("DisplayRegion");
|
||||
mDisplayDebug = gSavedSettings.getBOOL("DisplayDebug");
|
||||
mDisplayDebugConsole = gSavedSettings.getBOOL("DisplayDebugConsole");
|
||||
mDisplayLinden = gSavedSettings.getBOOL("DisplayLinden");
|
||||
|
||||
LLPanel::refresh();
|
||||
}
|
||||
|
||||
void LLPanelLCD::apply()
|
||||
{
|
||||
// nothing really to do here.
|
||||
}
|
||||
|
||||
|
||||
void LLPanelLCD::cancel()
|
||||
{
|
||||
// doing this to restore situation when we entered this function
|
||||
gSavedSettings.setS32("LCDDestination", mLCDDestination);
|
||||
gSavedSettings.setBOOL("DisplayChat", mDisplayChat);
|
||||
gSavedSettings.setBOOL("DisplayIM", mDisplayIM);
|
||||
gSavedSettings.setBOOL("DisplayRegion", mDisplayRegion);
|
||||
gSavedSettings.setBOOL("DisplayDebug", mDisplayDebug);
|
||||
gSavedSettings.setBOOL("DisplayDebugConsole", mDisplayDebugConsole);
|
||||
gSavedSettings.setBOOL("DisplayLinden", mDisplayLinden);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* @file llpanelLCD.h
|
||||
* @brief lcd options panel
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_PANEL_LCD_H
|
||||
#define LL_PANEL_LCD_H
|
||||
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLCheckBoxCtrl;
|
||||
|
||||
|
||||
class LLPanelLCD : public LLPanel
|
||||
{
|
||||
public:
|
||||
LLPanelLCD();
|
||||
virtual ~LLPanelLCD();
|
||||
|
||||
virtual BOOL postBuild();
|
||||
virtual void refresh();
|
||||
void apply();
|
||||
void cancel();
|
||||
|
||||
protected:
|
||||
S32 mLCDDestination;
|
||||
BOOL mDisplayChat;
|
||||
BOOL mDisplayRegion;
|
||||
BOOL mDisplayDebug;
|
||||
BOOL mDisplayDebugConsole;
|
||||
BOOL mDisplayLinden;
|
||||
BOOL mDisplayIM;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -121,7 +121,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
|
||||
|
||||
// BUG? Check for all objects being editable?
|
||||
bool editable = gAgent.isGodlike()
|
||||
|| (objectp->permModify()
|
||||
|| (objectp->permModify() && !objectp->isPermanentEnforced()
|
||||
&& ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488
|
||||
BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
|
||||
|
||||
@@ -150,6 +150,9 @@ void LLPanelContents::getState(LLViewerObject *objectp )
|
||||
all_volume &&
|
||||
((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
|
||||
|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)));
|
||||
|
||||
getChildView("button permissions")->setEnabled(!objectp->isPermanentEnforced());
|
||||
mPanelInventory->setEnabled(!objectp->isPermanentEnforced());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ void LLPanelFace::getState()
|
||||
&& objectp->getPCode() == LL_PCODE_VOLUME
|
||||
&& objectp->permModify())
|
||||
{
|
||||
BOOL editable = objectp->permModify();
|
||||
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
|
||||
|
||||
|
||||
// only turn on auto-adjust button if there is a media renderer and the media is loaded
|
||||
|
||||
@@ -394,7 +394,6 @@ LLPanelObject::LLPanelObject(const std::string& name)
|
||||
mIsPhysical(FALSE),
|
||||
mIsTemporary(FALSE),
|
||||
mIsPhantom(FALSE),
|
||||
mCastShadows(TRUE),
|
||||
mSelectedType(MI_BOX)
|
||||
{
|
||||
}
|
||||
@@ -478,10 +477,10 @@ void LLPanelObject::getState( )
|
||||
}
|
||||
|
||||
// can move or rotate only linked group with move permissions, or sub-object with move and modify perms
|
||||
BOOL enable_move = objectp->permMove() && ((!objectp->isAttachment() && objectp->permModify()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
BOOL enable_scale = objectp->permMove() && objectp->permModify();
|
||||
BOOL enable_rotate = objectp->permMove() && ((objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
BOOL enable_link = objectp->permMove() && ((!objectp->isAttachment() && objectp->permModify()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
BOOL enable_move = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && !objectp->isAttachment() && (objectp->permModify() || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
BOOL enable_scale = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && objectp->permModify();
|
||||
BOOL enable_rotate = objectp->permMove() && !objectp->isPermanentEnforced() && ((root_objectp == NULL) || !root_objectp->isPermanentEnforced()) && ( (objectp->permModify() && !objectp->isAttachment()) || !gSavedSettings.getBOOL("EditLinkedParts"));
|
||||
|
||||
childSetEnabled("build_math_constants",true);
|
||||
S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
|
||||
BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ))
|
||||
@@ -528,8 +527,8 @@ void LLPanelObject::getState( )
|
||||
mCtrlPosX->setEnabled(enable_move);
|
||||
mCtrlPosY->setEnabled(enable_move);
|
||||
mCtrlPosZ->setEnabled(enable_move);
|
||||
mBtnLinkObj->setEnabled((enable_link && !single_volume));
|
||||
mBtnUnlinkObj->setEnabled((enable_link && (selected_count > 1)));
|
||||
mBtnLinkObj->setEnabled((enable_move && !single_volume));
|
||||
mBtnUnlinkObj->setEnabled((enable_move && (selected_count > 1)));
|
||||
mBtnCopyPos->setEnabled(enable_move);
|
||||
mBtnPastePos->setEnabled(enable_move);
|
||||
mBtnPastePosClip->setEnabled(enable_move);
|
||||
@@ -624,9 +623,15 @@ void LLPanelObject::getState( )
|
||||
childSetVisible("select_single", TRUE);
|
||||
childSetEnabled("select_single", TRUE);
|
||||
}
|
||||
BOOL is_flexible = volobjp && volobjp->isFlexible();
|
||||
BOOL is_permanent = root_objectp->flagObjectPermanent();
|
||||
BOOL is_permanent_enforced = root_objectp->isPermanentEnforced();
|
||||
BOOL is_character = root_objectp->flagCharacter();
|
||||
llassert(!is_permanent || !is_character); // should never have a permanent object that is also a character
|
||||
|
||||
// Lock checkbox - only modifiable if you own the object.
|
||||
BOOL self_owned = (gAgent.getID() == owner_id);
|
||||
mCheckLock->setEnabled( roots_selected > 0 && self_owned );
|
||||
mCheckLock->setEnabled( roots_selected > 0 && self_owned && !is_permanent_enforced);
|
||||
|
||||
// More lock and debit checkbox - get the values
|
||||
BOOL valid;
|
||||
@@ -656,29 +661,27 @@ void LLPanelObject::getState( )
|
||||
}
|
||||
}
|
||||
|
||||
BOOL is_flexible = volobjp && volobjp->isFlexible();
|
||||
|
||||
// Physics checkbox
|
||||
mIsPhysical = root_objectp->usePhysics();
|
||||
mIsPhysical = root_objectp->flagUsePhysics();
|
||||
llassert(!is_permanent || !mIsPhysical); // should never have a permanent object that is also physical
|
||||
|
||||
mCheckPhysics->set( mIsPhysical );
|
||||
mCheckPhysics->setEnabled( roots_selected>0
|
||||
&& (editable || gAgent.isGodlike())
|
||||
&& !is_flexible);
|
||||
&& !is_flexible && !is_permanent);
|
||||
|
||||
mIsTemporary = root_objectp->flagTemporaryOnRez();
|
||||
llassert(!is_permanent || !mIsTemporary); // should never has a permanent object that is also temporary
|
||||
|
||||
mCheckTemporary->set( mIsTemporary );
|
||||
mCheckTemporary->setEnabled( roots_selected>0 && editable );
|
||||
mCheckTemporary->setEnabled( roots_selected>0 && editable && !is_permanent);
|
||||
|
||||
mIsPhantom = root_objectp->flagPhantom();
|
||||
BOOL is_volume_detect = root_objectp->flagVolumeDetect();
|
||||
llassert(!is_character || !mIsPhantom); // should never have a character that is also a phantom
|
||||
mCheckPhantom->set( mIsPhantom );
|
||||
mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible );
|
||||
mCheckPhantom->setEnabled( roots_selected>0 && editable && !is_flexible && !is_permanent_enforced && !is_character && !is_volume_detect);
|
||||
|
||||
#if 0 // 1.9.2
|
||||
mCastShadows = root_objectp->flagCastShadows();
|
||||
mCheckCastShadows->set( mCastShadows );
|
||||
mCheckCastShadows->setEnabled( roots_selected==1 && editable );
|
||||
#endif
|
||||
|
||||
// Update material part
|
||||
// slightly inefficient - materials are unique per object, not per TE
|
||||
U8 material_code = 0;
|
||||
@@ -731,6 +734,7 @@ void LLPanelObject::getState( )
|
||||
BOOL hole_enabled = FALSE;
|
||||
F32 scale_x=1.f, scale_y=1.f;
|
||||
BOOL isMesh = FALSE;
|
||||
|
||||
if( !objectp || !objectp->getVolume() || !editable || !single_volume)
|
||||
{
|
||||
// Clear out all geometry fields.
|
||||
@@ -759,11 +763,10 @@ void LLPanelObject::getState( )
|
||||
{
|
||||
// Only allowed to change these parameters for objects
|
||||
// that you have permissions on AND are not attachments.
|
||||
enabled = root_objectp->permModify();
|
||||
|
||||
const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
|
||||
|
||||
enabled = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
|
||||
|
||||
// Volume type
|
||||
const LLVolumeParams &volume_params = objectp->getVolume()->getParams();
|
||||
U8 path = volume_params.getPathParams().getCurveType();
|
||||
U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
|
||||
U8 profile = profile_and_hole & LL_PCODE_PROFILE_MASK;
|
||||
@@ -1525,22 +1528,6 @@ void LLPanelObject::sendIsPhantom()
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelObject::sendCastShadows()
|
||||
{
|
||||
BOOL value = mCheckCastShadows->get();
|
||||
if( mCastShadows != value )
|
||||
{
|
||||
LLSelectMgr::getInstance()->selectionUpdateCastShadows(value);
|
||||
mCastShadows = value;
|
||||
|
||||
llinfos << "update cast shadows sent" << llendl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "update cast shadows not changed" << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelObject::onCommitMaterial( LLUICtrl* ctrl, void* userdata )
|
||||
{
|
||||
@@ -2369,10 +2356,6 @@ void LLPanelObject::clearCtrls()
|
||||
mCheckTemporary ->setEnabled( FALSE );
|
||||
mCheckPhantom ->set(FALSE);
|
||||
mCheckPhantom ->setEnabled( FALSE );
|
||||
#if 0 // 1.9.2
|
||||
mCheckCastShadows->set(FALSE);
|
||||
mCheckCastShadows->setEnabled( FALSE );
|
||||
#endif
|
||||
mComboMaterial ->setEnabled( FALSE );
|
||||
mLabelMaterial ->setEnabled( FALSE );
|
||||
// Disable text labels
|
||||
@@ -2468,14 +2451,6 @@ void LLPanelObject::onCommitPhantom( LLUICtrl* ctrl, void* userdata )
|
||||
self->sendIsPhantom();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
|
||||
{
|
||||
LLPanelObject* self = (LLPanelObject*) userdata;
|
||||
self->sendCastShadows();
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLPanelObject::onSelectSculpt(LLUICtrl* ctrl, void* userdata)
|
||||
{
|
||||
|
||||
@@ -72,7 +72,6 @@ public:
|
||||
static void onCommitPhysics( LLUICtrl* ctrl, void* userdata);
|
||||
static void onCommitTemporary( LLUICtrl* ctrl, void* userdata);
|
||||
static void onCommitPhantom( LLUICtrl* ctrl, void* userdata);
|
||||
static void onCommitCastShadows( LLUICtrl* ctrl, void* userdata);
|
||||
|
||||
static void onLinkObj( void* user_data);
|
||||
static void onUnlinkObj( void* user_data);
|
||||
@@ -110,7 +109,6 @@ protected:
|
||||
void sendIsPhysical();
|
||||
void sendIsTemporary();
|
||||
void sendIsPhantom();
|
||||
void sendCastShadows();
|
||||
void sendSculpt();
|
||||
|
||||
void getVolumeParams(LLVolumeParams& volume_params);
|
||||
@@ -207,7 +205,6 @@ protected:
|
||||
LLCheckBoxCtrl *mCheckPhysics;
|
||||
LLCheckBoxCtrl *mCheckTemporary;
|
||||
LLCheckBoxCtrl *mCheckPhantom;
|
||||
LLCheckBoxCtrl *mCheckCastShadows;
|
||||
|
||||
LLTextureCtrl *mCtrlSculptTexture;
|
||||
LLTextBox *mLabelSculptType;
|
||||
@@ -222,7 +219,6 @@ protected:
|
||||
BOOL mIsPhysical; // to avoid sending "physical" when not changed
|
||||
BOOL mIsTemporary; // to avoid sending "temporary" when not changed
|
||||
BOOL mIsPhantom; // to avoid sending "phantom" when not changed
|
||||
BOOL mCastShadows; // to avoid sending "cast shadows" when not changed
|
||||
S32 mSelectedType; // So we know what selected type we last were
|
||||
|
||||
LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel
|
||||
|
||||
281
indra/newview/llpanelpathfindingrebakenavmesh.cpp
Normal file
281
indra/newview/llpanelpathfindingrebakenavmesh.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
/**
|
||||
* @file llpanelpathfindingrebakenavmesh.cpp
|
||||
* @brief Implementation of llpanelpathfindingrebakenavmesh
|
||||
* @author Prep@lindenlab.com
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2012, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llpanelpathfindingrebakenavmesh.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llbutton.h"
|
||||
#include "llenvmanager.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanel.h"
|
||||
#include "llpathfindingmanager.h"
|
||||
#include "llpathfindingnavmesh.h"
|
||||
#include "llpathfindingnavmeshstatus.h"
|
||||
#include "lltoolbar.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
|
||||
LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getInstance()
|
||||
{
|
||||
static LLPanelPathfindingRebakeNavmesh* panel = getPanel();
|
||||
return panel;
|
||||
}
|
||||
|
||||
BOOL LLPanelPathfindingRebakeNavmesh::postBuild()
|
||||
{
|
||||
//Rebake button
|
||||
mNavMeshRebakeButton = getChild<LLButton>("navmesh_btn");
|
||||
llassert(mNavMeshRebakeButton != NULL);
|
||||
mNavMeshRebakeButton->setCommitCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick, this));
|
||||
//LLHints::registerHintTarget("navmesh_btn", mNavMeshRebakeButton->getHandle());
|
||||
|
||||
//Sending rebake request
|
||||
mNavMeshSendingButton = findChild<LLButton>("navmesh_btn_sending");
|
||||
llassert(mNavMeshSendingButton != NULL);
|
||||
//LLHints::registerHintTarget("navmesh_btn_sending", mNavMeshSendingButton->getHandle());
|
||||
|
||||
//rebaking...
|
||||
mNavMeshBakingButton = findChild<LLButton>("navmesh_btn_baking");
|
||||
llassert(mNavMeshBakingButton != NULL);
|
||||
//LLHints::registerHintTarget("navmesh_btn_baking", mNavMeshBakingButton->getHandle());
|
||||
|
||||
setMode(kRebakeNavMesh_Default);
|
||||
|
||||
createNavMeshStatusListenerForCurrentRegion();
|
||||
|
||||
if ( !mRegionCrossingSlot.connected() )
|
||||
{
|
||||
mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this));
|
||||
}
|
||||
|
||||
if (!mAgentStateSlot.connected())
|
||||
{
|
||||
mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleAgentState, this, _1));
|
||||
}
|
||||
LLPathfindingManager::getInstance()->requestGetAgentState();
|
||||
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::draw()
|
||||
{
|
||||
if (doDraw())
|
||||
{
|
||||
updatePosition();
|
||||
LLPanel::draw();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLPanelPathfindingRebakeNavmesh::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
|
||||
{
|
||||
gViewerWindow->unblockToolTips();
|
||||
|
||||
if (mNavMeshRebakeButton->getVisible())
|
||||
{
|
||||
msg=mNavMeshRebakeButton->getToolTip();
|
||||
//LLToolTipMgr::instance().show(mNavMeshRebakeButton->getToolTip());
|
||||
}
|
||||
else if (mNavMeshSendingButton->getVisible())
|
||||
{
|
||||
msg=mNavMeshSendingButton->getToolTip();
|
||||
//LLToolTipMgr::instance().show(mNavMeshSendingButton->getToolTip());
|
||||
}
|
||||
else if (mNavMeshBakingButton->getVisible())
|
||||
{
|
||||
msg=mNavMeshBakingButton->getToolTip();
|
||||
//LLToolTipMgr::instance().show(mNavMeshBakingButton->getToolTip());
|
||||
}
|
||||
|
||||
// Convert rect local to screen coordinates
|
||||
localPointToScreen(
|
||||
0, 0,
|
||||
&(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) );
|
||||
localPointToScreen(
|
||||
getRect().getWidth(), getRect().getHeight(),
|
||||
&(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) );
|
||||
return true;//LLPanel::handleToolTip(x, y, mask);
|
||||
}
|
||||
|
||||
LLPanelPathfindingRebakeNavmesh::LLPanelPathfindingRebakeNavmesh()
|
||||
: LLPanel(),
|
||||
mCanRebakeRegion(FALSE),
|
||||
mRebakeNavMeshMode(kRebakeNavMesh_Default),
|
||||
mNavMeshRebakeButton(NULL),
|
||||
mNavMeshSendingButton(NULL),
|
||||
mNavMeshBakingButton(NULL),
|
||||
mNavMeshSlot(),
|
||||
mRegionCrossingSlot(),
|
||||
mAgentStateSlot()
|
||||
{
|
||||
// make sure we have the only instance of this class
|
||||
static bool b = true;
|
||||
llassert_always(b);
|
||||
b=false;
|
||||
}
|
||||
|
||||
LLPanelPathfindingRebakeNavmesh::~LLPanelPathfindingRebakeNavmesh()
|
||||
{
|
||||
}
|
||||
|
||||
LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getPanel()
|
||||
{
|
||||
LLPanelPathfindingRebakeNavmesh* panel = new LLPanelPathfindingRebakeNavmesh();
|
||||
LLUICtrlFactory::getInstance()->buildPanel(panel,"panel_navmesh_rebake.xml");
|
||||
return panel;
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode)
|
||||
{
|
||||
if (pRebakeNavMeshMode == kRebakeNavMesh_Available)
|
||||
{
|
||||
LLNotificationsUtil::add("PathfindingRebakeNavmesh");
|
||||
}
|
||||
mNavMeshRebakeButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_Available);
|
||||
mNavMeshSendingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_RequestSent);
|
||||
mNavMeshBakingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_InProgress);
|
||||
mRebakeNavMeshMode = pRebakeNavMeshMode;
|
||||
}
|
||||
|
||||
LLPanelPathfindingRebakeNavmesh::ERebakeNavMeshMode LLPanelPathfindingRebakeNavmesh::getMode() const
|
||||
{
|
||||
return mRebakeNavMeshMode;
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick()
|
||||
{
|
||||
setMode(kRebakeNavMesh_RequestSent);
|
||||
LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1));
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion)
|
||||
{
|
||||
mCanRebakeRegion = pCanRebakeRegion;
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus)
|
||||
{
|
||||
if (getMode() == kRebakeNavMesh_RequestSent)
|
||||
{
|
||||
setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default);
|
||||
}
|
||||
|
||||
if (!pResponseStatus)
|
||||
{
|
||||
LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh");
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus)
|
||||
{
|
||||
ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default;
|
||||
if (pNavMeshStatus.isValid())
|
||||
{
|
||||
switch (pNavMeshStatus.getStatus())
|
||||
{
|
||||
case LLPathfindingNavMeshStatus::kPending :
|
||||
case LLPathfindingNavMeshStatus::kRepending :
|
||||
rebakeNavMeshMode = kRebakeNavMesh_Available;
|
||||
break;
|
||||
case LLPathfindingNavMeshStatus::kBuilding :
|
||||
rebakeNavMeshMode = kRebakeNavMesh_InProgress;
|
||||
break;
|
||||
case LLPathfindingNavMeshStatus::kComplete :
|
||||
rebakeNavMeshMode = kRebakeNavMesh_NotAvailable;
|
||||
break;
|
||||
default :
|
||||
rebakeNavMeshMode = kRebakeNavMesh_Default;
|
||||
llassert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setMode(rebakeNavMeshMode);
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed()
|
||||
{
|
||||
createNavMeshStatusListenerForCurrentRegion();
|
||||
mCanRebakeRegion = FALSE;
|
||||
LLPathfindingManager::getInstance()->requestGetAgentState();
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion()
|
||||
{
|
||||
if (mNavMeshSlot.connected())
|
||||
{
|
||||
mNavMeshSlot.disconnect();
|
||||
}
|
||||
|
||||
LLViewerRegion *currentRegion = gAgent.getRegion();
|
||||
if (currentRegion != NULL)
|
||||
{
|
||||
mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2));
|
||||
LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLPanelPathfindingRebakeNavmesh::doDraw() const
|
||||
{
|
||||
return (mCanRebakeRegion && (mRebakeNavMeshMode != kRebakeNavMesh_NotAvailable));
|
||||
}
|
||||
|
||||
void LLPanelPathfindingRebakeNavmesh::updatePosition()
|
||||
{
|
||||
#if 0
|
||||
S32 y_pos = 0;
|
||||
S32 bottom_tb_center = 0;
|
||||
|
||||
if (LLToolBar* toolbar_bottom = gToolBarView->getChild<LLToolBar>("toolbar_bottom"))
|
||||
{
|
||||
y_pos = toolbar_bottom->getRect().getHeight();
|
||||
bottom_tb_center = toolbar_bottom->getRect().getCenterX();
|
||||
}
|
||||
|
||||
S32 left_tb_width = 0;
|
||||
if (LLToolBar* toolbar_left = gToolBarView->getChild<LLToolBar>("toolbar_left"))
|
||||
{
|
||||
left_tb_width = toolbar_left->getRect().getWidth();
|
||||
}
|
||||
|
||||
if(LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container"))
|
||||
{
|
||||
panel_ssf_container->setOrigin(0, y_pos);
|
||||
}
|
||||
|
||||
S32 x_pos = bottom_tb_center-getRect().getWidth()/2 - left_tb_width + 113 /* width of stand/fly button *//* + 10 *//* margin */;
|
||||
|
||||
/*setOrigin( x_pos, 0);*/
|
||||
#endif
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user