Merge branch 'DRTVWR-570-maint-Q' of https://bitbucket.org/lindenlab/viewer
# Conflicts: # indra/llcommon/llsdserialize.cpp # indra/llmath/llvolume.cpp # indra/llmath/llvolume.h # indra/newview/llfloateropenobject.cpp # indra/newview/llfloateropenobject.h # indra/newview/llmaterialmgr.cpp # indra/newview/llmeshrepository.cpp # indra/newview/llmeshrepository.h # indra/newview/skins/default/xui/en/floater_openobject.xmlmaster
commit
2aceea66ff
|
|
@ -1384,6 +1384,7 @@ Sovereign Engineer
|
|||
OPEN-343
|
||||
SL-11625
|
||||
BUG-229030
|
||||
SL-14696
|
||||
SL-14705
|
||||
SL-14706
|
||||
SL-14707
|
||||
|
|
@ -1391,6 +1392,7 @@ Sovereign Engineer
|
|||
SL-14732
|
||||
SL-15096
|
||||
SL-16127
|
||||
SL-18249
|
||||
SpacedOut Frye
|
||||
VWR-34
|
||||
VWR-45
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@
|
|||
#include <iostream>
|
||||
#include "apr_base64.h"
|
||||
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
|
||||
#ifdef LL_USESYSTEMLIBS
|
||||
# include <zlib.h>
|
||||
#else
|
||||
|
|
@ -2128,8 +2131,8 @@ std::string zip_llsd(LLSD& data)
|
|||
{ //copy result into output
|
||||
if (strm.avail_out >= CHUNK)
|
||||
{
|
||||
// free(output);
|
||||
if( output )
|
||||
deflateEnd(&strm);
|
||||
if(output)
|
||||
free(output);
|
||||
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
|
||||
return std::string();
|
||||
|
|
@ -2153,8 +2156,8 @@ std::string zip_llsd(LLSD& data)
|
|||
}
|
||||
else
|
||||
{
|
||||
// free(output);
|
||||
if( output )
|
||||
deflateEnd(&strm);
|
||||
if(output)
|
||||
free(output);
|
||||
LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL;
|
||||
return std::string();
|
||||
|
|
@ -2166,8 +2169,7 @@ std::string zip_llsd(LLSD& data)
|
|||
|
||||
std::string result((char*) output, size);
|
||||
deflateEnd(&strm);
|
||||
// free(output);
|
||||
if( output )
|
||||
if(output)
|
||||
free(output);
|
||||
|
||||
return result;
|
||||
|
|
@ -2178,59 +2180,70 @@ std::string zip_llsd(LLSD& data)
|
|||
// and deserializes from that copy using LLSDSerialize
|
||||
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size)
|
||||
{
|
||||
U8* result = NULL;
|
||||
U32 cur_size = 0;
|
||||
z_stream strm;
|
||||
|
||||
const U32 CHUNK = 65536;
|
||||
|
||||
U8 *in = new(std::nothrow) U8[size];
|
||||
std::unique_ptr<U8[]> in = std::unique_ptr<U8[]>(new(std::nothrow) U8[size]);
|
||||
if (!in)
|
||||
{
|
||||
return ZR_MEM_ERROR;
|
||||
}
|
||||
is.read((char*) in, size);
|
||||
is.read((char*) in.get(), size);
|
||||
|
||||
U8 out[CHUNK];
|
||||
return unzip_llsd(data, in.get(), size);
|
||||
}
|
||||
|
||||
LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32 size)
|
||||
{
|
||||
U8* result = NULL;
|
||||
U32 cur_size = 0;
|
||||
z_stream strm;
|
||||
|
||||
constexpr U32 CHUNK = 1024 * 512;
|
||||
|
||||
static thread_local std::unique_ptr<U8[]> out;
|
||||
if (!out)
|
||||
{
|
||||
out = std::unique_ptr<U8[]>(new(std::nothrow) U8[CHUNK]);
|
||||
}
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
strm.avail_in = size;
|
||||
strm.next_in = in;
|
||||
strm.next_in = const_cast<U8*>(in);
|
||||
|
||||
S32 ret = inflateInit(&strm);
|
||||
|
||||
do
|
||||
{
|
||||
strm.avail_out = CHUNK;
|
||||
strm.next_out = out;
|
||||
strm.next_out = out.get();
|
||||
ret = inflate(&strm, Z_NO_FLUSH);
|
||||
if (ret == Z_STREAM_ERROR)
|
||||
{
|
||||
LL_DEBUGS() << "Unzip error: Z_STREAM_ERROR" << LL_ENDL; // <FS>
|
||||
inflateEnd(&strm);
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
delete [] in;
|
||||
return ZR_DATA_ERROR;
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR;
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
LL_DEBUGS() << "Unzip error: " << ret << LL_ENDL; // <FS>
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
return ZR_DATA_ERROR;
|
||||
}
|
||||
case Z_STREAM_ERROR:
|
||||
case Z_BUF_ERROR:
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
free(result);
|
||||
return ZR_BUFFER_ERROR;
|
||||
}
|
||||
|
||||
case Z_MEM_ERROR:
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
delete [] in;
|
||||
return ZR_MEM_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U32 have = CHUNK-strm.avail_out;
|
||||
|
|
@ -2243,21 +2256,18 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
|
|||
{
|
||||
free(result);
|
||||
}
|
||||
delete[] in;
|
||||
return ZR_MEM_ERROR;
|
||||
}
|
||||
result = new_result;
|
||||
memcpy(result+cur_size, out, have);
|
||||
memcpy(result+cur_size, out.get(), have);
|
||||
cur_size += have;
|
||||
|
||||
} while (ret == Z_OK);
|
||||
} while (ret == Z_OK && ret != Z_STREAM_END);
|
||||
|
||||
inflateEnd(&strm);
|
||||
delete [] in;
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
LL_DEBUGS() << "Unzip error: !Z_STREAM_END" << LL_ENDL; // <FS>
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
|
|
@ -2266,41 +2276,11 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
|
|||
|
||||
//result now points to the decompressed LLSD block
|
||||
{
|
||||
std::istringstream istr;
|
||||
// Since we are using this for meshes, data we are dealing with tend to be large.
|
||||
// So string can potentially fail to allocate, make sure this won't cause problems
|
||||
try
|
||||
{
|
||||
std::string res_str((char*)result, cur_size);
|
||||
char* result_ptr = strip_deprecated_header((char*)result, cur_size);
|
||||
|
||||
std::string deprecated_header("<? LLSD/Binary ?>");
|
||||
|
||||
if (res_str.substr(0, deprecated_header.size()) == deprecated_header)
|
||||
{
|
||||
res_str = res_str.substr(deprecated_header.size() + 1, cur_size);
|
||||
}
|
||||
cur_size = res_str.size();
|
||||
|
||||
istr.str(res_str);
|
||||
}
|
||||
#ifdef LL_WINDOWS
|
||||
catch (std::length_error)
|
||||
{
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
return ZR_SIZE_ERROR;
|
||||
}
|
||||
#endif
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
return ZR_MEM_ERROR;
|
||||
}
|
||||
|
||||
if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH))
|
||||
boost::iostreams::stream<boost::iostreams::array_source> istrm(result_ptr, cur_size);
|
||||
|
||||
if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH))
|
||||
{
|
||||
// free(result);
|
||||
if( result )
|
||||
|
|
@ -2314,41 +2294,169 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
|
|||
free(result);
|
||||
return ZR_OK;
|
||||
}
|
||||
// </FS:Beq pp Rye>
|
||||
//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* unzip_llsdNavMesh(bool& valid, unsigned int& outsize, std::istream& is, S32 size)
|
||||
{
|
||||
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
|
||||
// if (size == 0)
|
||||
// {
|
||||
// LL_WARNS() << "No data to unzip." << LL_ENDL;
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
// U8* result = NULL;
|
||||
// U32 cur_size = 0;
|
||||
// z_stream strm;
|
||||
|
||||
// const U32 CHUNK = 0x4000;
|
||||
|
||||
// U8 *in = new(std::nothrow) U8[size];
|
||||
// if (in == NULL)
|
||||
// {
|
||||
// LL_WARNS() << "Memory allocation failure." << LL_ENDL;
|
||||
// return NULL;
|
||||
// }
|
||||
// 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;
|
||||
|
||||
// valid = true; // <FS:ND/> Default is all okay.
|
||||
// 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);
|
||||
// if( result )
|
||||
// free(result);
|
||||
// delete [] in;
|
||||
// in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
|
||||
// valid = false;
|
||||
// }
|
||||
|
||||
// switch (ret)
|
||||
// {
|
||||
// case Z_NEED_DICT:
|
||||
// ret = Z_DATA_ERROR;
|
||||
// case Z_DATA_ERROR:
|
||||
// case Z_MEM_ERROR:
|
||||
// inflateEnd(&strm);
|
||||
// // free(result);
|
||||
// if( result )
|
||||
// free(result);
|
||||
// delete [] in;
|
||||
// valid = false;
|
||||
// in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
|
||||
// break;
|
||||
// }
|
||||
|
||||
// if( valid ) {// <FS:ND> in case this stream is invalid, do not pass the already freed buffer to realloc.
|
||||
|
||||
// U32 have = CHUNK-strm.avail_out;
|
||||
|
||||
// U8* new_result = (U8*) realloc(result, cur_size + have);
|
||||
// if (new_result == NULL)
|
||||
// {
|
||||
// LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size
|
||||
// << " bytes; requested " << cur_size + have
|
||||
// << " bytes; total syze: ." << size << " bytes."
|
||||
// << LL_ENDL;
|
||||
// inflateEnd(&strm);
|
||||
// if (result)
|
||||
// {
|
||||
// free(result);
|
||||
// }
|
||||
// delete[] in;
|
||||
// valid = false;
|
||||
// return NULL;
|
||||
// }
|
||||
// result = new_result;
|
||||
// memcpy(result+cur_size, out, have);
|
||||
// cur_size += have;
|
||||
|
||||
// } // </FS:ND>
|
||||
|
||||
// } while (ret == Z_OK);
|
||||
|
||||
// inflateEnd(&strm);
|
||||
// delete [] in;
|
||||
|
||||
// if (ret != Z_STREAM_END)
|
||||
// {
|
||||
// // <FS:ND> result might have been freed above. And calling free with a null pointer is not defined.
|
||||
// // free(result);
|
||||
// if( result )
|
||||
// free(result);
|
||||
// // </FS:ND>
|
||||
|
||||
// valid = false;
|
||||
// return NULL;
|
||||
// }
|
||||
|
||||
// //result now points to the decompressed LLSD block
|
||||
// {
|
||||
// outsize= cur_size;
|
||||
// valid = true;
|
||||
// }
|
||||
|
||||
// return result;
|
||||
// }
|
||||
if (size == 0)
|
||||
{
|
||||
LL_WARNS() << "No data to unzip." << LL_ENDL;
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<U8[]> in;
|
||||
try
|
||||
{
|
||||
in = std::make_unique<U8[]>(size);
|
||||
}
|
||||
catch (const std::bad_alloc&)
|
||||
{
|
||||
LL_WARNS() << "Memory allocation failure." << LL_ENDL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
is.read((char*)in.get(), size);
|
||||
return unzip_llsdNavMesh(valid, outsize, in.get(), size);
|
||||
}
|
||||
|
||||
U8* unzip_llsdNavMesh(bool& valid, unsigned int& outsize, const U8* in, S32 size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
LL_WARNS() << "No data to unzip." << LL_ENDL;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
U8* result = NULL;
|
||||
U8* result = nullptr;
|
||||
U32 cur_size = 0;
|
||||
z_stream strm;
|
||||
|
||||
|
||||
const U32 CHUNK = 0x4000;
|
||||
|
||||
U8 *in = new(std::nothrow) U8[size];
|
||||
if (in == NULL)
|
||||
{
|
||||
LL_WARNS() << "Memory allocation failure." << LL_ENDL;
|
||||
return NULL;
|
||||
}
|
||||
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;
|
||||
strm.next_in = const_cast<U8*>(in);
|
||||
|
||||
valid = true; // <FS:ND/> Default is all okay.
|
||||
S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP );
|
||||
|
||||
S32 ret = inflateInit2(&strm, windowBits | ENABLE_ZLIB_GZIP);
|
||||
do
|
||||
{
|
||||
strm.avail_out = CHUNK;
|
||||
|
|
@ -2357,36 +2465,27 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
|
|||
if (ret == Z_STREAM_ERROR)
|
||||
{
|
||||
inflateEnd(&strm);
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
delete [] in;
|
||||
in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
|
||||
valid = false;
|
||||
free(result);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case Z_NEED_DICT:
|
||||
ret = Z_DATA_ERROR;
|
||||
[[fallthrough]];
|
||||
case Z_DATA_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
inflateEnd(&strm);
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
delete [] in;
|
||||
free(result);
|
||||
valid = false;
|
||||
in = NULL; result = NULL;// <FS:ND> Or we get a double free aftr the while loop ...
|
||||
break;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( valid ) {// <FS:ND> in case this stream is invalid, do not pass the already freed buffer to realloc.
|
||||
|
||||
U32 have = CHUNK-strm.avail_out;
|
||||
U32 have = CHUNK - strm.avail_out;
|
||||
|
||||
U8* new_result = (U8*) realloc(result, cur_size + have);
|
||||
if (new_result == NULL)
|
||||
U8* new_result = (U8*)realloc(result, cur_size + have);
|
||||
if (!new_result)
|
||||
{
|
||||
LL_WARNS() << "Failed to unzip LLSD NavMesh block: can't reallocate memory, current size: " << cur_size
|
||||
<< " bytes; requested " << cur_size + have
|
||||
|
|
@ -2397,40 +2496,50 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32
|
|||
{
|
||||
free(result);
|
||||
}
|
||||
delete[] in;
|
||||
valid = false;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
result = new_result;
|
||||
memcpy(result+cur_size, out, have);
|
||||
memcpy(result + cur_size, out, have);
|
||||
cur_size += have;
|
||||
|
||||
} // </FS:ND>
|
||||
|
||||
} while (ret == Z_OK);
|
||||
|
||||
inflateEnd(&strm);
|
||||
delete [] in;
|
||||
|
||||
if (ret != Z_STREAM_END)
|
||||
{
|
||||
// <FS:ND> result might have been freed above. And calling free with a null pointer is not defined.
|
||||
// free(result);
|
||||
if( result )
|
||||
free(result);
|
||||
// </FS:ND>
|
||||
|
||||
free(result);
|
||||
valid = false;
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//result now points to the decompressed LLSD block
|
||||
{
|
||||
outsize= cur_size;
|
||||
valid = true;
|
||||
outsize = cur_size;
|
||||
valid = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
// </FS:Beq pp Rye>
|
||||
|
||||
char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size)
|
||||
{
|
||||
const char* deprecated_header = "<? LLSD/Binary ?>";
|
||||
constexpr size_t deprecated_header_size = 17;
|
||||
|
||||
if (cur_size > deprecated_header_size
|
||||
&& memcmp(in, deprecated_header, deprecated_header_size) == 0)
|
||||
{
|
||||
in = in + deprecated_header_size;
|
||||
cur_size = cur_size - deprecated_header_size;
|
||||
if (header_size)
|
||||
{
|
||||
*header_size = deprecated_header_size + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -858,9 +858,12 @@ public:
|
|||
ZR_SIZE_ERROR,
|
||||
ZR_DATA_ERROR,
|
||||
ZR_PARSE_ERROR,
|
||||
ZR_BUFFER_ERROR,
|
||||
ZR_VERSION_ERROR
|
||||
} EZipRresult;
|
||||
// return OK or reason for failure
|
||||
static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size);
|
||||
static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size);
|
||||
};
|
||||
|
||||
//dirty little zip functions -- yell at davep
|
||||
|
|
@ -868,4 +871,9 @@ LL_COMMON_API std::string zip_llsd(LLSD& data);
|
|||
|
||||
|
||||
LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size);
|
||||
// <FS:Beq pp Rye> Add non-allocating variants of unzip_llsd
|
||||
LL_COMMON_API U8* unzip_llsdNavMesh(bool& valid, unsigned int& outsize, const U8* in, S32 size);
|
||||
|
||||
// returns a pointer to the array or past the array if the deprecated header exists
|
||||
LL_COMMON_API char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size = nullptr);
|
||||
#endif // LL_LLSDSERIALIZE_H
|
||||
|
|
|
|||
|
|
@ -2411,13 +2411,12 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
|
|||
LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
// <FS:Beq pp Rye> Add non-allocating variants of of unpackVolumeFaces
|
||||
return unpackVolumeFacesInternal(mdl);
|
||||
}
|
||||
|
||||
bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)
|
||||
{
|
||||
//input stream is now pointing at a zlib compressed block of LLSD
|
||||
//input data is now pointing at a zlib compressed block of LLSD
|
||||
//decompress block
|
||||
LLSD mdl;
|
||||
U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size);
|
||||
|
|
@ -2431,7 +2430,6 @@ bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size)
|
|||
|
||||
bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
|
||||
{
|
||||
// </FS:Beq pp Rye>
|
||||
{
|
||||
U32 face_count = mdl.size();
|
||||
|
||||
|
|
|
|||
|
|
@ -1108,14 +1108,12 @@ protected:
|
|||
BOOL generate();
|
||||
void createVolumeFaces();
|
||||
public:
|
||||
virtual bool unpackVolumeFaces(std::istream& is, S32 size);
|
||||
// <FS:Beq pp Rye> Add non-allocating variants of of unpackVolumeFaces
|
||||
bool unpackVolumeFaces(std::istream& is, S32 size);
|
||||
bool unpackVolumeFaces(U8* in_data, S32 size);
|
||||
private:
|
||||
bool unpackVolumeFacesInternal(const LLSD& mdl);
|
||||
|
||||
public:
|
||||
// </FS:Beq pp Rye>
|
||||
virtual void setMeshAssetLoaded(BOOL loaded);
|
||||
virtual BOOL isMeshAssetLoaded();
|
||||
|
||||
|
|
|
|||
|
|
@ -1416,6 +1416,16 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin):
|
|||
fromLLSD(skin);
|
||||
}
|
||||
|
||||
LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) :
|
||||
mMeshID(mesh_id),
|
||||
mPelvisOffset(0.0),
|
||||
mLockScaleIfJointPosition(false),
|
||||
mInvalidJointsScrubbed(false),
|
||||
mJointNumsInitialized(false)
|
||||
{
|
||||
fromLLSD(skin);
|
||||
}
|
||||
|
||||
void LLMeshSkinInfo::fromLLSD(LLSD& skin)
|
||||
{
|
||||
if (skin.has("joint_names"))
|
||||
|
|
|
|||
|
|
@ -43,12 +43,13 @@ class domMesh;
|
|||
#define MAX_MODEL_FACES 8
|
||||
|
||||
LL_ALIGN_PREFIX(16)
|
||||
class LLMeshSkinInfo
|
||||
class LLMeshSkinInfo : public LLRefCount
|
||||
{
|
||||
LL_ALIGN_NEW
|
||||
public:
|
||||
LLMeshSkinInfo();
|
||||
LLMeshSkinInfo(LLSD& data);
|
||||
LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data);
|
||||
void fromLLSD(LLSD& data);
|
||||
LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const;
|
||||
void updateHash();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,17 @@
|
|||
|
||||
/*[EXTRA_CODE_HERE]*/
|
||||
|
||||
// Inputs
|
||||
VARYING vec4 vary_HazeColor;
|
||||
VARYING float vary_LightNormPosDot;
|
||||
|
||||
uniform sampler2D rainbow_map;
|
||||
uniform sampler2D halo_map;
|
||||
|
||||
uniform float moisture_level;
|
||||
uniform float droplet_radius;
|
||||
uniform float ice_level;
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_data[3];
|
||||
#else
|
||||
|
|
@ -35,11 +46,34 @@ out vec4 frag_data[3];
|
|||
// The fragment shader for the sky
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VARYING vec4 vary_HazeColor;
|
||||
vec3 rainbow(float d)
|
||||
{
|
||||
// 'Interesting' values of d are -0.75 .. -0.825, i.e. when view vec nearly opposite of sun vec
|
||||
// Rainbox tex is mapped with REPEAT, so -.75 as tex coord is same as 0.25. -0.825 -> 0.175. etc.
|
||||
// SL-13629
|
||||
// Unfortunately the texture is inverted, so we need to invert the y coord, but keep the 'interesting'
|
||||
// part within the same 0.175..0.250 range, i.e. d = (1 - d) - 1.575
|
||||
d = clamp(-0.575 - d, 0.0, 1.0);
|
||||
|
||||
// With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
|
||||
// So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
|
||||
// space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
|
||||
float interior_coord = max(0.0, d - 0.25) * 4.2857;
|
||||
d = clamp(d, 0.0, 0.25) + interior_coord;
|
||||
|
||||
float rad = (droplet_radius - 5.0f) / 1024.0f;
|
||||
return pow(texture2D(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
|
||||
}
|
||||
|
||||
vec3 halo22(float d)
|
||||
{
|
||||
d = clamp(d, 0.1, 1.0);
|
||||
float v = sqrt(clamp(1 - (d * d), 0, 1));
|
||||
return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
|
||||
}
|
||||
|
||||
/// Soft clips the light with a gamma correction
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
vec3 srgb_to_linear(vec3 c);
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
@ -48,14 +82,18 @@ void main()
|
|||
// the fragment) if the sky wouldn't show up because the clouds
|
||||
// are fully opaque.
|
||||
|
||||
vec4 color;
|
||||
color = vary_HazeColor;
|
||||
vec4 color = vary_HazeColor;
|
||||
|
||||
float rel_pos_lightnorm = vary_LightNormPosDot;
|
||||
float optic_d = rel_pos_lightnorm;
|
||||
vec3 halo_22 = halo22(optic_d);
|
||||
color.rgb += rainbow(optic_d);
|
||||
color.rgb += halo_22;
|
||||
color.rgb *= 2.;
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
/// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(color.rgb, 0.0);
|
||||
// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(color.rgb, 1.0);
|
||||
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
|
||||
frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ ATTRIBUTE vec3 position;
|
|||
|
||||
// Output parameters
|
||||
VARYING vec4 vary_HazeColor;
|
||||
VARYING float vary_LightNormPosDot;
|
||||
|
||||
// Inputs
|
||||
uniform vec3 camPosLocal;
|
||||
|
|
@ -72,27 +73,29 @@ void main()
|
|||
vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
|
||||
|
||||
// Adj position vector to clamp altitude
|
||||
if (rel_pos.y > 0)
|
||||
if (rel_pos.y > 0.)
|
||||
{
|
||||
rel_pos *= (max_y / rel_pos.y);
|
||||
}
|
||||
if (rel_pos.y < 0)
|
||||
if (rel_pos.y < 0.)
|
||||
{
|
||||
rel_pos *= (-32000. / rel_pos.y);
|
||||
}
|
||||
|
||||
// Can normalize then
|
||||
vec3 rel_pos_norm = normalize(rel_pos);
|
||||
// Normalized
|
||||
vec3 rel_pos_norm = normalize(rel_pos);
|
||||
float rel_pos_len = length(rel_pos);
|
||||
|
||||
float rel_pos_len = length(rel_pos);
|
||||
// Grab this value and pass to frag shader for rainbows
|
||||
float rel_pos_lightnorm_dot = dot(rel_pos_norm, lightnorm.xyz);
|
||||
vary_LightNormPosDot = rel_pos_lightnorm_dot;
|
||||
|
||||
// Initialize temp variables
|
||||
vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
|
||||
vec4 light_atten;
|
||||
|
||||
// Sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
|
||||
// Calculate relative weights
|
||||
vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
|
||||
|
|
@ -112,7 +115,7 @@ void main()
|
|||
combined_haze = exp(-combined_haze * density_dist);
|
||||
|
||||
// Compute haze glow
|
||||
float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
|
||||
float haze_glow = 1.0 - rel_pos_lightnorm_dot;
|
||||
// haze_glow is 0 at the sun and increases away from sun
|
||||
haze_glow = max(haze_glow, .001);
|
||||
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
|
|
@ -123,30 +126,30 @@ void main()
|
|||
|
||||
// Add "minimum anti-solar illumination"
|
||||
// For sun, add to glow. For moon, remove glow entirely. SL-13768
|
||||
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
|
||||
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
|
||||
|
||||
vec4 color =
|
||||
(blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
|
||||
// Haze color above cloud
|
||||
vec4 color = (blue_horizon * blue_weight * (sunlight + ambient_color)
|
||||
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
|
||||
|
||||
// Final atmosphere additive
|
||||
color *= (1. - combined_haze);
|
||||
|
||||
// Increase ambient when there are more clouds
|
||||
vec4 tmpAmbient = ambient_color;
|
||||
tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
|
||||
vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
|
||||
|
||||
// Dim sunlight by cloud shadow percentage
|
||||
sunlight *= max(0.0, (1. - cloud_shadow));
|
||||
|
||||
// Haze color below cloud
|
||||
vec4 additiveColorBelowCloud =
|
||||
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
|
||||
vec4 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
|
||||
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
|
||||
|
||||
// Attenuate cloud color by atmosphere
|
||||
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
|
||||
|
||||
// At horizon, blend high altitude sky color towards the darker color below the clouds
|
||||
color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
|
||||
color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
|
||||
|
||||
// Haze color above cloud
|
||||
vary_HazeColor = color;
|
||||
|
|
|
|||
|
|
@ -1,199 +0,0 @@
|
|||
/**
|
||||
* @file class2/deferred/skyF.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2005, 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$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
// SKY ////////////////////////////////////////////////////////////////////////
|
||||
// The vertex shader for creating the atmospheric sky
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Inputs
|
||||
uniform vec3 camPosLocal;
|
||||
|
||||
uniform vec4 lightnorm;
|
||||
uniform vec4 sunlight_color;
|
||||
uniform vec4 moonlight_color;
|
||||
uniform int sun_up_factor;
|
||||
uniform vec4 ambient_color;
|
||||
uniform vec4 blue_horizon;
|
||||
uniform vec4 blue_density;
|
||||
uniform float haze_horizon;
|
||||
uniform float haze_density;
|
||||
|
||||
uniform float cloud_shadow;
|
||||
uniform float density_multiplier;
|
||||
uniform float distance_multiplier;
|
||||
uniform float max_y;
|
||||
|
||||
uniform vec4 glow;
|
||||
uniform float sun_moon_glow_factor;
|
||||
|
||||
uniform vec4 cloud_color;
|
||||
|
||||
#ifdef DEFINE_GL_FRAGCOLOR
|
||||
out vec4 frag_data[3];
|
||||
#else
|
||||
#define frag_data gl_FragData
|
||||
#endif
|
||||
|
||||
VARYING vec3 pos;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// The fragment shader for the sky
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uniform sampler2D rainbow_map;
|
||||
uniform sampler2D halo_map;
|
||||
|
||||
uniform float moisture_level;
|
||||
uniform float droplet_radius;
|
||||
uniform float ice_level;
|
||||
|
||||
vec3 rainbow(float d)
|
||||
{
|
||||
// d is the dot product of view and sun directions, so ranging -1.0..1.0
|
||||
// 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
|
||||
// Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
|
||||
|
||||
// SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
|
||||
// Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
|
||||
// interesting range, but in reversed order: i.e. d = (1 - d) - 1.575
|
||||
d = clamp(-0.575 - d, 0.0, 1.0);
|
||||
|
||||
// With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
|
||||
// So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
|
||||
// space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
|
||||
float interior_coord = max(0.0, d - 0.25) * 4.2857;
|
||||
d = clamp(d, 0.0, 0.25) + interior_coord;
|
||||
|
||||
float rad = (droplet_radius - 5.0f) / 1024.0f;
|
||||
return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
|
||||
}
|
||||
|
||||
vec3 halo22(float d)
|
||||
{
|
||||
d = clamp(d, 0.1, 1.0);
|
||||
float v = sqrt(clamp(1 - (d * d), 0, 1));
|
||||
return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
|
||||
}
|
||||
|
||||
/// Soft clips the light with a gamma correction
|
||||
vec3 scaleSoftClip(vec3 light);
|
||||
|
||||
void main()
|
||||
{
|
||||
// World / view / projection
|
||||
// Get relative position (offset why?)
|
||||
vec3 rel_pos = pos.xyz - camPosLocal.xyz + vec3(0, 50, 0);
|
||||
|
||||
// Adj position vector to clamp altitude
|
||||
if (rel_pos.y > 0.)
|
||||
{
|
||||
rel_pos *= (max_y / rel_pos.y);
|
||||
}
|
||||
if (rel_pos.y < 0.)
|
||||
{
|
||||
rel_pos *= (-32000. / rel_pos.y);
|
||||
}
|
||||
|
||||
// Normalized
|
||||
vec3 rel_pos_norm = normalize(rel_pos);
|
||||
float rel_pos_len = length(rel_pos);
|
||||
|
||||
// Initialize temp variables
|
||||
vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
|
||||
|
||||
// Sunlight attenuation effect (hue and brightness) due to atmosphere
|
||||
// this is used later for sunlight modulation at various altitudes
|
||||
vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
|
||||
|
||||
// Calculate relative weights
|
||||
vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
|
||||
vec4 blue_weight = blue_density / combined_haze;
|
||||
vec4 haze_weight = haze_density / combined_haze;
|
||||
|
||||
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
|
||||
float off_axis = 1.0 / max(1e-6, max(0, rel_pos_norm.y) + lightnorm.y);
|
||||
sunlight *= exp(-light_atten * off_axis);
|
||||
|
||||
// Distance
|
||||
float density_dist = rel_pos_len * density_multiplier;
|
||||
|
||||
// Transparency (-> combined_haze)
|
||||
// ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
|
||||
// compiler gets confused.
|
||||
combined_haze = exp(-combined_haze * density_dist);
|
||||
|
||||
// Compute haze glow
|
||||
float haze_glow = dot(rel_pos_norm, lightnorm.xyz);
|
||||
haze_glow = 1. - haze_glow;
|
||||
// haze_glow is 0 at the sun and increases away from sun
|
||||
haze_glow = max(haze_glow, .001);
|
||||
// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
|
||||
haze_glow *= glow.x;
|
||||
// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
|
||||
haze_glow = pow(haze_glow, glow.z);
|
||||
// glow.z should be negative, so we're doing a sort of (1 / "angle") function
|
||||
|
||||
// Add "minimum anti-solar illumination"
|
||||
// For sun, add to glow. For moon, remove glow entirely. SL-13768
|
||||
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
|
||||
|
||||
// Haze color above cloud
|
||||
vec4 color = blue_horizon * blue_weight * (sunlight + ambient_color)
|
||||
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient_color);
|
||||
|
||||
// Final atmosphere additive
|
||||
color *= (1. - combined_haze);
|
||||
|
||||
// Increase ambient when there are more clouds
|
||||
// TODO 9/20: DJH what does this do? max(0,(1-ambient)) will change the color
|
||||
vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
|
||||
|
||||
// Dim sunlight by cloud shadow percentage
|
||||
sunlight *= max(0.0, (1. - cloud_shadow));
|
||||
|
||||
// Haze color below cloud
|
||||
vec4 add_below_cloud = blue_horizon * blue_weight * (sunlight + ambient)
|
||||
+ haze_horizon * haze_weight * (sunlight * haze_glow + ambient);
|
||||
|
||||
// Attenuate cloud color by atmosphere
|
||||
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
|
||||
|
||||
// At horizon, blend high altitude sky color towards the darker color below the clouds
|
||||
color += (add_below_cloud - color) * (1. - sqrt(combined_haze));
|
||||
|
||||
float optic_d = dot(rel_pos_norm, lightnorm.xyz);
|
||||
vec3 halo_22 = halo22(optic_d);
|
||||
color.rgb += rainbow(optic_d);
|
||||
color.rgb += halo_22;
|
||||
color.rgb *= 2.;
|
||||
color.rgb = scaleSoftClip(color.rgb);
|
||||
|
||||
// Gamma correct for WL (soft clip effect).
|
||||
frag_data[0] = vec4(color.rgb, 1.0);
|
||||
frag_data[1] = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
frag_data[2] = vec4(0.0, 0.0, 0.0, 1.0); // 1.0 in norm.w masks off fog
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* @file WLSkyV.glsl
|
||||
*
|
||||
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2005, 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$
|
||||
*/
|
||||
|
||||
uniform mat4 modelview_projection_matrix;
|
||||
|
||||
ATTRIBUTE vec3 position;
|
||||
|
||||
// SKY ////////////////////////////////////////////////////////////////////////
|
||||
// The vertex shader for creating the atmospheric sky
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
VARYING vec3 pos;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
// World / view / projection
|
||||
pos = position.xyz;
|
||||
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
|
||||
}
|
||||
|
|
@ -59,8 +59,6 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key)
|
|||
{
|
||||
// <FS:Ansariel> Cinder's fly-out button
|
||||
//mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this));
|
||||
//mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this));
|
||||
//mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this));
|
||||
mCommitCallbackRegistrar.add("OpenObject.CopyAction", boost::bind(&LLFloaterOpenObject::onClickCopy, this, _2));
|
||||
// </FS:Ansariel>
|
||||
mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this));
|
||||
|
|
@ -260,18 +258,6 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data)
|
|||
// moveToInventory(false);
|
||||
// closeFloater();
|
||||
//}
|
||||
//
|
||||
//void LLFloaterOpenObject::onClickMoveAndWear()
|
||||
//{
|
||||
// moveToInventory(true, false);
|
||||
// closeFloater();
|
||||
//}
|
||||
//
|
||||
//void LLFloaterOpenObject::onClickReplace()
|
||||
//{
|
||||
// moveToInventory(true, true);
|
||||
// closeFloater();
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
void LLFloaterOpenObject::onClickCancel()
|
||||
|
|
|
|||
|
|
@ -64,8 +64,6 @@ protected:
|
|||
|
||||
// <FS:Ansariel> Cinder's fly-out button
|
||||
//void onClickMoveToInventory();
|
||||
//void onClickMoveAndWear();
|
||||
//void onClickReplace();
|
||||
void onClickCopy(const LLSD& value);
|
||||
// </FS:Ansariel>
|
||||
void onClickCancel();
|
||||
|
|
|
|||
|
|
@ -429,12 +429,10 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI
|
|||
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
|
||||
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
|
||||
|
||||
LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||
std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
|
||||
std::istringstream content_stream(content_string);
|
||||
const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||
|
||||
LLSD response_data;
|
||||
U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
|
||||
U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size());
|
||||
if (uzip_result != LLUZipHelper::ZR_OK)
|
||||
{
|
||||
LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
|
||||
|
|
@ -472,15 +470,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL
|
|||
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
|
||||
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
|
||||
|
||||
LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||
std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
|
||||
std::istringstream content_stream(content_string);
|
||||
const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||
|
||||
LLSD response_data;
|
||||
// <FS:Beq pp Rye> Use new variant unzip_llsd
|
||||
// U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
|
||||
U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size());
|
||||
// </FS:Beq pp Rye>
|
||||
if (uzip_result != LLUZipHelper::ZR_OK)
|
||||
{
|
||||
LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
|
||||
|
|
@ -544,12 +537,10 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content)
|
|||
llassert(content.has(MATERIALS_CAP_ZIP_FIELD));
|
||||
llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary());
|
||||
|
||||
LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||
std::string content_string(reinterpret_cast<const char*>(content_binary.data()), content_binary.size());
|
||||
std::istringstream content_stream(content_string);
|
||||
const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary();
|
||||
|
||||
LLSD response_data;
|
||||
U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size());
|
||||
U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size());
|
||||
if (uzip_result != LLUZipHelper::ZR_OK)
|
||||
{
|
||||
LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -210,10 +210,8 @@ public:
|
|||
LLCondition* mSignal;
|
||||
|
||||
//map of known mesh headers
|
||||
typedef std::map<LLUUID, LLSD> mesh_header_map;
|
||||
typedef boost::unordered_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; // pair is header_size and data
|
||||
mesh_header_map mMeshHeader;
|
||||
|
||||
std::map<LLUUID, U32> mMeshHeaderSize;
|
||||
|
||||
class HeaderRequest : public RequestStats
|
||||
{
|
||||
|
|
@ -283,10 +281,13 @@ public:
|
|||
};
|
||||
|
||||
//set of requested skin info
|
||||
std::set<UUIDBasedRequest> mSkinRequests;
|
||||
std::deque<UUIDBasedRequest> mSkinRequests;
|
||||
|
||||
// list of completed skin info requests
|
||||
std::list<LLMeshSkinInfo> mSkinInfoQ;
|
||||
std::deque<LLMeshSkinInfo*> mSkinInfoQ;
|
||||
|
||||
// list of skin info requests that have failed or are unavailaibe
|
||||
std::deque<UUIDBasedRequest> mSkinUnavailableQ;
|
||||
|
||||
//set of requested decompositions
|
||||
std::set<UUIDBasedRequest> mDecompositionRequests;
|
||||
|
|
@ -304,13 +305,13 @@ public:
|
|||
std::queue<LODRequest> mLODReqQ;
|
||||
|
||||
//queue of unavailable LODs (either asset doesn't exist or asset doesn't have desired LOD)
|
||||
std::queue<LODRequest> mUnavailableQ;
|
||||
std::deque<LODRequest> mUnavailableQ;
|
||||
|
||||
//queue of successfully loaded meshes
|
||||
std::queue<LoadedMesh> mLoadedQ;
|
||||
std::deque<LoadedMesh> mLoadedQ;
|
||||
|
||||
//map of pending header requests and currently desired LODs
|
||||
typedef std::map<LLVolumeParams, std::vector<S32> > pending_lod_map;
|
||||
typedef boost::unordered_map<LLUUID, std::vector<S32> > pending_lod_map;
|
||||
pending_lod_map mPendingLOD;
|
||||
|
||||
// llcorehttp library interface objects.
|
||||
|
|
@ -360,7 +361,7 @@ public:
|
|||
|
||||
//send request for skin info, returns true if header info exists
|
||||
// (should hold onto mesh_id and try again later if header info does not exist)
|
||||
bool fetchMeshSkinInfo(const LLUUID& mesh_id);
|
||||
bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true);
|
||||
|
||||
//send request for decomposition, returns true if header info exists
|
||||
// (should hold onto mesh_id and try again later if header info does not exist)
|
||||
|
|
@ -599,18 +600,20 @@ public:
|
|||
void shutdown();
|
||||
S32 update();
|
||||
|
||||
void unregisterMesh(LLVOVolume* volume);
|
||||
//mesh management functions
|
||||
S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1);
|
||||
|
||||
void notifyLoadedMeshes();
|
||||
void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume);
|
||||
void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod);
|
||||
void notifySkinInfoReceived(LLMeshSkinInfo& info);
|
||||
void notifySkinInfoReceived(LLMeshSkinInfo* info);
|
||||
void notifySkinInfoUnavailable(const LLUUID& info);
|
||||
void notifyDecompositionReceived(LLModel::Decomposition* info);
|
||||
|
||||
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
|
||||
static S32 getActualMeshLOD(LLSD& header, S32 lod);
|
||||
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr);
|
||||
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr);
|
||||
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
|
||||
void fetchPhysicsShape(const LLUUID& mesh_id);
|
||||
bool hasPhysicsShape(const LLUUID& mesh_id);
|
||||
|
|
@ -635,13 +638,13 @@ public:
|
|||
static void metricsProgress(unsigned int count);
|
||||
static void metricsUpdate();
|
||||
|
||||
typedef std::map<LLVolumeParams, std::set<LLUUID> > mesh_load_map;
|
||||
typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map;
|
||||
mesh_load_map mLoadingMeshes[4];
|
||||
|
||||
// <FS:Ansariel> DAE export
|
||||
LLUUID getCreatorFromHeader(const LLUUID& mesh_id);
|
||||
|
||||
typedef std::unordered_map<LLUUID, LLMeshSkinInfo> skin_map;
|
||||
typedef std::unordered_map<LLUUID, LLPointer<LLMeshSkinInfo>> skin_map;
|
||||
skin_map mSkinMap;
|
||||
|
||||
typedef std::map<LLUUID, LLModel::Decomposition*> decomposition_map;
|
||||
|
|
@ -652,7 +655,7 @@ public:
|
|||
std::vector<LLMeshRepoThread::LODRequest> mPendingRequests;
|
||||
|
||||
//list of mesh ids awaiting skin info
|
||||
typedef std::map<LLUUID, std::set<LLUUID> > skin_load_map;
|
||||
typedef boost::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map;
|
||||
skin_load_map mLoadingSkins;
|
||||
|
||||
//list of mesh ids that need to send skin info fetch requests
|
||||
|
|
@ -677,6 +680,8 @@ public:
|
|||
std::vector<LLMeshUploadThread*> mUploadWaitList;
|
||||
|
||||
LLPhysicsDecomp* mDecompThread;
|
||||
|
||||
LLFrameTimer mSkinInfoCullTimer;
|
||||
|
||||
class inventory_data
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1438,7 +1438,8 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par
|
|||
mHaveInventory(FALSE),
|
||||
mIsInventoryEmpty(TRUE),
|
||||
mInventoryNeedsUpdate(FALSE),
|
||||
mInventoryViewModel(p.name)
|
||||
mInventoryViewModel(p.name),
|
||||
mShowRootFolder(p.show_root_folder)
|
||||
{
|
||||
// Setup context menu callbacks
|
||||
mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2));
|
||||
|
|
@ -1710,15 +1711,23 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
|
|||
// </FS:Ansariel>
|
||||
|
||||
LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
|
||||
new_folder->addToFolder(mFolders);
|
||||
new_folder->toggleOpen();
|
||||
|
||||
if (mShowRootFolder)
|
||||
{
|
||||
new_folder->addToFolder(mFolders);
|
||||
new_folder->toggleOpen();
|
||||
}
|
||||
|
||||
if (!contents.empty())
|
||||
{
|
||||
createViewsForCategory(&contents, inventory_root, new_folder);
|
||||
createViewsForCategory(&contents, inventory_root, mShowRootFolder ? new_folder : mFolders);
|
||||
}
|
||||
// Refresh for label to add item count
|
||||
new_folder->refresh();
|
||||
|
||||
if (mShowRootFolder)
|
||||
{
|
||||
// Refresh for label to add item count
|
||||
new_folder->refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,8 +48,14 @@ class LLViewerObject;
|
|||
class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
|
||||
{
|
||||
public:
|
||||
// dummy param block for template registration purposes
|
||||
struct Params : public LLPanel::Params {};
|
||||
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
|
||||
{
|
||||
Optional<bool> show_root_folder;
|
||||
|
||||
Params()
|
||||
: show_root_folder("show_root_folder", true)
|
||||
{}
|
||||
};
|
||||
|
||||
LLPanelObjectInventory(const Params&);
|
||||
virtual ~LLPanelObjectInventory();
|
||||
|
|
@ -113,6 +119,7 @@ private:
|
|||
BOOL mIsInventoryEmpty; // 'Empty' label
|
||||
BOOL mInventoryNeedsUpdate; // for idle, set on changed callback
|
||||
LLFolderViewModelInventory mInventoryViewModel;
|
||||
bool mShowRootFolder;
|
||||
};
|
||||
|
||||
#endif // LL_LLPANELOBJECTINVENTORY_H
|
||||
|
|
|
|||
|
|
@ -245,6 +245,9 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
|
|||
mColorChanged = FALSE;
|
||||
mSpotLightPriority = 0.f;
|
||||
|
||||
mSkinInfoFailed = false;
|
||||
mSkinInfo = NULL;
|
||||
|
||||
mMediaImplList.resize(getNumTEs());
|
||||
mLastFetchedMediaVersion = -1;
|
||||
mServerDrawableUpdateCount = 0;
|
||||
|
|
@ -263,6 +266,8 @@ LLVOVolume::~LLVOVolume()
|
|||
delete mVolumeImpl;
|
||||
mVolumeImpl = NULL;
|
||||
|
||||
gMeshRepo.unregisterMesh(this);
|
||||
|
||||
if(!mMediaImplList.empty())
|
||||
{
|
||||
for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
|
||||
|
|
@ -1254,6 +1259,12 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo
|
|||
// if it's a mesh
|
||||
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
|
||||
{
|
||||
if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID())
|
||||
{
|
||||
mSkinInfo = NULL;
|
||||
mSkinInfoFailed = false;
|
||||
}
|
||||
|
||||
if (!getVolume()->isMeshAssetLoaded())
|
||||
{
|
||||
//load request not yet issued, request pipeline load this mesh
|
||||
|
|
@ -1265,6 +1276,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo
|
|||
}
|
||||
}
|
||||
|
||||
if (!mSkinInfo && !mSkinInfoFailed)
|
||||
{
|
||||
const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this);
|
||||
if (skin_info)
|
||||
{
|
||||
notifySkinInfoLoaded(skin_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // otherwise is sculptie
|
||||
{
|
||||
|
|
@ -1317,6 +1336,9 @@ void LLVOVolume::updateSculptTexture()
|
|||
{
|
||||
mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
|
||||
}
|
||||
|
||||
mSkinInfoFailed = false;
|
||||
mSkinInfo = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1371,6 +1393,20 @@ void LLVOVolume::notifyMeshLoaded()
|
|||
updateVisualComplexity();
|
||||
}
|
||||
|
||||
void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
|
||||
{
|
||||
mSkinInfoFailed = false;
|
||||
mSkinInfo = skin;
|
||||
|
||||
notifyMeshLoaded();
|
||||
}
|
||||
|
||||
void LLVOVolume::notifySkinInfoUnavailable()
|
||||
{
|
||||
mSkinInfoFailed = true;
|
||||
mSkinInfo = nullptr;
|
||||
}
|
||||
|
||||
// sculpt replaces generate() for sculpted surfaces
|
||||
void LLVOVolume::sculpt()
|
||||
{
|
||||
|
|
@ -3847,7 +3883,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const
|
|||
{
|
||||
if (getVolume())
|
||||
{
|
||||
return gMeshRepo.getSkinInfo(getMeshID(), this);
|
||||
return mSkinInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -357,6 +357,8 @@ public:
|
|||
void updateVisualComplexity();
|
||||
|
||||
void notifyMeshLoaded();
|
||||
void notifySkinInfoLoaded(const LLMeshSkinInfo* skin);
|
||||
void notifySkinInfoUnavailable();
|
||||
|
||||
// Returns 'true' iff the media data for this object is in flight
|
||||
bool isMediaDataBeingFetched() const;
|
||||
|
|
@ -445,6 +447,8 @@ private:
|
|||
|
||||
LLPointer<LLRiggedVolume> mRiggedVolume;
|
||||
|
||||
bool mSkinInfoFailed;
|
||||
LLConstPointer<LLMeshSkinInfo> mSkinInfo;
|
||||
// statics
|
||||
public:
|
||||
static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop
|
||||
|
|
|
|||
|
|
@ -308,12 +308,12 @@ void LLLocalMeshObject::attachSkinInfo()
|
|||
auto skinmap_seeker = gMeshRepo.mSkinMap.find(mSculptID);
|
||||
if (skinmap_seeker == gMeshRepo.mSkinMap.end())
|
||||
{
|
||||
gMeshRepo.mSkinMap[mSculptID] = mMeshSkinInfo;
|
||||
gMeshRepo.mSkinMap[mSculptID] = &mMeshSkinInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: seems necessary, not tested without.
|
||||
skinmap_seeker->second = mMeshSkinInfo;
|
||||
skinmap_seeker->second = &mMeshSkinInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue