Merge branch 'develop' into callum/viewer-cef-2025-08
commit
e935a8aebc
|
|
@ -1,8 +1,5 @@
|
|||
* text eol=lf
|
||||
|
||||
# VSTool (normalization disabled)
|
||||
indra/tools/vstool/* -text
|
||||
|
||||
# Images
|
||||
*.bmp binary
|
||||
*.BMP binary
|
||||
|
|
|
|||
|
|
@ -43,7 +43,11 @@ jobs:
|
|||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: windows
|
||||
runner: qa-dan-asus
|
||||
runner: qa-windows-asus-dan
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: windows
|
||||
runner: qa-windows-z600-dan
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: mac
|
||||
|
|
|
|||
|
|
@ -1435,11 +1435,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>9e59c93c7110e87b4ff3db330f11a23c50e5000f</string>
|
||||
<string>7facda95e2f00c260513f3d4db42588fa8ba703c</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910560</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289774</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -1451,11 +1451,11 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>7ed994db5bafa9a7ad09a1b53da850a84715c65e</string>
|
||||
<string>01d08f13c7bc8d1b95b0330fa6833b7d8274e4d0</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910561</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289775</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
|
|
@ -1467,24 +1467,24 @@
|
|||
<key>creds</key>
|
||||
<string>github</string>
|
||||
<key>hash</key>
|
||||
<string>66824c02e0e5eabbfbe37bfb173360195f89697c</string>
|
||||
<string>6d00345c7d3471bc5f7c1218e014dd0f1a2c069b</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/178910562</string>
|
||||
<string>https://api.github.com/repos/secondlife/llphysicsextensions_source/releases/assets/196289778</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2010, Linden Research, Inc.</string>
|
||||
<key>license</key>
|
||||
<string>internal</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/llphysicsextensions.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2010, Linden Research, Inc.</string>
|
||||
<key>version</key>
|
||||
<string>1.0.66e6919</string>
|
||||
<string>1.0.11137145495</string>
|
||||
<key>name</key>
|
||||
<string>llphysicsextensions_source</string>
|
||||
</map>
|
||||
|
|
@ -2332,59 +2332,33 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>threejs</key>
|
||||
<map>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>cfed00d8ea7265c035c2d86a234b28efb0b23756</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-darwin64-b8f6746.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9de1295b157c9913c28be81ff933c73493ecc132</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-linux64-b8f6746.tar.zst</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>4141710fccbd1ea2b3b53d00e189bdfa2ee9d441</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-b8f6746/threejs-0.132.2-windows64-b8f6746.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright © 2010-2021 three.js authors</string>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/THREEJS_LICENSE.txt</string>
|
||||
<key>copyright</key>
|
||||
<string>Copyright © 2010-2021 three.js authors</string>
|
||||
<key>version</key>
|
||||
<string>0.132.2</string>
|
||||
<key>name</key>
|
||||
<string>threejs</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>common</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>982c0fa427458082ea9e3cb9603904210732b64e</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>sha1</string>
|
||||
<key>url</key>
|
||||
<string>https://github.com/secondlife/3p-three_js/releases/download/v0.132.2-5da28d9/threejs-0.132.2-common-8454371083.tar.zst</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>0.132.2</string>
|
||||
</map>
|
||||
<key>tinygltf</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -119,6 +119,8 @@ public:
|
|||
|
||||
virtual void addDebugText( const std::string& text ) = 0;
|
||||
|
||||
virtual std::string getDebugName() const { return getID().asString(); }
|
||||
|
||||
virtual const LLUUID& getID() const = 0;
|
||||
//-------------------------------------------------------------------------
|
||||
// End Interface
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llassettype.h"
|
||||
#include "lldictionary.h"
|
||||
#include "llmemory.h"
|
||||
#include "llsd.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -246,3 +247,19 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LLSD LLAssetType::getTypeNames()
|
||||
{
|
||||
LLSD type_names;
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
for (S32 type = AT_TEXTURE; type < AT_COUNT; ++type)
|
||||
{
|
||||
const AssetEntry *entry = dict->lookup((LLAssetType::EType) type);
|
||||
// skip llassettype_bad_lookup
|
||||
if (entry)
|
||||
{
|
||||
type_names.append(entry->mTypeName);
|
||||
}
|
||||
}
|
||||
return type_names;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,6 +165,8 @@ public:
|
|||
static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
|
||||
static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
|
||||
|
||||
static LLSD getTypeNames();
|
||||
|
||||
static const std::string BADLOOKUP;
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -638,6 +638,14 @@ public:
|
|||
{
|
||||
getCPUIDInfo();
|
||||
uint64_t frequency = getSysctlInt64("hw.cpufrequency");
|
||||
if (!frequency)
|
||||
{
|
||||
auto tbfrequency = getSysctlInt64("hw.tbfrequency");
|
||||
struct clockinfo clockrate;
|
||||
auto clockrate_len = sizeof(clockrate);
|
||||
if (!sysctlbyname("kern.clockrate", &clockrate, &clockrate_len, NULL, 0))
|
||||
frequency = tbfrequency * clockrate.hz;
|
||||
}
|
||||
setInfo(eFrequency, (F64)frequency / (F64)1000000);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -553,6 +553,45 @@ LLSD shallow(LLSD value, LLSD filter=LLSD()) { return llsd_shallow(value, filter
|
|||
|
||||
} // namespace llsd
|
||||
|
||||
/*****************************************************************************
|
||||
* LLSDParam<std::vector<T>>
|
||||
*****************************************************************************/
|
||||
// Given an LLSD array, return a const std::vector<T>&, where T is a type
|
||||
// supported by LLSDParam. Bonus: if the LLSD value is actually a scalar,
|
||||
// return a single-element vector containing the converted value.
|
||||
template <typename T>
|
||||
class LLSDParam<std::vector<T>>: public LLSDParamBase
|
||||
{
|
||||
public:
|
||||
LLSDParam(const LLSD& array)
|
||||
{
|
||||
// treat undefined "array" as empty vector
|
||||
if (array.isDefined())
|
||||
{
|
||||
// what if it's a scalar?
|
||||
if (! array.isArray())
|
||||
{
|
||||
v.push_back(LLSDParam<T>(array));
|
||||
}
|
||||
else // really is an array
|
||||
{
|
||||
// reserve space for the array entries
|
||||
v.reserve(array.size());
|
||||
for (const auto& item : llsd::inArray(array))
|
||||
{
|
||||
v.push_back(LLSDParam<T>(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator const std::vector<T>&() const { return v; }
|
||||
|
||||
private:
|
||||
std::vector<T> v;
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* toArray(), toMap()
|
||||
*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ namespace LL
|
|||
* ThreadPool listens for application shutdown messages on the "LLApp"
|
||||
* LLEventPump. Call close() to shut down this ThreadPool early.
|
||||
*/
|
||||
virtual void close();
|
||||
void close();
|
||||
|
||||
std::string getName() const { return mName; }
|
||||
size_t getWidth() const { return mThreads.size(); }
|
||||
|
|
@ -122,7 +122,7 @@ namespace LL
|
|||
size_t threads=1,
|
||||
size_t capacity=1024*1024,
|
||||
bool auto_shutdown = true):
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity), auto_shutdown)
|
||||
ThreadPoolBase(name, threads, new queue_t(name, capacity, false), auto_shutdown)
|
||||
{}
|
||||
~ThreadPoolUsing() override {}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "llcoros.h"
|
||||
#include LLCOROS_MUTEX_HEADER
|
||||
#include "llerror.h"
|
||||
#include "llevents.h"
|
||||
#include "llexception.h"
|
||||
#include "stringize.h"
|
||||
|
||||
|
|
@ -30,11 +31,38 @@ using Lock = LLCoros::LockType;
|
|||
/*****************************************************************************
|
||||
* WorkQueueBase
|
||||
*****************************************************************************/
|
||||
LL::WorkQueueBase::WorkQueueBase(const std::string& name):
|
||||
super(makeName(name))
|
||||
LL::WorkQueueBase::WorkQueueBase(const std::string& name, bool auto_shutdown)
|
||||
: super(makeName(name))
|
||||
{
|
||||
// TODO: register for "LLApp" events so we can implicitly close() on
|
||||
// viewer shutdown.
|
||||
if (auto_shutdown)
|
||||
{
|
||||
// Register for "LLApp" events so we can implicitly close() on viewer shutdown
|
||||
std::string listener_name = "WorkQueue:" + getKey();
|
||||
LLEventPumps::instance().obtain("LLApp").listen(
|
||||
listener_name,
|
||||
[this](const LLSD& stat)
|
||||
{
|
||||
std::string status(stat["status"]);
|
||||
if (status != "running")
|
||||
{
|
||||
// Viewer is shutting down, close this queue
|
||||
LL_DEBUGS("WorkQueue") << getKey() << " closing on app shutdown" << LL_ENDL;
|
||||
close();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Store the listener name so we can unregister in the destructor
|
||||
mListenerName = listener_name;
|
||||
}
|
||||
}
|
||||
|
||||
LL::WorkQueueBase::~WorkQueueBase()
|
||||
{
|
||||
if (!mListenerName.empty() && !LLEventPumps::wasDeleted())
|
||||
{
|
||||
LLEventPumps::instance().obtain("LLApp").stopListening(mListenerName);
|
||||
}
|
||||
}
|
||||
|
||||
void LL::WorkQueueBase::runUntilClose()
|
||||
|
|
@ -220,8 +248,8 @@ void LL::WorkQueueBase::checkCoroutine(const std::string& method)
|
|||
/*****************************************************************************
|
||||
* WorkQueue
|
||||
*****************************************************************************/
|
||||
LL::WorkQueue::WorkQueue(const std::string& name, size_t capacity):
|
||||
super(name),
|
||||
LL::WorkQueue::WorkQueue(const std::string& name, size_t capacity, bool auto_shutdown):
|
||||
super(name, auto_shutdown),
|
||||
mQueue(capacity)
|
||||
{
|
||||
}
|
||||
|
|
@ -269,8 +297,8 @@ bool LL::WorkQueue::tryPop_(Work& work)
|
|||
/*****************************************************************************
|
||||
* WorkSchedule
|
||||
*****************************************************************************/
|
||||
LL::WorkSchedule::WorkSchedule(const std::string& name, size_t capacity):
|
||||
super(name),
|
||||
LL::WorkSchedule::WorkSchedule(const std::string& name, size_t capacity, bool auto_shutdown):
|
||||
super(name, auto_shutdown),
|
||||
mQueue(capacity)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,9 @@ namespace LL
|
|||
* You may omit the WorkQueueBase name, in which case a unique name is
|
||||
* synthesized; for practical purposes that makes it anonymous.
|
||||
*/
|
||||
WorkQueueBase(const std::string& name);
|
||||
WorkQueueBase(const std::string& name, bool auto_shutdown);
|
||||
|
||||
virtual ~WorkQueueBase();
|
||||
|
||||
/**
|
||||
* Since the point of WorkQueue is to pass work to some other worker
|
||||
|
|
@ -197,6 +199,9 @@ namespace LL
|
|||
private:
|
||||
virtual Work pop_() = 0;
|
||||
virtual bool tryPop_(Work&) = 0;
|
||||
|
||||
// Name used for the LLApp event listener (empty if not registered)
|
||||
std::string mListenerName;
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
@ -212,7 +217,7 @@ namespace LL
|
|||
* You may omit the WorkQueue name, in which case a unique name is
|
||||
* synthesized; for practical purposes that makes it anonymous.
|
||||
*/
|
||||
WorkQueue(const std::string& name = std::string(), size_t capacity=1024);
|
||||
WorkQueue(const std::string& name = std::string(), size_t capacity=1024, bool auto_shutdown = true);
|
||||
|
||||
/**
|
||||
* Since the point of WorkQueue is to pass work to some other worker
|
||||
|
|
@ -282,7 +287,7 @@ namespace LL
|
|||
* You may omit the WorkSchedule name, in which case a unique name is
|
||||
* synthesized; for practical purposes that makes it anonymous.
|
||||
*/
|
||||
WorkSchedule(const std::string& name = std::string(), size_t capacity=1024);
|
||||
WorkSchedule(const std::string& name = std::string(), size_t capacity=1024, bool auto_shutdown = true);
|
||||
|
||||
/**
|
||||
* Since the point of WorkSchedule is to pass work to some other worker
|
||||
|
|
|
|||
|
|
@ -538,6 +538,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
long sslHostV(0L);
|
||||
long dnsCacheTimeout(-1L);
|
||||
long nobody(0L);
|
||||
curl_off_t lastModified(0L);
|
||||
|
||||
if (mReqOptions)
|
||||
{
|
||||
|
|
@ -546,6 +547,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L;
|
||||
dnsCacheTimeout = mReqOptions->getDNSCacheTimeout();
|
||||
nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;
|
||||
lastModified = (curl_off_t)mReqOptions->getLastModified();
|
||||
}
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
|
||||
|
||||
|
|
@ -554,6 +556,17 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
|
||||
|
||||
if (lastModified)
|
||||
{
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||
#if (LIBCURL_VERSION_NUM >= 0x073B00)
|
||||
// requires curl 7.59.0
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE_LARGE, lastModified);
|
||||
#else
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE, (long)lastModified);
|
||||
#endif
|
||||
}
|
||||
|
||||
// The Linksys WRT54G V5 router has an issue with frequent
|
||||
// DNS lookups from LAN machines. If they happen too often,
|
||||
// like for every HTTP request, the router gets annoyed after
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ HttpOptions::HttpOptions() :
|
|||
mVerifyPeer(sDefaultVerifyPeer),
|
||||
mVerifyHost(false),
|
||||
mDNSCacheTimeout(-1L),
|
||||
mLastModified(0),
|
||||
mNoBody(false)
|
||||
{}
|
||||
|
||||
|
|
@ -129,6 +130,11 @@ void HttpOptions::setHeadersOnly(bool nobody)
|
|||
}
|
||||
}
|
||||
|
||||
void HttpOptions::setLastModified(time_t lastModified)
|
||||
{
|
||||
mLastModified = lastModified;
|
||||
}
|
||||
|
||||
void HttpOptions::setDefaultSSLVerifyPeer(bool verify)
|
||||
{
|
||||
sDefaultVerifyPeer = verify;
|
||||
|
|
|
|||
|
|
@ -178,6 +178,13 @@ public:
|
|||
return mNoBody;
|
||||
}
|
||||
|
||||
// Default: 0
|
||||
void setLastModified(time_t lastModified);
|
||||
time_t getLastModified() const
|
||||
{
|
||||
return mLastModified;
|
||||
}
|
||||
|
||||
/// Sets default behavior for verifying that the name in the
|
||||
/// security certificate matches the name of the host contacted.
|
||||
/// Defaults false if not set, but should be set according to
|
||||
|
|
@ -199,6 +206,7 @@ protected:
|
|||
bool mVerifyHost;
|
||||
int mDNSCacheTimeout;
|
||||
bool mNoBody;
|
||||
time_t mLastModified;
|
||||
|
||||
static bool sDefaultVerifyPeer;
|
||||
}; // end class HttpOptions
|
||||
|
|
|
|||
|
|
@ -558,6 +558,12 @@ bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
|
|||
LL_INFOS() << "Dropping alpha information during BMP encoding" << LL_ENDL;
|
||||
}
|
||||
|
||||
if (raw_image->isBufferInvalid())
|
||||
{
|
||||
setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
setSize(raw_image->getWidth(), raw_image->getHeight(), dst_components);
|
||||
|
||||
U8 magic[14];
|
||||
|
|
|
|||
|
|
@ -329,6 +329,12 @@ bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_
|
|||
{
|
||||
llassert_always(raw_image);
|
||||
|
||||
if (raw_image->isBufferInvalid())
|
||||
{
|
||||
setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
S32 ncomponents = raw_image->getComponents();
|
||||
EFileFormat format;
|
||||
switch (ncomponents)
|
||||
|
|
|
|||
|
|
@ -491,6 +491,12 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time )
|
|||
|
||||
resetLastError();
|
||||
|
||||
if (raw_image->isBufferInvalid())
|
||||
{
|
||||
setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
LLImageDataSharedLock lockIn(raw_image);
|
||||
LLImageDataLock lockOut(this);
|
||||
|
||||
|
|
|
|||
|
|
@ -897,6 +897,12 @@ bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod
|
|||
|
||||
bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible)
|
||||
{
|
||||
if (raw_image.isBufferInvalid())
|
||||
{
|
||||
base.setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
JPEG2KEncode encode(comment_text, reversible);
|
||||
bool encoded = encode.encode(raw_image, base);
|
||||
if (!encoded)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "llfoldertype.h"
|
||||
#include "lldictionary.h"
|
||||
#include "llmemory.h"
|
||||
#include "llsd.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
|
|
@ -220,3 +221,21 @@ const std::string &LLFolderType::badLookup()
|
|||
static const std::string sBadLookup = "llfoldertype_bad_lookup";
|
||||
return sBadLookup;
|
||||
}
|
||||
|
||||
LLSD LLFolderType::getTypeNames()
|
||||
{
|
||||
LLSD type_names;
|
||||
for (S32 type = FT_TEXTURE; type < FT_COUNT; ++type)
|
||||
{
|
||||
if (lookupIsEnsembleType((LLFolderType::EType)type))
|
||||
continue;
|
||||
|
||||
const FolderEntry* entry = LLFolderDictionary::getInstance()->lookup((LLFolderType::EType)type);
|
||||
// skip llfoldertype_bad_lookup
|
||||
if (entry)
|
||||
{
|
||||
type_names.append(entry->mName);
|
||||
}
|
||||
}
|
||||
return type_names;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ public:
|
|||
|
||||
static const std::string& badLookup(); // error string when a lookup fails
|
||||
|
||||
static LLSD getTypeNames();
|
||||
|
||||
protected:
|
||||
LLFolderType() {}
|
||||
~LLFolderType() {}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ static const std::string INV_ITEM_ID_LABEL("item_id");
|
|||
static const std::string INV_FOLDER_ID_LABEL("cat_id");
|
||||
static const std::string INV_PARENT_ID_LABEL("parent_id");
|
||||
static const std::string INV_THUMBNAIL_LABEL("thumbnail");
|
||||
static const std::string INV_FAVORITE_LABEL("favorite");
|
||||
static const std::string INV_THUMBNAIL_ID_LABEL("thumbnail_id");
|
||||
static const std::string INV_ASSET_TYPE_LABEL("type");
|
||||
static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type");
|
||||
|
|
@ -59,6 +60,7 @@ static const std::string INV_LINKED_ID_LABEL("linked_id");
|
|||
static const std::string INV_SALE_INFO_LABEL("sale_info");
|
||||
static const std::string INV_FLAGS_LABEL("flags");
|
||||
static const std::string INV_CREATION_DATE_LABEL("created_at");
|
||||
static const std::string INV_TOGGLED_LABEL("toggled");
|
||||
|
||||
// key used by agent-inventory-service
|
||||
static const std::string INV_ASSET_TYPE_LABEL_WS("type_default");
|
||||
|
|
@ -82,14 +84,16 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
|
|||
mParentUUID(parent_uuid),
|
||||
mType(type),
|
||||
mName(name),
|
||||
mCreationDate(0)
|
||||
mCreationDate(0),
|
||||
mFavorite(false)
|
||||
{
|
||||
correctInventoryName(mName);
|
||||
}
|
||||
|
||||
LLInventoryObject::LLInventoryObject()
|
||||
: mType(LLAssetType::AT_NONE),
|
||||
mCreationDate(0)
|
||||
mCreationDate(0),
|
||||
mFavorite(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +108,7 @@ void LLInventoryObject::copyObject(const LLInventoryObject* other)
|
|||
mType = other->mType;
|
||||
mName = other->mName;
|
||||
mThumbnailUUID = other->mThumbnailUUID;
|
||||
mFavorite = other->mFavorite;
|
||||
}
|
||||
|
||||
const LLUUID& LLInventoryObject::getUUID() const
|
||||
|
|
@ -121,6 +126,11 @@ const LLUUID& LLInventoryObject::getThumbnailUUID() const
|
|||
return mThumbnailUUID;
|
||||
}
|
||||
|
||||
bool LLInventoryObject::getIsFavorite() const
|
||||
{
|
||||
return mFavorite;
|
||||
}
|
||||
|
||||
const std::string& LLInventoryObject::getName() const
|
||||
{
|
||||
return mName;
|
||||
|
|
@ -175,6 +185,11 @@ void LLInventoryObject::setThumbnailUUID(const LLUUID& thumbnail_uuid)
|
|||
mThumbnailUUID = thumbnail_uuid;
|
||||
}
|
||||
|
||||
void LLInventoryObject::setFavorite(bool favorite)
|
||||
{
|
||||
mFavorite = favorite;
|
||||
}
|
||||
|
||||
void LLInventoryObject::setType(LLAssetType::EType type)
|
||||
{
|
||||
mType = type;
|
||||
|
|
@ -247,6 +262,23 @@ bool LLInventoryObject::importLegacyStream(std::istream& input_stream)
|
|||
{
|
||||
setThumbnailUUID(LLUUID::null);
|
||||
}
|
||||
|
||||
if (metadata.has("favorite"))
|
||||
{
|
||||
const LLSD& favorite = metadata["favorite"];
|
||||
if (favorite.has("toggled"))
|
||||
{
|
||||
setFavorite(favorite["toggled"].asBoolean());
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("name", keyword))
|
||||
{
|
||||
|
|
@ -735,6 +767,23 @@ bool LLInventoryItem::importLegacyStream(std::istream& input_stream)
|
|||
{
|
||||
setThumbnailUUID(LLUUID::null);
|
||||
}
|
||||
|
||||
if (metadata.has("favorite"))
|
||||
{
|
||||
const LLSD& favorite = metadata["favorite"];
|
||||
if (favorite.has("toggled"))
|
||||
{
|
||||
setFavorite(favorite["toggled"].asBoolean());
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else if(0 == strcmp("inv_type", keyword))
|
||||
{
|
||||
|
|
@ -879,7 +928,7 @@ bool LLInventoryItem::exportLegacyStream(std::ostream& output_stream, bool inclu
|
|||
|
||||
LLSD LLInventoryItem::asLLSD() const
|
||||
{
|
||||
LLSD sd = LLSD();
|
||||
LLSD sd;
|
||||
asLLSD(sd);
|
||||
return sd;
|
||||
}
|
||||
|
|
@ -888,13 +937,18 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
|
|||
{
|
||||
sd[INV_ITEM_ID_LABEL] = mUUID;
|
||||
sd[INV_PARENT_ID_LABEL] = mParentUUID;
|
||||
sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions);
|
||||
ll_fill_sd_from_permissions(sd[INV_PERMISSIONS_LABEL], mPermissions);
|
||||
|
||||
if (mThumbnailUUID.notNull())
|
||||
{
|
||||
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
if (mFavorite)
|
||||
{
|
||||
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
|
||||
U32 mask = mPermissions.getMaskBase();
|
||||
if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED)
|
||||
|| (mAssetUUID.isNull()))
|
||||
|
|
@ -909,19 +963,22 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
|
|||
cipher.encrypt(shadow_id.mData, UUID_BYTES);
|
||||
sd[INV_SHADOW_ID_LABEL] = shadow_id;
|
||||
}
|
||||
sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
|
||||
sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType;
|
||||
sd[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
|
||||
const std::string inv_type_str = LLInventoryType::lookup(mInventoryType);
|
||||
if(!inv_type_str.empty())
|
||||
{
|
||||
sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
sd[INV_INVENTORY_TYPE_LABEL] = (LLSD::Integer)mInventoryType;
|
||||
}
|
||||
//sd[INV_FLAGS_LABEL] = (S32)mFlags;
|
||||
sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags);
|
||||
sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD();
|
||||
mSaleInfo.asLLSD(sd[INV_SALE_INFO_LABEL]);
|
||||
sd[INV_NAME_LABEL] = mName;
|
||||
sd[INV_DESC_LABEL] = mDescription;
|
||||
sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate;
|
||||
sd[INV_CREATION_DATE_LABEL] = (LLSD::Integer)mCreationDate;
|
||||
}
|
||||
|
||||
bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
||||
|
|
@ -937,6 +994,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
|||
|
||||
// TODO - figure out if this should be moved into the noclobber fields above
|
||||
mThumbnailUUID.setNull();
|
||||
mFavorite = false;
|
||||
mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
|
||||
|
||||
// iterate as map to avoid making unnecessary temp copies of everything
|
||||
LLSD::map_const_iterator i, end;
|
||||
|
|
@ -982,9 +1041,20 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i->first == INV_FAVORITE_LABEL)
|
||||
{
|
||||
const LLSD& favorite_map = i->second;
|
||||
const std::string w = INV_TOGGLED_LABEL;
|
||||
if (favorite_map.has(w))
|
||||
{
|
||||
mFavorite = favorite_map[w].asBoolean();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i->first == INV_PERMISSIONS_LABEL)
|
||||
{
|
||||
mPermissions = ll_permissions_from_sd(i->second);
|
||||
mPermissions.importLLSD(i->second);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1177,6 +1247,11 @@ LLSD LLInventoryCategory::asLLSD() const
|
|||
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
if (mFavorite)
|
||||
{
|
||||
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
|
|
@ -1188,11 +1263,17 @@ LLSD LLInventoryCategory::asAISCreateCatLLSD() const
|
|||
S8 type = static_cast<S8>(mPreferredType);
|
||||
sd[INV_ASSET_TYPE_LABEL_WS] = type;
|
||||
sd[INV_NAME_LABEL] = mName;
|
||||
|
||||
if (mThumbnailUUID.notNull())
|
||||
{
|
||||
sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
if (mFavorite)
|
||||
{
|
||||
sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
|
|
@ -1240,6 +1321,17 @@ bool LLInventoryCategory::fromLLSD(const LLSD& sd)
|
|||
mThumbnailUUID = sd[w];
|
||||
}
|
||||
}
|
||||
mFavorite = false;
|
||||
w = INV_FAVORITE_LABEL;
|
||||
if (sd.has(w))
|
||||
{
|
||||
const LLSD& favorite_map = sd[w];
|
||||
w = INV_TOGGLED_LABEL;
|
||||
if (favorite_map.has(w))
|
||||
{
|
||||
mFavorite = favorite_map[w].asBoolean();
|
||||
}
|
||||
}
|
||||
w = INV_ASSET_TYPE_LABEL;
|
||||
if (sd.has(w))
|
||||
{
|
||||
|
|
@ -1362,6 +1454,23 @@ bool LLInventoryCategory::importLegacyStream(std::istream& input_stream)
|
|||
{
|
||||
setThumbnailUUID(LLUUID::null);
|
||||
}
|
||||
|
||||
if (metadata.has("favorite"))
|
||||
{
|
||||
const LLSD& favorite = metadata["favorite"];
|
||||
if (favorite.has("toggled"))
|
||||
{
|
||||
setFavorite(favorite["toggled"].asBoolean());
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setFavorite(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1396,12 +1505,11 @@ bool LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, bool)
|
|||
return true;
|
||||
}
|
||||
|
||||
LLSD LLInventoryCategory::exportLLSD() const
|
||||
void LLInventoryCategory::exportLLSD(LLSD& cat_data) const
|
||||
{
|
||||
LLSD cat_data;
|
||||
cat_data[INV_FOLDER_ID_LABEL] = mUUID;
|
||||
cat_data[INV_PARENT_ID_LABEL] = mParentUUID;
|
||||
cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType);
|
||||
cat_data[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType));
|
||||
cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType);
|
||||
cat_data[INV_NAME_LABEL] = mName;
|
||||
|
||||
|
|
@ -1409,49 +1517,76 @@ LLSD LLInventoryCategory::exportLLSD() const
|
|||
{
|
||||
cat_data[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID);
|
||||
}
|
||||
|
||||
return cat_data;
|
||||
if (mFavorite)
|
||||
{
|
||||
cat_data[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
|
||||
bool LLInventoryCategory::importLLSDMap(const LLSD& cat_data)
|
||||
{
|
||||
if (cat_data.has(INV_FOLDER_ID_LABEL))
|
||||
LLSD::map_const_iterator i, end;
|
||||
end = cat_data.endMap();
|
||||
for ( i = cat_data.beginMap(); i != end; ++i)
|
||||
{
|
||||
setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID());
|
||||
importLLSD(i->first, i->second);
|
||||
}
|
||||
if (cat_data.has(INV_PARENT_ID_LABEL))
|
||||
{
|
||||
setParent(cat_data[INV_PARENT_ID_LABEL].asUUID());
|
||||
}
|
||||
if (cat_data.has(INV_ASSET_TYPE_LABEL))
|
||||
{
|
||||
setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString()));
|
||||
}
|
||||
if (cat_data.has(INV_PREFERRED_TYPE_LABEL))
|
||||
{
|
||||
setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString()));
|
||||
}
|
||||
if (cat_data.has(INV_THUMBNAIL_LABEL))
|
||||
{
|
||||
LLUUID thumbnail_uuid;
|
||||
const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL];
|
||||
if (thumbnail_data.has(INV_ASSET_ID_LABEL))
|
||||
{
|
||||
thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID();
|
||||
}
|
||||
setThumbnailUUID(thumbnail_uuid);
|
||||
}
|
||||
if (cat_data.has(INV_NAME_LABEL))
|
||||
{
|
||||
mName = cat_data[INV_NAME_LABEL].asString();
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLInventoryCategory::importLLSD(const std::string& label, const LLSD& value)
|
||||
{
|
||||
if (label == INV_FOLDER_ID_LABEL)
|
||||
{
|
||||
setUUID(value.asUUID());
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_PARENT_ID_LABEL)
|
||||
{
|
||||
setParent(value.asUUID());
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_ASSET_TYPE_LABEL)
|
||||
{
|
||||
setType(LLAssetType::lookup(value.asString()));
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_PREFERRED_TYPE_LABEL)
|
||||
{
|
||||
setPreferredType(LLFolderType::lookup(value.asString()));
|
||||
return true;
|
||||
}
|
||||
else if (label == INV_THUMBNAIL_LABEL)
|
||||
{
|
||||
LLUUID thumbnail_uuid;
|
||||
if (value.has(INV_ASSET_ID_LABEL))
|
||||
{
|
||||
thumbnail_uuid = value[INV_ASSET_ID_LABEL].asUUID();
|
||||
}
|
||||
setThumbnailUUID(thumbnail_uuid);
|
||||
return true;
|
||||
}
|
||||
if (label == INV_FAVORITE_LABEL)
|
||||
{
|
||||
bool favorite = false;
|
||||
if (value.has(INV_TOGGLED_LABEL))
|
||||
{
|
||||
favorite = value[INV_TOGGLED_LABEL].asBoolean();
|
||||
}
|
||||
setFavorite(favorite);
|
||||
}
|
||||
else if (label == INV_NAME_LABEL)
|
||||
{
|
||||
mName = value.asString();
|
||||
LLStringUtil::replaceNonstandardASCII(mName, ' ');
|
||||
LLStringUtil::replaceChar(mName, '|', ' ');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function definitions
|
||||
/// Local function definitions for testing purposes
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public:
|
|||
virtual const LLUUID& getLinkedUUID() const; // inventoryID that this item points to, else this item's inventoryID
|
||||
const LLUUID& getParentUUID() const;
|
||||
virtual const LLUUID& getThumbnailUUID() const;
|
||||
virtual bool getIsFavorite() const;
|
||||
virtual const std::string& getName() const;
|
||||
virtual LLAssetType::EType getType() const;
|
||||
LLAssetType::EType getActualType() const; // bypasses indirection for linked items
|
||||
|
|
@ -86,6 +87,7 @@ public:
|
|||
virtual void rename(const std::string& new_name);
|
||||
void setParent(const LLUUID& new_parent);
|
||||
virtual void setThumbnailUUID(const LLUUID& thumbnail_uuid);
|
||||
virtual void setFavorite(bool favorite);
|
||||
void setType(LLAssetType::EType type);
|
||||
virtual void setCreationDate(time_t creation_date_utc); // only stored for items
|
||||
|
||||
|
|
@ -111,6 +113,7 @@ protected:
|
|||
LLUUID mUUID;
|
||||
LLUUID mParentUUID; // Parent category. Root categories have LLUUID::NULL.
|
||||
LLUUID mThumbnailUUID;
|
||||
bool mFavorite;
|
||||
LLAssetType::EType mType;
|
||||
std::string mName;
|
||||
time_t mCreationDate; // seconds from 1/1/1970, UTC
|
||||
|
|
@ -270,8 +273,9 @@ public:
|
|||
virtual bool importLegacyStream(std::istream& input_stream);
|
||||
virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const;
|
||||
|
||||
LLSD exportLLSD() const;
|
||||
bool importLLSD(const LLSD& cat_data);
|
||||
virtual void exportLLSD(LLSD& sd) const;
|
||||
bool importLLSDMap(const LLSD& cat_data);
|
||||
virtual bool importLLSD(const std::string& label, const LLSD& value);
|
||||
//--------------------------------------------------------------------
|
||||
// Member Variables
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -285,6 +289,7 @@ protected:
|
|||
//
|
||||
// These functions convert between structured data and an inventory
|
||||
// item, appropriate for serialization.
|
||||
// Not up to date (no favorites, nor thumbnails), for testing purposes
|
||||
//-----------------------------------------------------------------------------
|
||||
LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item);
|
||||
LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat);
|
||||
|
|
|
|||
|
|
@ -704,6 +704,79 @@ bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const
|
|||
return true;
|
||||
}
|
||||
|
||||
static const std::string PERM_CREATOR_ID_LABEL("creator_id");
|
||||
static const std::string PERM_OWNER_ID_LABEL("owner_id");
|
||||
static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
|
||||
static const std::string PERM_GROUP_ID_LABEL("group_id");
|
||||
static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
|
||||
static const std::string PERM_BASE_MASK_LABEL("base_mask");
|
||||
static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
|
||||
static const std::string PERM_GROUP_MASK_LABEL("group_mask");
|
||||
static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
|
||||
static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
|
||||
|
||||
void LLPermissions::importLLSD(const LLSD& sd_perm)
|
||||
{
|
||||
LLSD::map_const_iterator i, end;
|
||||
end = sd_perm.endMap();
|
||||
for (i = sd_perm.beginMap(); i != end; ++i)
|
||||
{
|
||||
const std::string& label = i->first;
|
||||
if (label == PERM_CREATOR_ID_LABEL)
|
||||
{
|
||||
mCreator = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_OWNER_ID_LABEL)
|
||||
{
|
||||
mOwner = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_LAST_OWNER_ID_LABEL)
|
||||
{
|
||||
mLastOwner = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_GROUP_ID_LABEL)
|
||||
{
|
||||
mGroup = i->second.asUUID();
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_BASE_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskBase = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_OWNER_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskOwner = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_EVERYONE_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskEveryone = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_GROUP_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskGroup = mask;
|
||||
continue;
|
||||
}
|
||||
if (label == PERM_NEXT_OWNER_MASK_LABEL)
|
||||
{
|
||||
PermissionMask mask = i->second.asInteger();
|
||||
mMaskNextOwner = mask;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fix();
|
||||
}
|
||||
|
||||
bool LLPermissions::operator==(const LLPermissions &rhs) const
|
||||
{
|
||||
return
|
||||
|
|
@ -998,55 +1071,30 @@ std::string mask_to_string(U32 mask)
|
|||
///----------------------------------------------------------------------------
|
||||
/// exported functions
|
||||
///----------------------------------------------------------------------------
|
||||
static const std::string PERM_CREATOR_ID_LABEL("creator_id");
|
||||
static const std::string PERM_OWNER_ID_LABEL("owner_id");
|
||||
static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id");
|
||||
static const std::string PERM_GROUP_ID_LABEL("group_id");
|
||||
static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group");
|
||||
static const std::string PERM_BASE_MASK_LABEL("base_mask");
|
||||
static const std::string PERM_OWNER_MASK_LABEL("owner_mask");
|
||||
static const std::string PERM_GROUP_MASK_LABEL("group_mask");
|
||||
static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask");
|
||||
static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask");
|
||||
|
||||
LLSD ll_create_sd_from_permissions(const LLPermissions& perm)
|
||||
{
|
||||
LLSD rv;
|
||||
ll_fill_sd_from_permissions(rv, perm);
|
||||
return rv;
|
||||
}
|
||||
void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm)
|
||||
{
|
||||
rv[PERM_CREATOR_ID_LABEL] = perm.getCreator();
|
||||
rv[PERM_OWNER_ID_LABEL] = perm.getOwner();
|
||||
rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner();
|
||||
rv[PERM_GROUP_ID_LABEL] = perm.getGroup();
|
||||
rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned();
|
||||
rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase();
|
||||
rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner();
|
||||
rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup();
|
||||
rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone();
|
||||
rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner();
|
||||
return rv;
|
||||
rv[PERM_BASE_MASK_LABEL] = (LLSD::Integer)perm.getMaskBase();
|
||||
rv[PERM_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskOwner();
|
||||
rv[PERM_GROUP_MASK_LABEL] = (LLSD::Integer)perm.getMaskGroup();
|
||||
rv[PERM_EVERYONE_MASK_LABEL] = (LLSD::Integer)perm.getMaskEveryone();
|
||||
rv[PERM_NEXT_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskNextOwner();
|
||||
}
|
||||
|
||||
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm)
|
||||
{
|
||||
LLPermissions rv;
|
||||
rv.init(
|
||||
sd_perm[PERM_CREATOR_ID_LABEL].asUUID(),
|
||||
sd_perm[PERM_OWNER_ID_LABEL].asUUID(),
|
||||
sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(),
|
||||
sd_perm[PERM_GROUP_ID_LABEL].asUUID());
|
||||
|
||||
// We do a cast to U32 here since LLSD does not attempt to
|
||||
// represent unsigned ints.
|
||||
PermissionMask mask;
|
||||
mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger());
|
||||
rv.setMaskBase(mask);
|
||||
mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger());
|
||||
rv.setMaskOwner(mask);
|
||||
mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger());
|
||||
rv.setMaskEveryone(mask);
|
||||
mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger());
|
||||
rv.setMaskGroup(mask);
|
||||
mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger());
|
||||
rv.setMaskNext(mask);
|
||||
rv.fix();
|
||||
rv.importLLSD(sd_perm);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -299,6 +299,8 @@ public:
|
|||
bool importLegacyStream(std::istream& input_stream);
|
||||
bool exportLegacyStream(std::ostream& output_stream) const;
|
||||
|
||||
void importLLSD(const LLSD& sd_perm);
|
||||
|
||||
bool operator==(const LLPermissions &rhs) const;
|
||||
bool operator!=(const LLPermissions &rhs) const;
|
||||
|
||||
|
|
@ -435,6 +437,7 @@ protected:
|
|||
// like 'creator_id', 'owner_id', etc, with the value copied from the
|
||||
// permission object.
|
||||
LLSD ll_create_sd_from_permissions(const LLPermissions& perm);
|
||||
void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm);
|
||||
LLPermissions ll_permissions_from_sd(const LLSD& sd_perm);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -90,15 +90,20 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
|
|||
LLSD LLSaleInfo::asLLSD() const
|
||||
{
|
||||
LLSD sd;
|
||||
asLLSD(sd);
|
||||
return sd;
|
||||
}
|
||||
|
||||
void LLSaleInfo::asLLSD(LLSD& sd) const
|
||||
{
|
||||
const char* type = lookup(mSaleType);
|
||||
if (!type)
|
||||
{
|
||||
LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL;
|
||||
type = lookup(LLSaleInfo::FS_NOT);
|
||||
}
|
||||
sd["sale_type"] = type;
|
||||
sd["sale_type"] = std::string(type);
|
||||
sd["sale_price"] = mSalePrice;
|
||||
return sd;
|
||||
}
|
||||
|
||||
bool LLSaleInfo::fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask)
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public:
|
|||
|
||||
bool exportLegacyStream(std::ostream& output_stream) const;
|
||||
LLSD asLLSD() const;
|
||||
void asLLSD(LLSD &sd) const;
|
||||
operator LLSD() const { return asLLSD(); }
|
||||
bool fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask);
|
||||
bool importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,34 @@
|
|||
#pragma warning(disable: 4702)
|
||||
#endif
|
||||
|
||||
void set_random_inventory_metadata(LLInventoryObject* obj)
|
||||
{
|
||||
S32 extra = rand() % 4;
|
||||
switch (extra)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
LLUUID thumbnail_id;
|
||||
thumbnail_id.generate();
|
||||
obj->setThumbnailUUID(thumbnail_id);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
obj->setFavorite(true);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
LLUUID thumbnail_id;
|
||||
thumbnail_id.generate();
|
||||
obj->setThumbnailUUID(thumbnail_id);
|
||||
obj->setFavorite(true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LLPointer<LLInventoryItem> create_random_inventory_item()
|
||||
{
|
||||
LLUUID item_id;
|
||||
|
|
@ -75,6 +103,7 @@ LLPointer<LLInventoryItem> create_random_inventory_item()
|
|||
sale_info,
|
||||
flags,
|
||||
creation);
|
||||
set_random_inventory_metadata(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +119,7 @@ LLPointer<LLInventoryCategory> create_random_inventory_cat()
|
|||
parent_id,
|
||||
LLFolderType::FT_NONE,
|
||||
std::string("Sample category"));
|
||||
set_random_inventory_metadata(cat);
|
||||
return cat;
|
||||
}
|
||||
|
||||
|
|
@ -290,6 +320,7 @@ namespace tut
|
|||
src->setCreationDate(new_creation);
|
||||
|
||||
// test a save/load cycle to LLSD and back again
|
||||
// Note: ll_create_sd_from_inventory_item does not support metadata
|
||||
LLSD sd = ll_create_sd_from_inventory_item(src);
|
||||
LLPointer<LLInventoryItem> dst = new LLInventoryItem;
|
||||
bool successful_parse = dst->fromLLSD(sd);
|
||||
|
|
@ -329,7 +360,9 @@ namespace tut
|
|||
}
|
||||
|
||||
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl;
|
||||
LLSD sd;
|
||||
src1->asLLSD(sd);
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
|
||||
fileXML.close();
|
||||
|
||||
|
||||
|
|
@ -364,13 +397,13 @@ namespace tut
|
|||
ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
|
||||
ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
|
||||
|
||||
ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void inventory_object::test<8>()
|
||||
{
|
||||
|
||||
LLPointer<LLInventoryItem> src1 = create_random_inventory_item();
|
||||
|
||||
std::ostringstream ostream;
|
||||
|
|
@ -390,8 +423,8 @@ namespace tut
|
|||
ensure_equals("8.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription());
|
||||
ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
|
||||
|
||||
|
||||
ensure_equals("11.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("12.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // not supposed to carry over
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
|
|
@ -421,6 +454,8 @@ namespace tut
|
|||
ensure_equals("10.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription());
|
||||
ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate());
|
||||
ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());
|
||||
}
|
||||
|
||||
//******class LLInventoryCategory*******//
|
||||
|
|
@ -458,7 +493,9 @@ namespace tut
|
|||
}
|
||||
|
||||
LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat();
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl;
|
||||
LLSD sd;
|
||||
src1->exportLLSD(sd);
|
||||
fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl;
|
||||
fileXML.close();
|
||||
|
||||
llifstream file(filename.c_str());
|
||||
|
|
@ -481,13 +518,15 @@ namespace tut
|
|||
file.close();
|
||||
|
||||
LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory();
|
||||
src2->importLLSD(s_item);
|
||||
src2->importLLSDMap(s_item);
|
||||
|
||||
ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID());
|
||||
ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID());
|
||||
ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
|
||||
ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
|
||||
ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
|
||||
ensure_equals("6.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("7.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite());
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
|
|
@ -507,6 +546,7 @@ namespace tut
|
|||
ensure_equals("3.type::getType() failed", src1->getType(), src2->getType());
|
||||
ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType());
|
||||
ensure_equals("5.name::getName() failed", src1->getName(), src2->getName());
|
||||
|
||||
ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID());
|
||||
ensure_equals("14.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // currently not supposed to carry over
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -662,6 +662,12 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co
|
|||
bool vflip = true;
|
||||
bool hflip = false;
|
||||
|
||||
if (raw_image.isBufferInvalid())
|
||||
{
|
||||
base.setLastError("Invalid input, no buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Set up input image files
|
||||
|
|
|
|||
|
|
@ -328,28 +328,30 @@ void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix)
|
|||
}
|
||||
|
||||
|
||||
// Rotate 2 normalized orthogonal vectors in direction from `source` to `target`
|
||||
static void rotate2(LLVector3& source, LLVector3& target, F32 angle)
|
||||
{
|
||||
F32 sx = source[VX], sy = source[VY], sz = source[VZ];
|
||||
F32 tx = target[VX], ty = target[VY], tz = target[VZ];
|
||||
F32 c = cosf(angle), s = sinf(angle);
|
||||
|
||||
source.set(sx * c + tx * s, sy * c + ty * s, sz * c + tz * s);
|
||||
target.set(tx * c - sx * s, ty * c - sy * s, tz * c - sz * s);
|
||||
}
|
||||
|
||||
void LLCoordFrame::roll(F32 angle)
|
||||
{
|
||||
LLQuaternion q(angle, mXAxis);
|
||||
LLMatrix3 rotation_matrix(q);
|
||||
rotate(rotation_matrix);
|
||||
CHECK_FINITE_OBJ();
|
||||
rotate2(mYAxis, mZAxis, angle);
|
||||
}
|
||||
|
||||
void LLCoordFrame::pitch(F32 angle)
|
||||
{
|
||||
LLQuaternion q(angle, mYAxis);
|
||||
LLMatrix3 rotation_matrix(q);
|
||||
rotate(rotation_matrix);
|
||||
CHECK_FINITE_OBJ();
|
||||
rotate2(mZAxis, mXAxis, angle);
|
||||
}
|
||||
|
||||
void LLCoordFrame::yaw(F32 angle)
|
||||
{
|
||||
LLQuaternion q(angle, mZAxis);
|
||||
LLMatrix3 rotation_matrix(q);
|
||||
rotate(rotation_matrix);
|
||||
CHECK_FINITE_OBJ();
|
||||
rotate2(mXAxis, mYAxis, angle);
|
||||
}
|
||||
|
||||
// get*() routines
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ constexpr F32 DEG_TO_RAD = 0.017453292519943295769236907684886f;
|
|||
constexpr F32 RAD_TO_DEG = 57.295779513082320876798154814105f;
|
||||
constexpr F32 F_APPROXIMATELY_ZERO = 0.00001f;
|
||||
constexpr F32 F_LN10 = 2.3025850929940456840179914546844f;
|
||||
constexpr F32 OO_LN10 = 0.43429448190325182765112891891661;
|
||||
constexpr F32 OO_LN10 = 0.43429448190325182765112891891661f;
|
||||
constexpr F32 F_LN2 = 0.69314718056f;
|
||||
constexpr F32 OO_LN2 = 1.4426950408889634073599246810019f;
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ LLQuaternion::LLQuaternion(const LLMatrix3 &mat)
|
|||
|
||||
LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec)
|
||||
{
|
||||
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
|
||||
F32 mag = vec.length();
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
angle *= 0.5;
|
||||
|
|
@ -76,7 +76,7 @@ LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec)
|
|||
|
||||
LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec)
|
||||
{
|
||||
F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]);
|
||||
F32 mag = vec.length();
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
angle *= 0.5;
|
||||
|
|
|
|||
|
|
@ -5710,9 +5710,17 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents)
|
|||
|
||||
S32 vert_count = 0;
|
||||
if (!data.p.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count));
|
||||
}
|
||||
catch (std::bad_alloc&)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showOutOfMemory();
|
||||
LL_ERRS("LLCoros") << "Failed to allocate memory for VertexRemap: " << (S32)data.p.size() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if (vert_count < 65535 && vert_count != 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ F32 angle_between(const LLVector2& a, const LLVector2& b)
|
|||
return angle;
|
||||
}
|
||||
|
||||
F32 signed_angle_between(const LLVector2& a, const LLVector2& b)
|
||||
{
|
||||
F32 angle = angle_between(a, b);
|
||||
F32 rhombus_square = a[VX] * b[VY] - b[VX] * a[VY];
|
||||
return rhombus_square < 0 ? -angle : angle;
|
||||
}
|
||||
|
||||
bool are_parallel(const LLVector2& a, const LLVector2& b, F32 epsilon)
|
||||
{
|
||||
LLVector2 an = a;
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ class LLVector2
|
|||
// Non-member functions
|
||||
|
||||
F32 angle_between(const LLVector2& a, const LLVector2& b); // Returns angle (radians) between a and b
|
||||
F32 signed_angle_between(const LLVector2& a, const LLVector2& b); // Returns signed angle (radians) between a and b
|
||||
bool are_parallel(const LLVector2& a, const LLVector2& b, F32 epsilon = F_APPROXIMATELY_ZERO); // Returns true if a and b are very close to parallel
|
||||
F32 dist_vec(const LLVector2& a, const LLVector2& b); // Returns distance between a and b
|
||||
F32 dist_vec_squared(const LLVector2& a, const LLVector2& b);// Returns distance squared between a and b
|
||||
|
|
@ -124,26 +125,22 @@ LLVector2 lerp(const LLVector2& a, const LLVector2& b, F32 u); // Returns a vect
|
|||
|
||||
inline LLVector2::LLVector2()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(F32 x, F32 y)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
set(x, y);
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(const LLVector3 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
set(vec.mV);
|
||||
}
|
||||
|
||||
inline LLVector2::LLVector2(const LLSD &sd)
|
||||
|
|
@ -155,28 +152,24 @@ inline LLVector2::LLVector2(const LLSD &sd)
|
|||
|
||||
inline void LLVector2::clear()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VX] = mV[VY] = 0.f;
|
||||
}
|
||||
|
||||
inline void LLVector2::setZero()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::clearVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::zeroVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector2::set(F32 x, F32 y)
|
||||
|
|
@ -187,36 +180,31 @@ inline void LLVector2::set(F32 x, F32 y)
|
|||
|
||||
inline void LLVector2::set(const LLVector2 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
set(vec.mV);
|
||||
}
|
||||
|
||||
inline void LLVector2::set(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
set(vec[VX], vec[VY]);
|
||||
}
|
||||
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::setVec(F32 x, F32 y)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
set(x, y);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::setVec(const LLVector2 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector2::setVec(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -224,7 +212,7 @@ inline void LLVector2::setVec(const F32 *vec)
|
|||
|
||||
inline F32 LLVector2::length() const
|
||||
{
|
||||
return sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY]);
|
||||
return sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
inline F32 LLVector2::lengthSquared() const
|
||||
|
|
@ -234,61 +222,42 @@ inline F32 LLVector2::lengthSquared() const
|
|||
|
||||
inline F32 LLVector2::normalize()
|
||||
{
|
||||
F32 mag = sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY]);
|
||||
F32 oomag;
|
||||
F32 mag = length();
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
*this /= mag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
clear();
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// checker
|
||||
inline bool LLVector2::isFinite() const
|
||||
{
|
||||
return (llfinite(mV[VX]) && llfinite(mV[VY]));
|
||||
return llfinite(mV[VX]) && llfinite(mV[VY]);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector2::magVec() const
|
||||
{
|
||||
return sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY]);
|
||||
return length();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector2::magVecSquared() const
|
||||
{
|
||||
return mV[VX]*mV[VX] + mV[VY]*mV[VY];
|
||||
return lengthSquared();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector2::normVec()
|
||||
{
|
||||
F32 mag = sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return normalize();
|
||||
}
|
||||
|
||||
inline const LLVector2& LLVector2::scaleVec(const LLVector2& vec)
|
||||
|
|
@ -301,11 +270,7 @@ inline const LLVector2& LLVector2::scaleVec(const LLVector2& vec)
|
|||
|
||||
inline bool LLVector2::isNull() const
|
||||
{
|
||||
if (F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -405,10 +370,7 @@ inline const LLVector2& operator*=(LLVector2& a, F32 k)
|
|||
|
||||
inline const LLVector2& operator/=(LLVector2& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
a.mV[VX] *= t;
|
||||
a.mV[VY] *= t;
|
||||
return a;
|
||||
return a *= 1.f / k;
|
||||
}
|
||||
|
||||
inline LLVector2 operator-(const LLVector2& a)
|
||||
|
|
|
|||
|
|
@ -183,23 +183,17 @@ bool box_valid_and_non_zero(const LLVector3* box);
|
|||
|
||||
inline LLVector3::LLVector3()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
inline LLVector3::LLVector3(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline LLVector3::LLVector3(const glm::vec3& vec)
|
||||
|
|
@ -230,7 +224,7 @@ inline LLVector3::LLVector3(const LLVector3 ©)
|
|||
// checker
|
||||
inline bool LLVector3::isFinite() const
|
||||
{
|
||||
return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]));
|
||||
return llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -238,30 +232,22 @@ inline bool LLVector3::isFinite() const
|
|||
|
||||
inline void LLVector3::clear()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
set(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
inline void LLVector3::setZero()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector3::clearVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector3::zeroVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void LLVector3::set(F32 x, F32 y, F32 z)
|
||||
|
|
@ -273,16 +259,12 @@ inline void LLVector3::set(F32 x, F32 y, F32 z)
|
|||
|
||||
inline void LLVector3::set(const LLVector3& vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
set(vec.mV[VX], vec.mV[VY], vec.mV[VZ]);
|
||||
}
|
||||
|
||||
inline void LLVector3::set(const F32* vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
set(vec[VX], vec[VY], vec[VZ]);
|
||||
}
|
||||
|
||||
inline void LLVector3::set(const glm::vec4& vec)
|
||||
|
|
@ -302,77 +284,48 @@ inline void LLVector3::set(const glm::vec3& vec)
|
|||
// deprecated
|
||||
inline void LLVector3::setVec(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector3::setVec(const LLVector3& vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector3::setVec(const F32* vec)
|
||||
{
|
||||
mV[VX] = vec[0];
|
||||
mV[VY] = vec[1];
|
||||
mV[VZ] = vec[2];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline F32 LLVector3::normalize()
|
||||
{
|
||||
F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
mV[VZ] *= oomag;
|
||||
*this /= mag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
clear();
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector3::normVec()
|
||||
{
|
||||
F32 mag = sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
mV[VZ] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mag = 0;
|
||||
}
|
||||
return (mag);
|
||||
return normalize();
|
||||
}
|
||||
|
||||
// LLVector3 Magnitude and Normalization Functions
|
||||
|
||||
inline F32 LLVector3::length() const
|
||||
{
|
||||
return sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
return sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
inline F32 LLVector3::lengthSquared() const
|
||||
|
|
@ -382,12 +335,12 @@ inline F32 LLVector3::lengthSquared() const
|
|||
|
||||
inline F32 LLVector3::magVec() const
|
||||
{
|
||||
return sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
return length();
|
||||
}
|
||||
|
||||
inline F32 LLVector3::magVecSquared() const
|
||||
{
|
||||
return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
|
||||
return lengthSquared();
|
||||
}
|
||||
|
||||
inline bool LLVector3::inRange(F32 min, F32 max) const
|
||||
|
|
@ -499,9 +452,7 @@ inline const LLVector3& operator*=(LLVector3& a, const LLVector3& b)
|
|||
|
||||
inline const LLVector3& operator/=(LLVector3& a, F32 k)
|
||||
{
|
||||
a.mV[VX] /= k;
|
||||
a.mV[VY] /= k;
|
||||
a.mV[VZ] /= k;
|
||||
a *= 1.f / k;
|
||||
return a;
|
||||
}
|
||||
|
||||
|
|
@ -551,11 +502,8 @@ inline LLVector3 projected_vec(const LLVector3& a, const LLVector3& b)
|
|||
{
|
||||
return ((a * b) / bb) * b;
|
||||
}
|
||||
else
|
||||
{
|
||||
return b.zero;
|
||||
}
|
||||
}
|
||||
|
||||
inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
|
|
@ -591,11 +539,7 @@ inline LLVector3 lerp(const LLVector3& a, const LLVector3& b, F32 u)
|
|||
|
||||
inline bool LLVector3::isNull() const
|
||||
{
|
||||
if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
|
||||
}
|
||||
|
||||
inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
|
||||
|
|
@ -636,7 +580,7 @@ inline F32 angle_between(const LLVector3& a, const LLVector3& b)
|
|||
ab = 0.0f; // get rid of negative zero
|
||||
}
|
||||
LLVector3 c = a % b; // crossproduct
|
||||
return atan2f(sqrtf(c * c), ab); // return the angle
|
||||
return atan2f(c.length(), ab); // return the angle
|
||||
}
|
||||
|
||||
inline bool are_parallel(const LLVector3& a, const LLVector3& b, F32 epsilon)
|
||||
|
|
@ -646,7 +590,7 @@ inline bool are_parallel(const LLVector3& a, const LLVector3& b, F32 epsilon)
|
|||
an.normalize();
|
||||
bn.normalize();
|
||||
F32 dot = an * bn;
|
||||
if ( (1.0f - fabs(dot)) < epsilon)
|
||||
if (1.0f - fabs(dot) < epsilon)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,34 +159,22 @@ LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u); // Returns a vect
|
|||
|
||||
inline LLVector4::LLVector4(void)
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 1.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = 1.f;
|
||||
set(x, y, z, 1.f);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(F32 x, F32 y, F32 z, F32 w)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = w;
|
||||
set(x, y, z, w);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const F32 *vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
mV[VW] = vec[VW];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const F64 *vec)
|
||||
|
|
@ -215,18 +203,12 @@ inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w)
|
|||
|
||||
inline LLVector4::LLVector4(const LLVector3 &vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = 1.f;
|
||||
set(vec, 1.f);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = w;
|
||||
set(vec, w);
|
||||
}
|
||||
|
||||
inline LLVector4::LLVector4(const LLSD &sd)
|
||||
|
|
@ -252,43 +234,31 @@ inline LLVector4::LLVector4(const glm::vec4& vec)
|
|||
|
||||
inline bool LLVector4::isFinite() const
|
||||
{
|
||||
return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]));
|
||||
return llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]);
|
||||
}
|
||||
|
||||
// Clear and Assignment Functions
|
||||
|
||||
inline void LLVector4::clear()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 1.f;
|
||||
set(0.f, 0.f, 0.f, 1.f);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::clearVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 1.f;
|
||||
clear();
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::zeroVec()
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mV[VW] = 0.f;
|
||||
set(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
inline void LLVector4::set(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = 1.f;
|
||||
set(x, y, z, 1.f);
|
||||
}
|
||||
|
||||
inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w)
|
||||
|
|
@ -301,10 +271,7 @@ inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w)
|
|||
|
||||
inline void LLVector4::set(const LLVector4& vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = vec.mV[VW];
|
||||
set(vec.mV);
|
||||
}
|
||||
|
||||
inline void LLVector4::set(const LLVector3& vec, F32 w)
|
||||
|
|
@ -322,7 +289,6 @@ inline void LLVector4::set(const F32* vec)
|
|||
mV[VZ] = vec[VZ];
|
||||
mV[VW] = vec[VW];
|
||||
}
|
||||
|
||||
inline void LLVector4::set(const glm::vec4& vec)
|
||||
{
|
||||
mV[VX] = vec.x;
|
||||
|
|
@ -342,53 +308,38 @@ inline void LLVector4::set(const glm::vec3& vec, F32 w)
|
|||
// deprecated
|
||||
inline void LLVector4::setVec(F32 x, F32 y, F32 z)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = 1.f;
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(F32 x, F32 y, F32 z, F32 w)
|
||||
{
|
||||
mV[VX] = x;
|
||||
mV[VY] = y;
|
||||
mV[VZ] = z;
|
||||
mV[VW] = w;
|
||||
set(x, y, z, w);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(const LLVector4& vec)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = vec.mV[VW];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(const LLVector3& vec, F32 w)
|
||||
{
|
||||
mV[VX] = vec.mV[VX];
|
||||
mV[VY] = vec.mV[VY];
|
||||
mV[VZ] = vec.mV[VZ];
|
||||
mV[VW] = w;
|
||||
set(vec, w);
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline void LLVector4::setVec(const F32* vec)
|
||||
{
|
||||
mV[VX] = vec[VX];
|
||||
mV[VY] = vec[VY];
|
||||
mV[VZ] = vec[VZ];
|
||||
mV[VW] = vec[VW];
|
||||
set(vec);
|
||||
}
|
||||
|
||||
// LLVector4 Magnitude and Normalization Functions
|
||||
|
||||
inline F32 LLVector4::length() const
|
||||
{
|
||||
return sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
return sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
inline F32 LLVector4::lengthSquared() const
|
||||
|
|
@ -398,12 +349,12 @@ inline F32 LLVector4::lengthSquared() const
|
|||
|
||||
inline F32 LLVector4::magVec() const
|
||||
{
|
||||
return sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
return length();
|
||||
}
|
||||
|
||||
inline F32 LLVector4::magVecSquared() const
|
||||
{
|
||||
return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ];
|
||||
return lengthSquared();
|
||||
}
|
||||
|
||||
// LLVector4 Operators
|
||||
|
|
@ -422,7 +373,7 @@ inline LLVector4 operator-(const LLVector4& a, const LLVector4& b)
|
|||
|
||||
inline F32 operator*(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]);
|
||||
return a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ];
|
||||
}
|
||||
|
||||
inline LLVector4 operator%(const LLVector4& a, const LLVector4& b)
|
||||
|
|
@ -495,11 +446,7 @@ inline const LLVector4& operator*=(LLVector4& a, F32 k)
|
|||
|
||||
inline const LLVector4& operator/=(LLVector4& a, F32 k)
|
||||
{
|
||||
F32 t = 1.f / k;
|
||||
a.mV[VX] *= t;
|
||||
a.mV[VY] *= t;
|
||||
a.mV[VZ] *= t;
|
||||
return a;
|
||||
return a *= 1.f / k;
|
||||
}
|
||||
|
||||
inline LLVector4 operator-(const LLVector4& a)
|
||||
|
|
@ -520,13 +467,13 @@ inline LLVector4::operator glm::vec4() const
|
|||
inline F32 dist_vec(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
LLVector4 vec = a - b;
|
||||
return (vec.length());
|
||||
return vec.length();
|
||||
}
|
||||
|
||||
inline F32 dist_vec_squared(const LLVector4& a, const LLVector4& b)
|
||||
{
|
||||
LLVector4 vec = a - b;
|
||||
return (vec.lengthSquared());
|
||||
return vec.lengthSquared();
|
||||
}
|
||||
|
||||
inline LLVector4 lerp(const LLVector4& a, const LLVector4& b, F32 u)
|
||||
|
|
@ -541,14 +488,10 @@ inline LLVector4 lerp(const LLVector4& a, const LLVector4& b, F32 u)
|
|||
inline F32 LLVector4::normalize()
|
||||
{
|
||||
F32 mag = sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
mV[VZ] *= oomag;
|
||||
*this /= mag;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -557,30 +500,13 @@ inline F32 LLVector4::normalize()
|
|||
mV[VZ] = 0.f;
|
||||
mag = 0.f;
|
||||
}
|
||||
return (mag);
|
||||
return mag;
|
||||
}
|
||||
|
||||
// deprecated
|
||||
inline F32 LLVector4::normVec()
|
||||
{
|
||||
F32 mag = sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]);
|
||||
F32 oomag;
|
||||
|
||||
if (mag > FP_MAG_THRESHOLD)
|
||||
{
|
||||
oomag = 1.f/mag;
|
||||
mV[VX] *= oomag;
|
||||
mV[VY] *= oomag;
|
||||
mV[VZ] *= oomag;
|
||||
}
|
||||
else
|
||||
{
|
||||
mV[VX] = 0.f;
|
||||
mV[VY] = 0.f;
|
||||
mV[VZ] = 0.f;
|
||||
mag = 0.f;
|
||||
}
|
||||
return (mag);
|
||||
return normalize();
|
||||
}
|
||||
|
||||
// Because apparently some parts of the viewer use this for color info.
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static const U32 DEFAULT_POOL_SIZE = 5;
|
|||
// SL-14399: When we teleport to a brand-new simulator, the coprocedure queue
|
||||
// gets absolutely slammed with fetch requests. Make this queue effectively
|
||||
// unlimited.
|
||||
const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*1024;
|
||||
const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*512;
|
||||
|
||||
//=========================================================================
|
||||
class LLCoprocedurePool: private boost::noncopyable
|
||||
|
|
@ -58,7 +58,7 @@ class LLCoprocedurePool: private boost::noncopyable
|
|||
public:
|
||||
typedef LLCoprocedureManager::CoProcedure_t CoProcedure_t;
|
||||
|
||||
LLCoprocedurePool(const std::string &name, size_t size);
|
||||
LLCoprocedurePool(const std::string &name, size_t size, size_t queue_size);
|
||||
~LLCoprocedurePool();
|
||||
|
||||
/// Places the coprocedure on the queue for processing.
|
||||
|
|
@ -118,7 +118,7 @@ private:
|
|||
typedef std::shared_ptr<CoprocQueue_t> CoprocQueuePtr;
|
||||
|
||||
std::string mPoolName;
|
||||
size_t mPoolSize, mActiveCoprocsCount, mPending;
|
||||
size_t mPoolSize, mQueueSize, mActiveCoprocsCount, mPending;
|
||||
CoprocQueuePtr mPendingCoprocs;
|
||||
LLTempBoundListener mStatusListener;
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ LLCoprocedureManager::~LLCoprocedureManager()
|
|||
close();
|
||||
}
|
||||
|
||||
void LLCoprocedureManager::initializePool(const std::string &poolName)
|
||||
void LLCoprocedureManager::initializePool(const std::string &poolName, size_t queue_size)
|
||||
{
|
||||
poolMap_t::iterator it = mPoolMap.find(poolName);
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ void LLCoprocedureManager::initializePool(const std::string &poolName)
|
|||
LL_WARNS("CoProcMgr") << "LLCoprocedureManager: No setting for \"" << keyName << "\" setting pool size to default of " << size << LL_ENDL;
|
||||
}
|
||||
|
||||
poolPtr_t pool(new LLCoprocedurePool(poolName, size));
|
||||
poolPtr_t pool(new LLCoprocedurePool(poolName, size, queue_size));
|
||||
LL_ERRS_IF(!pool, "CoprocedureManager") << "Unable to create pool named \"" << poolName << "\" FATAL!" << LL_ENDL;
|
||||
|
||||
bool inserted = mPoolMap.emplace(poolName, pool).second;
|
||||
|
|
@ -212,7 +212,8 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd
|
|||
mPropertyQueryFn = queryfn;
|
||||
mPropertyDefineFn = updatefn;
|
||||
|
||||
initializePool("Upload");
|
||||
constexpr size_t UPLOAD_QUEUE_SIZE = 2048;
|
||||
initializePool("Upload", UPLOAD_QUEUE_SIZE);
|
||||
initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS
|
||||
// "ExpCache" pool gets initialized in LLExperienceCache
|
||||
// asset storage pool gets initialized in LLViewerAssetStorage
|
||||
|
|
@ -296,17 +297,19 @@ void LLCoprocedureManager::close(const std::string &pool)
|
|||
}
|
||||
|
||||
//=========================================================================
|
||||
LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
|
||||
LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size, size_t queue_size):
|
||||
mPoolName(poolName),
|
||||
mPoolSize(size),
|
||||
mQueueSize(queue_size),
|
||||
mActiveCoprocsCount(0),
|
||||
mPending(0),
|
||||
mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
|
||||
mCoroMapping()
|
||||
{
|
||||
llassert_always(mQueueSize > mPoolSize); // queue should be able to fit pool
|
||||
try
|
||||
{
|
||||
mPendingCoprocs = std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE);
|
||||
mPendingCoprocs = std::make_shared<CoprocQueue_t>(mQueueSize);
|
||||
// store in our LLTempBoundListener so that when the LLCoprocedurePool is
|
||||
// destroyed, we implicitly disconnect from this LLEventPump
|
||||
// Monitores application status
|
||||
|
|
@ -357,7 +360,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
|
|||
mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter));
|
||||
}
|
||||
|
||||
LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL;
|
||||
LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << mQueueSize << LL_ENDL;
|
||||
}
|
||||
|
||||
LLCoprocedurePool::~LLCoprocedurePool()
|
||||
|
|
@ -376,7 +379,7 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced
|
|||
<< "\" at "
|
||||
<< mPending << LL_ENDL;
|
||||
|
||||
if (mPending >= (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1))
|
||||
if (mPending >= (mQueueSize - 1))
|
||||
{
|
||||
// If it's all used up (not supposed to happen,
|
||||
// fetched should cap it), we are going to crash
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ public:
|
|||
void close();
|
||||
void close(const std::string &pool);
|
||||
|
||||
void initializePool(const std::string &poolName);
|
||||
void initializePool(const std::string &poolName, size_t queue_size = DEFAULT_QUEUE_SIZE);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ void LLExperienceCache::initSingleton()
|
|||
cache_stream >> (*this);
|
||||
}
|
||||
|
||||
LLCoprocedureManager::instance().initializePool("ExpCache");
|
||||
constexpr size_t CORO_QUEUE_SIZE = 2048;
|
||||
LLCoprocedureManager::instance().initializePool("ExpCache", CORO_QUEUE_SIZE);
|
||||
|
||||
LLCoros::instance().launch("LLExperienceCache::idleCoro",
|
||||
boost::bind(&LLExperienceCache::idleCoro, this));
|
||||
|
|
|
|||
|
|
@ -66,7 +66,12 @@ LLModel::~LLModel()
|
|||
{
|
||||
if (mDecompID >= 0)
|
||||
{
|
||||
LLConvexDecomposition::getInstance()->deleteDecomposition(mDecompID);
|
||||
// can be null on shutdown
|
||||
LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance();
|
||||
if (decomp)
|
||||
{
|
||||
decomp->deleteDecomposition(mDecompID);
|
||||
}
|
||||
}
|
||||
mPhysics.mMesh.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -492,22 +492,6 @@ U32 LLRenderTarget::getNumTextures() const
|
|||
void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options)
|
||||
{
|
||||
gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index), filter_options == LLTexUnit::TFO_TRILINEAR || filter_options == LLTexUnit::TFO_ANISOTROPIC);
|
||||
|
||||
bool isSRGB = false;
|
||||
llassert(mInternalFormat.size() > index);
|
||||
switch (mInternalFormat[index])
|
||||
{
|
||||
case GL_SRGB:
|
||||
case GL_SRGB8:
|
||||
case GL_SRGB_ALPHA:
|
||||
case GL_SRGB8_ALPHA8:
|
||||
isSRGB = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gGL.getTexUnit(channel)->setTextureFilteringOption(filter_options);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ public:
|
|||
S32 notify(const LLSD& info);
|
||||
bool notifyChildren(const LLSD& info);
|
||||
|
||||
void draw();
|
||||
virtual void draw();
|
||||
|
||||
void storeOpenCloseState();
|
||||
void restoreOpenCloseState();
|
||||
|
|
|
|||
|
|
@ -1346,9 +1346,17 @@ bool LLFlatListViewEx::getForceShowingUnmatchedItems() const
|
|||
return mForceShowingUnmatchedItems;
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show)
|
||||
void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show, bool notify_parent)
|
||||
{
|
||||
if (mForceShowingUnmatchedItems != show)
|
||||
{
|
||||
mForceShowingUnmatchedItems = show;
|
||||
if (!mFilterSubString.empty())
|
||||
{
|
||||
updateNoItemsMessage(mFilterSubString);
|
||||
filterItems(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::setFilterSubString(const std::string& filter_str, bool notify_parent)
|
||||
|
|
@ -1416,6 +1424,7 @@ void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent)
|
|||
|
||||
if (visibility_changed && notify_parent)
|
||||
{
|
||||
rearrangeItems();
|
||||
notifyParentItemsRectChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -484,7 +484,11 @@ public:
|
|||
|
||||
bool getForceShowingUnmatchedItems() const;
|
||||
|
||||
void setForceShowingUnmatchedItems(bool show);
|
||||
/**
|
||||
* Sets filtered out items to stay visible. Can result in rect changes,
|
||||
* so can notify_parent if rect changes
|
||||
*/
|
||||
void setForceShowingUnmatchedItems(bool show, bool notify_parent);
|
||||
|
||||
/**
|
||||
* Sets up new filter string and filters the list.
|
||||
|
|
|
|||
|
|
@ -221,6 +221,7 @@ public:
|
|||
void scrollToShowSelection();
|
||||
void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
|
||||
void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; }
|
||||
LLScrollContainer* getScrollContainer() { return mScrollContainer; }
|
||||
LLRect getVisibleRect();
|
||||
|
||||
bool search(LLFolderViewItem* first_item, const std::string &search_string, bool backward);
|
||||
|
|
|
|||
|
|
@ -31,11 +31,12 @@
|
|||
#include "llfolderviewitem.h"
|
||||
#include "llfolderview.h"
|
||||
#include "llfolderviewmodel.h"
|
||||
#include "llpanel.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llcriticaldamp.h"
|
||||
#include "llclipboard.h"
|
||||
#include "llfocusmgr.h" // gFocusMgr
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanel.h"
|
||||
#include "lltrans.h"
|
||||
#include "llwindow.h"
|
||||
|
||||
|
|
@ -60,7 +61,11 @@ LLUIColor LLFolderViewItem::sSearchStatusColor;
|
|||
S32 LLFolderViewItem::sTopPad = 0;
|
||||
LLUIImagePtr LLFolderViewItem::sFolderArrowImg;
|
||||
LLUIImagePtr LLFolderViewItem::sSelectionImg;
|
||||
LLUIImagePtr LLFolderViewItem::sFavoriteImg;
|
||||
LLUIImagePtr LLFolderViewItem::sFavoriteContentImg;
|
||||
LLFontGL* LLFolderViewItem::sSuffixFont = nullptr;
|
||||
LLUIColor LLFolderViewItem::sFavoriteColor;
|
||||
bool LLFolderViewItem::sColorSetInitialized = false;
|
||||
|
||||
// only integers can be initialized in header
|
||||
const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
|
||||
|
|
@ -68,6 +73,9 @@ const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
|
|||
|
||||
const LLColor4U DEFAULT_WHITE(255, 255, 255);
|
||||
|
||||
constexpr S32 FAVORITE_IMAGE_SIZE = 14;
|
||||
constexpr S32 FAVORITE_IMAGE_PAD = 3;
|
||||
|
||||
|
||||
//static
|
||||
LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
|
||||
|
|
@ -102,6 +110,8 @@ void LLFolderViewItem::initClass()
|
|||
sTopPad = default_params.item_top_pad;
|
||||
sFolderArrowImg = default_params.folder_arrow_image;
|
||||
sSelectionImg = default_params.selection_image;
|
||||
sFavoriteImg = default_params.favorite_image;
|
||||
sFavoriteContentImg = default_params.favorite_content_image;
|
||||
sSuffixFont = getLabelFontForStyle(LLFontGL::NORMAL);
|
||||
|
||||
sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
|
||||
|
|
@ -121,6 +131,8 @@ void LLFolderViewItem::cleanupClass()
|
|||
sFonts.clear();
|
||||
sFolderArrowImg = nullptr;
|
||||
sSelectionImg = nullptr;
|
||||
sFavoriteImg = nullptr;
|
||||
sFavoriteContentImg = nullptr;
|
||||
sSuffixFont = nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -129,13 +141,15 @@ void LLFolderViewItem::cleanupClass()
|
|||
LLFolderViewItem::Params::Params()
|
||||
: root(),
|
||||
listener(),
|
||||
favorite_image("favorite_image"),
|
||||
favorite_content_image("favorite_content_image"),
|
||||
folder_arrow_image("folder_arrow_image"),
|
||||
folder_indentation("folder_indentation"),
|
||||
selection_image("selection_image"),
|
||||
item_height("item_height"),
|
||||
item_top_pad("item_top_pad"),
|
||||
creation_date(),
|
||||
allow_wear("allow_wear", true),
|
||||
marketplace_item("marketplace_item", false),
|
||||
allow_drop("allow_drop", true),
|
||||
font_color("font_color"),
|
||||
font_highlight_color("font_highlight_color"),
|
||||
|
|
@ -155,6 +169,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
: LLView(p),
|
||||
mLabelWidth(0),
|
||||
mLabelWidthDirty(false),
|
||||
mIsFavorite(false),
|
||||
mHasFavorites(false),
|
||||
mSuffixNeedsRefresh(false),
|
||||
mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
|
||||
mParentFolder( NULL ),
|
||||
|
|
@ -175,7 +191,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
mRoot(p.root),
|
||||
mViewModelItem(p.listener),
|
||||
mIsMouseOverTitle(false),
|
||||
mAllowWear(p.allow_wear),
|
||||
mMarketplaceItem(p.marketplace_item),
|
||||
mAllowDrop(p.allow_drop),
|
||||
mFontColor(p.font_color),
|
||||
mFontHighlightColor(p.font_highlight_color),
|
||||
|
|
@ -189,6 +205,21 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
|
|||
mMaxFolderItemOverlap(p.max_folder_item_overlap),
|
||||
mDoubleClickOverride(p.double_click_override)
|
||||
{
|
||||
if (!sColorSetInitialized)
|
||||
{
|
||||
sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
|
||||
sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
|
||||
sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
|
||||
sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
|
||||
sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
|
||||
sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
|
||||
sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
|
||||
sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
|
||||
sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
|
||||
sFavoriteColor = LLUIColorTable::instance().getColor("InventoryFavoriteColor", DEFAULT_WHITE);
|
||||
sColorSetInitialized = true;
|
||||
}
|
||||
|
||||
if (mViewModelItem)
|
||||
{
|
||||
mViewModelItem->setFolderViewItem(this);
|
||||
|
|
@ -211,6 +242,7 @@ bool LLFolderViewItem::postBuild()
|
|||
// getDisplayName() is expensive (due to internal getLabelSuffix() and name building)
|
||||
// it also sets search strings so it requires a filter reset
|
||||
mLabel = utf8str_to_wstring(vmi->getDisplayName());
|
||||
mIsFavorite = vmi->isFavorite() && !vmi->isItemInTrash();
|
||||
setToolTip(vmi->getName());
|
||||
|
||||
// Dirty the filter flag of the model from the view (CHUI-849)
|
||||
|
|
@ -325,6 +357,7 @@ void LLFolderViewItem::refresh()
|
|||
|
||||
mLabel = utf8str_to_wstring(vmi.getDisplayName());
|
||||
mLabelFontBuffer.reset();
|
||||
mIsFavorite = vmi.isFavorite() && !vmi.isItemInTrash();
|
||||
setToolTip(vmi.getName());
|
||||
// icons are slightly expensive to get, can be optimized
|
||||
// see LLInventoryIcon::getIcon()
|
||||
|
|
@ -359,6 +392,8 @@ void LLFolderViewItem::refreshSuffix()
|
|||
mIconOpen = vmi->getIconOpen();
|
||||
mIconOverlay = vmi->getIconOverlay();
|
||||
|
||||
mIsFavorite = vmi->isFavorite() && !vmi->isItemInTrash();
|
||||
|
||||
if (mRoot->useLabelSuffix())
|
||||
{
|
||||
// Very Expensive!
|
||||
|
|
@ -428,6 +463,10 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
|
|||
}
|
||||
mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel.c_str()) + getLabelFontForStyle(LLFontGL::NORMAL)->getWidth(mLabelSuffix.c_str()) + mLabelPaddingRight;
|
||||
mLabelWidthDirty = false;
|
||||
if (mIsFavorite)
|
||||
{
|
||||
mLabelWidth += FAVORITE_IMAGE_SIZE + FAVORITE_IMAGE_PAD;
|
||||
}
|
||||
}
|
||||
|
||||
*width = llmax(*width, mLabelWidth);
|
||||
|
|
@ -554,10 +593,15 @@ void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
|
|||
|
||||
void LLFolderViewItem::openItem( void )
|
||||
{
|
||||
if (mAllowWear || !getViewModelItem()->isItemWearable())
|
||||
if (!mMarketplaceItem || !getViewModelItem()->isItemWearable())
|
||||
{
|
||||
getViewModelItem()->openItem();
|
||||
}
|
||||
else if (mMarketplaceItem)
|
||||
{
|
||||
// Wearing an object from any listing, active or not, is verbotten
|
||||
LLNotificationsUtil::add("AlertMerchantListingCannotWear");
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderViewItem::rename(const std::string& new_name)
|
||||
|
|
@ -771,6 +815,45 @@ void LLFolderViewItem::drawOpenFolderArrow()
|
|||
}
|
||||
}
|
||||
|
||||
void LLFolderViewItem::drawFavoriteIcon()
|
||||
{
|
||||
static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true);
|
||||
static LLUICachedControl<bool> draw_hollow_star("InventoryFavoritesUseHollowStar", true);
|
||||
|
||||
LLUIImage* favorite_image = nullptr;
|
||||
if (draw_star && mIsFavorite)
|
||||
{
|
||||
favorite_image = sFavoriteImg;
|
||||
}
|
||||
else if (draw_hollow_star && mHasFavorites && !isOpen())
|
||||
{
|
||||
favorite_image = sFavoriteContentImg;
|
||||
}
|
||||
|
||||
if (favorite_image)
|
||||
{
|
||||
S32 x_offset = 0;
|
||||
LLScrollContainer* scroll = mRoot->getScrollContainer();
|
||||
if (scroll)
|
||||
{
|
||||
S32 width = scroll->getVisibleContentRect().getWidth();
|
||||
S32 offset = scroll->getDocPosHorizontal();
|
||||
x_offset = width + offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
x_offset = getRect().getWidth();
|
||||
}
|
||||
gl_draw_scaled_image(
|
||||
x_offset - FAVORITE_IMAGE_SIZE - FAVORITE_IMAGE_PAD,
|
||||
getRect().getHeight() - mItemHeight + FAVORITE_IMAGE_PAD,
|
||||
FAVORITE_IMAGE_SIZE,
|
||||
FAVORITE_IMAGE_SIZE,
|
||||
favorite_image->getImage(),
|
||||
sFgColor);
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ bool LLFolderViewItem::isHighlightAllowed()
|
||||
{
|
||||
return mIsSelected;
|
||||
|
|
@ -928,6 +1011,7 @@ void LLFolderViewItem::draw()
|
|||
{
|
||||
drawOpenFolderArrow();
|
||||
}
|
||||
drawFavoriteIcon();
|
||||
|
||||
drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
|
||||
|
||||
|
|
@ -999,7 +1083,20 @@ void LLFolderViewItem::draw()
|
|||
}
|
||||
}
|
||||
|
||||
LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor;
|
||||
static LLUICachedControl<bool> highlight_color("InventoryFavoritesColorText", true);
|
||||
LLColor4 color;
|
||||
if (mIsSelected && filled)
|
||||
{
|
||||
color = mFontHighlightColor;
|
||||
}
|
||||
else if (mIsFavorite && highlight_color)
|
||||
{
|
||||
color = sFavoriteColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = mFontColor;
|
||||
}
|
||||
|
||||
if (isFadeItem())
|
||||
{
|
||||
|
|
@ -1093,7 +1190,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ):
|
|||
mIsFolderComplete(false), // folder might have children that are not loaded yet.
|
||||
mAreChildrenInited(false), // folder might have children that are not built yet.
|
||||
mLastArrangeGeneration( -1 ),
|
||||
mLastCalculatedWidth(0)
|
||||
mLastCalculatedWidth(0),
|
||||
mFavoritesDirtyFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1119,6 +1217,11 @@ LLFolderViewFolder::~LLFolderViewFolder( void )
|
|||
// The LLView base class takes care of object destruction. make sure that we
|
||||
// don't have mouse or keyboard focus
|
||||
gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
|
||||
|
||||
if (mFavoritesDirtyFlags)
|
||||
{
|
||||
gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, this);
|
||||
}
|
||||
}
|
||||
|
||||
// addToFolder() returns true if it succeeds. false otherwise
|
||||
|
|
@ -1762,6 +1865,140 @@ bool LLFolderViewFolder::isMovable()
|
|||
return true;
|
||||
}
|
||||
|
||||
void LLFolderViewFolder::updateHasFavorites(bool new_childs_value)
|
||||
{
|
||||
if (mFavoritesDirtyFlags == 0)
|
||||
{
|
||||
gIdleCallbacks.addFunction(&LLFolderViewFolder::onIdleUpdateFavorites, this);
|
||||
}
|
||||
if (new_childs_value)
|
||||
{
|
||||
mFavoritesDirtyFlags |= FAVORITE_ADDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
mFavoritesDirtyFlags |= FAVORITE_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
void LLFolderViewFolder::onIdleUpdateFavorites(void* data)
|
||||
{
|
||||
LLFolderViewFolder* self = reinterpret_cast<LLFolderViewFolder*>(data);
|
||||
if (self->mFavoritesDirtyFlags == 0)
|
||||
{
|
||||
// already processed either on previous run or by a different callback
|
||||
gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->getViewModelItem()->isItemInTrash())
|
||||
{
|
||||
// do not display favorite-stars in trash
|
||||
self->mFavoritesDirtyFlags = 0;
|
||||
gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->mFavoritesDirtyFlags == FAVORITE_ADDED)
|
||||
{
|
||||
if (!self->mHasFavorites)
|
||||
{
|
||||
// propagate up, exclude root
|
||||
LLFolderViewFolder* parent = self;
|
||||
while (parent
|
||||
&& (!parent->hasFavorites() || parent->mFavoritesDirtyFlags)
|
||||
&& !parent->getViewModelItem()->isAgentInventoryRoot())
|
||||
{
|
||||
parent->setHasFavorites(true);
|
||||
if (parent->mFavoritesDirtyFlags)
|
||||
{
|
||||
// Parent will remove onIdleUpdateFavorites later, don't remove now,
|
||||
// We are inside gIdleCallbacks. Removing 'self' callback is safe,
|
||||
// but removing 'parent' can invalidate following iterator
|
||||
parent->mFavoritesDirtyFlags = 0;
|
||||
}
|
||||
parent = parent->getParentFolder();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// already up to date
|
||||
self->mFavoritesDirtyFlags = 0;
|
||||
gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self);
|
||||
}
|
||||
}
|
||||
else if (self->mFavoritesDirtyFlags > FAVORITE_ADDED)
|
||||
{
|
||||
// full check
|
||||
LLFolderViewFolder* parent = self;
|
||||
while (parent && !parent->getViewModelItem()->isAgentInventoryRoot())
|
||||
{
|
||||
bool has_favorites = false;
|
||||
for (items_t::iterator iter = parent->mItems.begin();
|
||||
iter != parent->mItems.end();)
|
||||
{
|
||||
items_t::iterator iit = iter++;
|
||||
if ((*iit)->isFavorite())
|
||||
{
|
||||
has_favorites = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (folders_t::iterator iter = parent->mFolders.begin();
|
||||
iter != parent->mFolders.end() && !has_favorites;)
|
||||
{
|
||||
folders_t::iterator fit = iter++;
|
||||
if ((*fit)->isFavorite() || (*fit)->hasFavorites())
|
||||
{
|
||||
has_favorites = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_favorites)
|
||||
{
|
||||
if (parent->hasFavorites())
|
||||
{
|
||||
parent->setHasFavorites(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing changed
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// propagate up, exclude root
|
||||
while (parent
|
||||
&& (!parent->hasFavorites() || parent->mFavoritesDirtyFlags)
|
||||
&& !parent->getViewModelItem()->isAgentInventoryRoot())
|
||||
{
|
||||
parent->setHasFavorites(true);
|
||||
if (parent->mFavoritesDirtyFlags)
|
||||
{
|
||||
// Parent will remove onIdleUpdateFavorites later, don't remove now,
|
||||
// We are inside gIdleCallbacks. Removing 'self' callback is safe,
|
||||
// but removing 'parent' can invalidate following iterator
|
||||
parent->mFavoritesDirtyFlags = 0;
|
||||
}
|
||||
parent = parent->getParentFolder();
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (parent->mFavoritesDirtyFlags)
|
||||
{
|
||||
// Parent will remove onIdleUpdateFavorites later, don't remove now.
|
||||
// We are inside gIdleCallbacks. Removing 'self' callback is safe,
|
||||
// but removing 'parent' can invalidate following iterator
|
||||
parent->mFavoritesDirtyFlags = 0;
|
||||
}
|
||||
parent = parent->getParentFolder();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLFolderViewFolder::isRemovable()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,7 +50,9 @@ class LLFolderViewItem : public LLView
|
|||
public:
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Optional<LLUIImage*> folder_arrow_image,
|
||||
Optional<LLUIImage*> favorite_image,
|
||||
favorite_content_image,
|
||||
folder_arrow_image,
|
||||
selection_image;
|
||||
Mandatory<LLFolderView*> root;
|
||||
Mandatory<LLFolderViewModelItem*> listener;
|
||||
|
|
@ -60,7 +62,7 @@ public:
|
|||
item_top_pad;
|
||||
|
||||
Optional<time_t> creation_date;
|
||||
Optional<bool> allow_wear;
|
||||
Optional<bool> marketplace_item;
|
||||
Optional<bool> allow_drop;
|
||||
|
||||
Optional<LLUIColor> font_color;
|
||||
|
|
@ -93,6 +95,8 @@ protected:
|
|||
LLWString mLabel;
|
||||
S32 mLabelWidth;
|
||||
bool mLabelWidthDirty;
|
||||
bool mIsFavorite;
|
||||
bool mHasFavorites;
|
||||
S32 mLabelPaddingRight;
|
||||
LLFolderViewFolder* mParentFolder;
|
||||
LLPointer<LLFolderViewModelItem> mViewModelItem;
|
||||
|
|
@ -122,7 +126,7 @@ protected:
|
|||
mIsCurSelection,
|
||||
mDragAndDropTarget,
|
||||
mIsMouseOverTitle,
|
||||
mAllowWear,
|
||||
mMarketplaceItem,
|
||||
mAllowDrop,
|
||||
mSingleFolderMode,
|
||||
mDoubleClickOverride,
|
||||
|
|
@ -133,6 +137,7 @@ protected:
|
|||
|
||||
LLUIColor mFontColor;
|
||||
LLUIColor mFontHighlightColor;
|
||||
static bool sColorSetInitialized;
|
||||
|
||||
// For now assuming all colors are the same in derived classes.
|
||||
static LLUIColor sFgColor;
|
||||
|
|
@ -145,6 +150,8 @@ protected:
|
|||
static LLUIColor sFilterTextColor;
|
||||
static LLUIColor sSuffixColor;
|
||||
static LLUIColor sSearchStatusColor;
|
||||
static LLUIColor sFavoriteColor;
|
||||
|
||||
|
||||
// this is an internal method used for adding items to folders. A
|
||||
// no-op at this level, but reimplemented in derived classes.
|
||||
|
|
@ -208,6 +215,8 @@ public:
|
|||
// Returns true is this object and all of its children can be moved
|
||||
virtual bool isMovable();
|
||||
|
||||
bool isFavorite() const { return mIsFavorite; }
|
||||
|
||||
// destroys this item recursively
|
||||
virtual void destroyView();
|
||||
|
||||
|
|
@ -298,6 +307,7 @@ public:
|
|||
// virtual void handleDropped();
|
||||
virtual void draw();
|
||||
void drawOpenFolderArrow();
|
||||
void drawFavoriteIcon();
|
||||
void drawHighlight(bool showContent, bool hasKeyboardFocus, const LLUIColor& selectColor, const LLUIColor& flashColor, const LLUIColor& outlineColor, const LLUIColor& mouseOverColor);
|
||||
void drawLabel(const LLFontGL* font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
|
||||
virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop,
|
||||
|
|
@ -311,6 +321,8 @@ private:
|
|||
static S32 sTopPad;
|
||||
static LLUIImagePtr sFolderArrowImg;
|
||||
static LLUIImagePtr sSelectionImg;
|
||||
static LLUIImagePtr sFavoriteImg;
|
||||
static LLUIImagePtr sFavoriteContentImg;
|
||||
static LLFontGL* sSuffixFont;
|
||||
|
||||
LLFontVertexBuffer mLabelFontBuffer;
|
||||
|
|
@ -400,6 +412,18 @@ public:
|
|||
// Returns true is this object and all of its children can be moved
|
||||
virtual bool isMovable();
|
||||
|
||||
bool isFavorite() const { return mIsFavorite; }
|
||||
bool hasFavorites() const { return mHasFavorites; }
|
||||
void setHasFavorites(bool val) { mHasFavorites = val; }
|
||||
void updateHasFavorites(bool new_childs_value);
|
||||
private:
|
||||
static void onIdleUpdateFavorites(void* data);
|
||||
|
||||
constexpr static S32 FAVORITE_ADDED = 1;
|
||||
constexpr static S32 FAVORITE_REMOVED = 2;
|
||||
S32 mFavoritesDirtyFlags { 0 };
|
||||
public:
|
||||
|
||||
// destroys this folder, and all children
|
||||
virtual void destroyView();
|
||||
void destroyRoot();
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ public:
|
|||
|
||||
virtual void navigateToFolder(bool new_window = false, bool change_mode = false) = 0;
|
||||
|
||||
virtual bool isFavorite() const = 0;
|
||||
virtual bool isItemWearable() const { return false; }
|
||||
|
||||
virtual bool isItemRenameable() const = 0;
|
||||
|
|
@ -171,6 +172,7 @@ public:
|
|||
virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
|
||||
|
||||
virtual bool isItemRemovable( bool check_worn = true) const = 0; // Can be destroyed
|
||||
virtual bool isItemInTrash(void) const = 0;
|
||||
virtual bool removeItem() = 0;
|
||||
virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
|
||||
|
||||
|
|
@ -183,6 +185,9 @@ public:
|
|||
virtual void pasteFromClipboard() = 0;
|
||||
virtual void pasteLinkFromClipboard() = 0;
|
||||
|
||||
virtual bool isAgentInventory() const = 0;
|
||||
virtual bool isAgentInventoryRoot() const = 0;
|
||||
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
|
||||
|
||||
virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
|
||||
|
|
@ -219,6 +224,7 @@ public:
|
|||
virtual S32 getSortVersion() = 0;
|
||||
virtual void setSortVersion(S32 version) = 0;
|
||||
virtual void setParent(LLFolderViewModelItem* parent) = 0;
|
||||
virtual const LLFolderViewModelItem* getParent() = 0;
|
||||
virtual bool hasParent() = 0;
|
||||
|
||||
protected:
|
||||
|
|
@ -249,14 +255,14 @@ public:
|
|||
mChildren.clear();
|
||||
}
|
||||
|
||||
void requestSort() { mSortVersion = -1; }
|
||||
S32 getSortVersion() { return mSortVersion; }
|
||||
void setSortVersion(S32 version) { mSortVersion = version;}
|
||||
void requestSort() override { mSortVersion = -1; }
|
||||
S32 getSortVersion() override { return mSortVersion; }
|
||||
void setSortVersion(S32 version) override { mSortVersion = version;}
|
||||
|
||||
S32 getLastFilterGeneration() const { return mLastFilterGeneration; }
|
||||
S32 getLastFilterGeneration() const override { return mLastFilterGeneration; }
|
||||
S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
|
||||
S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; }
|
||||
void dirtyFilter()
|
||||
S32 getMarkedDirtyGeneration() const override { return mMarkedDirtyGeneration; }
|
||||
void dirtyFilter() override
|
||||
{
|
||||
if(mMarkedDirtyGeneration < 0)
|
||||
{
|
||||
|
|
@ -271,7 +277,7 @@ public:
|
|||
mParent->dirtyFilter();
|
||||
}
|
||||
}
|
||||
void dirtyDescendantsFilter()
|
||||
void dirtyDescendantsFilter() override
|
||||
{
|
||||
mMostFilteredDescendantGeneration = -1;
|
||||
if (mParent)
|
||||
|
|
@ -279,13 +285,13 @@ public:
|
|||
mParent->dirtyDescendantsFilter();
|
||||
}
|
||||
}
|
||||
bool hasFilterStringMatch();
|
||||
std::string::size_type getFilterStringOffset();
|
||||
std::string::size_type getFilterStringSize();
|
||||
bool hasFilterStringMatch() override;
|
||||
std::string::size_type getFilterStringOffset() override;
|
||||
std::string::size_type getFilterStringSize() override;
|
||||
|
||||
typedef std::list<LLFolderViewModelItem*> child_list_t;
|
||||
typedef std::list<LLPointer<LLFolderViewModelItem> > child_list_t;
|
||||
|
||||
virtual void addChild(LLFolderViewModelItem* child)
|
||||
virtual void addChild(LLFolderViewModelItem* child) override
|
||||
{
|
||||
mChildren.push_back(child);
|
||||
child->setParent(this);
|
||||
|
|
@ -293,15 +299,15 @@ public:
|
|||
requestSort();
|
||||
}
|
||||
|
||||
virtual void removeChild(LLFolderViewModelItem* child)
|
||||
virtual void removeChild(LLFolderViewModelItem* child) override final
|
||||
{
|
||||
mChildren.remove(child);
|
||||
child->setParent(NULL);
|
||||
mChildren.remove(child);
|
||||
dirtyDescendantsFilter();
|
||||
dirtyFilter();
|
||||
}
|
||||
|
||||
virtual void clearChildren()
|
||||
virtual void clearChildren() override
|
||||
{
|
||||
// We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest
|
||||
std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); });
|
||||
|
|
@ -314,7 +320,7 @@ public:
|
|||
child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); }
|
||||
child_list_t::size_type getChildrenCount() const { return mChildren.size(); }
|
||||
|
||||
void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
|
||||
void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) override
|
||||
{
|
||||
mPassedFilter = passed;
|
||||
mLastFilterGeneration = filter_generation;
|
||||
|
|
@ -323,20 +329,20 @@ public:
|
|||
mMarkedDirtyGeneration = -1;
|
||||
}
|
||||
|
||||
void setPassedFolderFilter(bool passed, S32 filter_generation)
|
||||
void setPassedFolderFilter(bool passed, S32 filter_generation) override
|
||||
{
|
||||
mPassedFolderFilter = passed;
|
||||
mLastFolderFilterGeneration = filter_generation;
|
||||
}
|
||||
|
||||
virtual bool potentiallyVisible()
|
||||
virtual bool potentiallyVisible() override
|
||||
{
|
||||
return passedFilter() // we've passed the filter
|
||||
|| (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet
|
||||
|| descendantsPassedFilter();
|
||||
}
|
||||
|
||||
virtual bool passedFilter(S32 filter_generation = -1)
|
||||
virtual bool passedFilter(S32 filter_generation = -1) override
|
||||
{
|
||||
if (filter_generation < 0)
|
||||
{
|
||||
|
|
@ -347,7 +353,7 @@ public:
|
|||
return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation));
|
||||
}
|
||||
|
||||
virtual bool descendantsPassedFilter(S32 filter_generation = -1)
|
||||
virtual bool descendantsPassedFilter(S32 filter_generation = -1) override
|
||||
{
|
||||
if (filter_generation < 0)
|
||||
{
|
||||
|
|
@ -356,10 +362,10 @@ public:
|
|||
return mMostFilteredDescendantGeneration >= filter_generation;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
|
||||
virtual bool hasParent() { return mParent != NULL; }
|
||||
virtual void setParent(LLFolderViewModelItem* parent) override final { mParent = parent; }
|
||||
virtual const LLFolderViewModelItem* getParent() override { return mParent; };
|
||||
virtual bool hasParent() override { return mParent != NULL; }
|
||||
|
||||
S32 mSortVersion;
|
||||
bool mPassedFilter;
|
||||
|
|
@ -376,7 +382,7 @@ protected:
|
|||
LLFolderViewModelItem* mParent;
|
||||
LLFolderViewModelInterface& mRootViewModel;
|
||||
|
||||
void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
|
||||
void setFolderViewItem(LLFolderViewItem* folder_view_item) override { mFolderViewItem = folder_view_item;}
|
||||
LLFolderViewItem* mFolderViewItem;
|
||||
};
|
||||
|
||||
|
|
@ -390,15 +396,15 @@ public:
|
|||
mFolderView(NULL)
|
||||
{}
|
||||
|
||||
virtual void requestSortAll()
|
||||
virtual void requestSortAll() override
|
||||
{
|
||||
// sort everything
|
||||
mTargetSortVersion++;
|
||||
}
|
||||
virtual std::string getStatusText(bool is_empty_folder = false);
|
||||
virtual void filter();
|
||||
virtual std::string getStatusText(bool is_empty_folder = false) override;
|
||||
virtual void filter() override;
|
||||
|
||||
void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
|
||||
void setFolderView(LLFolderView* folder_view) override { mFolderView = folder_view;}
|
||||
|
||||
protected:
|
||||
bool needsSort(class LLFolderViewModelItem* item);
|
||||
|
|
@ -428,14 +434,14 @@ public:
|
|||
virtual const SortType& getSorter() const { return *mSorter; }
|
||||
virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); }
|
||||
|
||||
virtual FilterType& getFilter() { return *mFilter; }
|
||||
virtual const FilterType& getFilter() const { return *mFilter; }
|
||||
virtual FilterType& getFilter() override { return *mFilter; }
|
||||
virtual const FilterType& getFilter() const override { return *mFilter; }
|
||||
virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); }
|
||||
|
||||
// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
|
||||
// this method needs to be overloaded and return the relevant fetch status.
|
||||
virtual bool contentsReady() { return true; }
|
||||
virtual bool isFolderComplete(LLFolderViewFolder* folder) { return true; }
|
||||
virtual bool contentsReady() override { return true; }
|
||||
virtual bool isFolderComplete(LLFolderViewFolder* folder) override { return true; }
|
||||
|
||||
struct ViewModelCompare
|
||||
{
|
||||
|
|
@ -456,7 +462,7 @@ public:
|
|||
const SortType& mSorter;
|
||||
};
|
||||
|
||||
void sort(LLFolderViewFolder* folder)
|
||||
void sort(LLFolderViewFolder* folder) override
|
||||
{
|
||||
if (needsSort(folder->getViewModelItem()))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "llfocusmgr.h"
|
||||
#include "llcoord.h"
|
||||
#include "llwindow.h"
|
||||
#include "llemojihelper.h"
|
||||
#include "llcriticaldamp.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
|
|
@ -1411,6 +1412,7 @@ void LLMenuItemBranchDownGL::openMenu( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
LLEmojiHelper::instance().hideHelper(nullptr, true);
|
||||
if (branch->getTornOff())
|
||||
{
|
||||
LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent());
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "llmodaldialog.h"
|
||||
|
||||
#include "llemojihelper.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "v4color.h"
|
||||
#include "v2math.h"
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
#include "llwindow.h"
|
||||
#include "llkeyboard.h"
|
||||
#include "llmenugl.h"
|
||||
|
||||
// static
|
||||
std::list<LLModalDialog*> LLModalDialog::sModalStack;
|
||||
|
||||
|
|
@ -98,7 +100,7 @@ void LLModalDialog::onOpen(const LLSD& key)
|
|||
{
|
||||
if (mModal)
|
||||
{
|
||||
// If Modal, Hide the active modal dialog
|
||||
// If Modal, hide the active modal dialog
|
||||
if (!sModalStack.empty())
|
||||
{
|
||||
LLModalDialog* front = sModalStack.front();
|
||||
|
|
@ -155,6 +157,12 @@ void LLModalDialog::setVisible( bool visible )
|
|||
{
|
||||
if( visible )
|
||||
{
|
||||
// Hide all menus currently shown
|
||||
LLMenuGL::sMenuContainer->hideMenus();
|
||||
|
||||
// Hide EmojiPicker if it is shown
|
||||
LLEmojiHelper::instance().hideHelper(nullptr, true);
|
||||
|
||||
// This is a modal dialog. It sucks up all mouse and keyboard operations.
|
||||
gFocusMgr.setMouseCapture( this );
|
||||
|
||||
|
|
@ -301,7 +309,6 @@ void LLModalDialog::centerOnScreen()
|
|||
centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY])));
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLModalDialog::onAppFocusLost()
|
||||
{
|
||||
|
|
@ -333,6 +340,7 @@ void LLModalDialog::onAppFocusGained()
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLModalDialog::shutdownModals()
|
||||
{
|
||||
// This method is only for use during app shutdown. ~LLModalDialog()
|
||||
|
|
|
|||
|
|
@ -2227,6 +2227,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
|
|||
registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url));
|
||||
registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url));
|
||||
registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
|
||||
registrar.add("Url.ZoomInObject", boost::bind(&LLUrlAction::zoomInObject, url));
|
||||
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
|
||||
registrar.add("Url.ShowParcelOnMap", boost::bind(&LLUrlAction::showParcelOnMap, url));
|
||||
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
|
||||
|
|
|
|||
|
|
@ -274,7 +274,9 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
|
|||
mShowChatMentionPicker(false),
|
||||
mEnableTooltipPaste(p.enable_tooltip_paste),
|
||||
mPassDelete(false),
|
||||
mKeepSelectionOnReturn(false)
|
||||
mKeepSelectionOnReturn(false),
|
||||
mSelectAllOnFocusReceived(false),
|
||||
mSelectedOnFocusReceived(false)
|
||||
{
|
||||
mSourceID.generate();
|
||||
|
||||
|
|
@ -398,6 +400,7 @@ void LLTextEditor::selectNext(const std::string& search_text_in, bool case_insen
|
|||
setCursorPos(loc);
|
||||
|
||||
mIsSelecting = true;
|
||||
mSelectedOnFocusReceived = false;
|
||||
mSelectionEnd = mCursorPos;
|
||||
mSelectionStart = llmin((S32)getLength(), (S32)(mCursorPos + search_text.size()));
|
||||
}
|
||||
|
|
@ -677,6 +680,13 @@ bool LLTextEditor::canSelectAll() const
|
|||
return true;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLTextEditor::deselect()
|
||||
{
|
||||
LLTextBase::deselect();
|
||||
mSelectedOnFocusReceived = false;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLTextEditor::selectAll()
|
||||
{
|
||||
|
|
@ -694,6 +704,11 @@ void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_p
|
|||
endSelection();
|
||||
}
|
||||
|
||||
void LLTextEditor::setSelectAllOnFocusReceived(bool b)
|
||||
{
|
||||
mSelectAllOnFocusReceived = b;
|
||||
}
|
||||
|
||||
void LLTextEditor::insertEmoji(llwchar emoji)
|
||||
{
|
||||
LL_INFOS() << "LLTextEditor::insertEmoji(" << wchar_utf8_preview(emoji) << ")" << LL_ENDL;
|
||||
|
|
@ -795,8 +810,16 @@ bool LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask)
|
|||
// Delay cursor flashing
|
||||
resetCursorBlink();
|
||||
|
||||
mSelectedOnFocusReceived = false;
|
||||
if (handled && !gFocusMgr.getMouseCapture())
|
||||
{
|
||||
if (!mask && mSelectAllOnFocusReceived)
|
||||
{
|
||||
mIsSelecting = false;
|
||||
mSelectionStart = getLength();
|
||||
mSelectionEnd = 0;
|
||||
mSelectedOnFocusReceived = true;
|
||||
}
|
||||
gFocusMgr.setMouseCapture( this );
|
||||
}
|
||||
return handled;
|
||||
|
|
@ -2200,6 +2223,11 @@ void LLTextEditor::focusLostHelper()
|
|||
gEditMenuHandler = NULL;
|
||||
}
|
||||
|
||||
if (mSelectedOnFocusReceived)
|
||||
{
|
||||
deselect();
|
||||
}
|
||||
|
||||
if (mCommitOnFocusLost)
|
||||
{
|
||||
onCommit();
|
||||
|
|
|
|||
|
|
@ -144,8 +144,10 @@ public:
|
|||
virtual bool canDoDelete() const;
|
||||
virtual void selectAll();
|
||||
virtual bool canSelectAll() const;
|
||||
virtual void deselect();
|
||||
|
||||
void selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos);
|
||||
void setSelectAllOnFocusReceived(bool b);
|
||||
|
||||
virtual bool canLoadOrSaveToFile();
|
||||
|
||||
|
|
@ -336,6 +338,8 @@ private:
|
|||
bool mEnableTooltipPaste;
|
||||
bool mPassDelete;
|
||||
bool mKeepSelectionOnReturn; // disabling of removing selected text after pressing of Enter
|
||||
bool mSelectAllOnFocusReceived;
|
||||
bool mSelectedOnFocusReceived;
|
||||
|
||||
LLUUID mSourceID;
|
||||
|
||||
|
|
|
|||
|
|
@ -117,6 +117,16 @@ void LLUrlAction::teleportToLocation(std::string url)
|
|||
}
|
||||
}
|
||||
|
||||
void LLUrlAction::zoomInObject(std::string url)
|
||||
{
|
||||
LLUrlMatch match;
|
||||
std::string object_id = getObjectId(url);
|
||||
if (LLUUID::validate(object_id) && LLUrlRegistry::instance().findUrl(url, match))
|
||||
{
|
||||
executeSLURL("secondlife:///app/object/" + object_id + "/zoomin/" + match.getLocation());
|
||||
}
|
||||
}
|
||||
|
||||
void LLUrlAction::showLocationOnMap(std::string url)
|
||||
{
|
||||
LLUrlMatch match;
|
||||
|
|
@ -160,6 +170,16 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
|
|||
}
|
||||
}
|
||||
|
||||
std::string LLUrlAction::getURLLabel(std::string url)
|
||||
{
|
||||
LLUrlMatch match;
|
||||
if (LLUrlRegistry::instance().findUrl(url, match))
|
||||
{
|
||||
return match.getLabel();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void LLUrlAction::showProfile(std::string url)
|
||||
{
|
||||
// Get id from 'secondlife:///app/{cmd}/{id}/{action}'
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ public:
|
|||
/// if the Url specifies an SL location, teleport there
|
||||
static void teleportToLocation(std::string url);
|
||||
|
||||
/// If the Url specifies an object id, attempt to zoom in.
|
||||
/// If not possible to zoom in, show on map
|
||||
static void zoomInObject(std::string url);
|
||||
|
||||
/// if the Url specifies an SL location, show it on a map
|
||||
static void showLocationOnMap(std::string url);
|
||||
|
||||
|
|
@ -74,6 +78,8 @@ public:
|
|||
/// copy a Url to the clipboard
|
||||
static void copyURLToClipboard(std::string url);
|
||||
|
||||
static std::string getURLLabel(std::string url);
|
||||
|
||||
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
|
||||
static void showProfile(std::string url);
|
||||
static std::string getUserID(std::string url);
|
||||
|
|
|
|||
|
|
@ -43,8 +43,6 @@
|
|||
#include "llexperiencecache.h"
|
||||
#include "v3dmath.h"
|
||||
|
||||
#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
|
||||
|
||||
// Utility functions
|
||||
std::string localize_slapp_label(const std::string& url, const std::string& full_name);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@
|
|||
class LLAvatarName;
|
||||
class LLVector3d;
|
||||
|
||||
#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
|
||||
|
||||
typedef boost::signals2::signal<void (const std::string& url,
|
||||
const std::string& label,
|
||||
const std::string& icon)> LLUrlLabelSignal;
|
||||
|
|
|
|||
|
|
@ -904,12 +904,12 @@ void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable)
|
|||
// set_enabled shouldn't be done on the worker thread.
|
||||
if (mPeerConnection)
|
||||
{
|
||||
mPeerConnection->SetAudioRecording(enable);
|
||||
auto senders = mPeerConnection->GetSenders();
|
||||
for (auto &sender : senders)
|
||||
{
|
||||
sender->track()->set_enabled(enable);
|
||||
}
|
||||
mPeerConnection->SetAudioRecording(enable);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -964,6 +964,9 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
|
|||
{
|
||||
if (mPeerConnection)
|
||||
{
|
||||
// SetAudioRecording must be called before enabling/disabling tracks.
|
||||
mPeerConnection->SetAudioRecording(enable);
|
||||
|
||||
auto senders = mPeerConnection->GetSenders();
|
||||
|
||||
RTC_LOG(LS_INFO) << __FUNCTION__ << (mMute ? "disabling" : "enabling") << " streams count " << senders.size();
|
||||
|
|
@ -982,7 +985,6 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute)
|
|||
track->set_enabled(enable);
|
||||
}
|
||||
}
|
||||
mPeerConnection->SetAudioRecording(enable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,10 +371,14 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
LLWindowWin32Thread();
|
||||
|
||||
void run() override;
|
||||
void close() override;
|
||||
|
||||
// closes queue, wakes thread, waits until thread closes
|
||||
void wakeAndDestroy();
|
||||
// Detroys handles and window
|
||||
// Either post to or call from window thread
|
||||
void destroyWindow();
|
||||
|
||||
// Closes queue, wakes thread, waits until thread closes.
|
||||
// Call from main thread
|
||||
bool wakeAndDestroy();
|
||||
|
||||
void glReady()
|
||||
{
|
||||
|
|
@ -431,6 +435,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool
|
|||
// until after some graphics setup. See SL-20177. -Cosmic,2023-09-18
|
||||
bool mGLReady = false;
|
||||
bool mGotGLBuffer = false;
|
||||
LLAtomicBool mDeleteOnExit = false;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -874,6 +879,7 @@ LLWindowWin32::~LLWindowWin32()
|
|||
}
|
||||
|
||||
delete mDragDrop;
|
||||
mDragDrop = NULL;
|
||||
|
||||
delete [] mWindowTitle;
|
||||
mWindowTitle = NULL;
|
||||
|
|
@ -885,6 +891,7 @@ LLWindowWin32::~LLWindowWin32()
|
|||
mWindowClassName = NULL;
|
||||
|
||||
delete mWindowThread;
|
||||
mWindowThread = NULL;
|
||||
}
|
||||
|
||||
void LLWindowWin32::show()
|
||||
|
|
@ -993,7 +1000,7 @@ void LLWindowWin32::close()
|
|||
// Restore gamma to the system values.
|
||||
restoreGamma();
|
||||
|
||||
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
|
||||
LL_INFOS("Window") << "Destroying Window Thread" << LL_ENDL;
|
||||
|
||||
if (sWindowHandleForMessageBox == mWindowHandle)
|
||||
{
|
||||
|
|
@ -1003,7 +1010,11 @@ void LLWindowWin32::close()
|
|||
mhDC = NULL;
|
||||
mWindowHandle = NULL;
|
||||
|
||||
mWindowThread->wakeAndDestroy();
|
||||
if (mWindowThread->wakeAndDestroy())
|
||||
{
|
||||
// thread will delete itselfs once done
|
||||
mWindowThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool LLWindowWin32::isValid()
|
||||
|
|
@ -3134,10 +3145,14 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
|
|||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
else // (NULL == window_imp)
|
||||
{
|
||||
// (NULL == window_imp)
|
||||
LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL;
|
||||
if (u_msg == WM_DESTROY)
|
||||
{
|
||||
PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// pass unhandled messages down to Windows
|
||||
|
|
@ -4607,25 +4622,11 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
|
|||
#endif // LL_WINDOWS
|
||||
|
||||
inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread()
|
||||
: LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, true /*should be false, temporary workaround for SL-18721*/)
|
||||
: LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, false)
|
||||
{
|
||||
LL::ThreadPool::start();
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::close()
|
||||
{
|
||||
if (!mQueue->isClosed())
|
||||
{
|
||||
LL_WARNS() << "Closing window thread without using destroy_window_handler" << LL_ENDL;
|
||||
LL::ThreadPool::close();
|
||||
|
||||
// Workaround for SL-18721 in case window closes too early and abruptly
|
||||
LLSplashScreen::show();
|
||||
LLSplashScreen::update("..."); // will be updated later
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LogChange is to log changes in status while trying to avoid spamming the
|
||||
* log with repeated messages, especially in a tight loop. It refuses to log
|
||||
|
|
@ -4849,26 +4850,18 @@ void LLWindowWin32::LLWindowWin32Thread::run()
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
destroyWindow();
|
||||
|
||||
if (mDeleteOnExit)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy()
|
||||
void LLWindowWin32::LLWindowWin32Thread::destroyWindow()
|
||||
{
|
||||
if (mQueue->isClosed())
|
||||
{
|
||||
LL_WARNS() << "Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we don't leave a blank toolbar button.
|
||||
// Also hiding window now prevents user from suspending it
|
||||
// via some action (like dragging it around)
|
||||
ShowWindow(mWindowHandleThrd, SW_HIDE);
|
||||
|
||||
// Schedule destruction
|
||||
HWND old_handle = mWindowHandleThrd;
|
||||
post([this]()
|
||||
{
|
||||
if (IsWindow(mWindowHandleThrd))
|
||||
if (mWindowHandleThrd != NULL && IsWindow(mWindowHandleThrd))
|
||||
{
|
||||
if (mhDCThrd)
|
||||
{
|
||||
|
|
@ -4892,65 +4885,75 @@ void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy()
|
|||
}
|
||||
mWindowHandleThrd = NULL;
|
||||
mhDCThrd = NULL;
|
||||
mGLReady = false;
|
||||
});
|
||||
}
|
||||
|
||||
bool LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy()
|
||||
{
|
||||
if (mQueue->isClosed())
|
||||
{
|
||||
LL_WARNS("Window") << "Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hide the window immediately to prevent user interaction during shutdown
|
||||
if (mWindowHandleThrd)
|
||||
{
|
||||
ShowWindow(mWindowHandleThrd, SW_HIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Window") << "Tried to hide window, but Win32 window handle is NULL." << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
|
||||
mGLReady = false;
|
||||
|
||||
// Capture current handle before we lose it
|
||||
HWND old_handle = mWindowHandleThrd;
|
||||
|
||||
// Clear the user data to prevent callbacks from finding us
|
||||
if (old_handle)
|
||||
{
|
||||
SetWindowLongPtr(old_handle, GWLP_USERDATA, NULL);
|
||||
}
|
||||
|
||||
// Signal thread to clean up when done
|
||||
mDeleteOnExit = true;
|
||||
|
||||
// Close the queue first
|
||||
LL_DEBUGS("Window") << "Closing window's pool queue" << LL_ENDL;
|
||||
mQueue->close();
|
||||
|
||||
// Post a nonsense user message to wake up the thread in
|
||||
// case it is waiting for a getMessage()
|
||||
// Wake up the thread if it's stuck in GetMessage()
|
||||
if (old_handle)
|
||||
{
|
||||
WPARAM wparam{ 0xB0B0 };
|
||||
LL_DEBUGS("Window") << "PostMessage(" << std::hex << old_handle
|
||||
<< ", " << WM_DUMMY_
|
||||
<< ", " << wparam << ")" << std::dec << LL_ENDL;
|
||||
|
||||
// Use PostMessage to signal thread to wake up
|
||||
PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337);
|
||||
}
|
||||
|
||||
// There are cases where window will refuse to close,
|
||||
// can't wait forever on join, check state instead
|
||||
LLTimer timeout;
|
||||
timeout.setTimerExpirySec(2.0);
|
||||
while (!getQueue().done() && !timeout.hasExpired() && mWindowHandleThrd)
|
||||
{
|
||||
ms_sleep(100);
|
||||
}
|
||||
|
||||
if (getQueue().done() || mWindowHandleThrd == NULL)
|
||||
{
|
||||
// Window is closed, started closing or is cleaning up
|
||||
// now wait for our single thread to die.
|
||||
if (mWindowHandleThrd)
|
||||
{
|
||||
LL_INFOS("Window") << "Window is closing, waiting on pool's thread to join, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Window") << "Waiting on pool's thread, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL;
|
||||
}
|
||||
// Cleanly detach threads instead of joining them to avoid blocking the main thread
|
||||
// This is acceptable since the thread will self-delete with mDeleteOnExit
|
||||
for (auto& pair : mThreads)
|
||||
{
|
||||
pair.second.join();
|
||||
}
|
||||
}
|
||||
else
|
||||
try {
|
||||
// Only detach if the thread is joinable
|
||||
if (pair.second.joinable())
|
||||
{
|
||||
// Something suspended window thread, can't afford to wait forever
|
||||
// so kill thread instead
|
||||
// Ex: This can happen if user starts dragging window arround (if it
|
||||
// was visible) or a modal notification pops up
|
||||
LL_WARNS("Window") << "Window is frozen, couldn't perform clean exit" << LL_ENDL;
|
||||
|
||||
for (auto& pair : mThreads)
|
||||
{
|
||||
// very unsafe
|
||||
TerminateThread(pair.second.native_handle(), 0);
|
||||
pair.second.detach();
|
||||
}
|
||||
}
|
||||
catch (const std::system_error& e) {
|
||||
LL_WARNS("Window") << "Exception detaching thread: " << e.what() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LL_DEBUGS("Window") << "thread pool shutdown complete" << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLWindowWin32::post(const std::function<void()>& func)
|
||||
|
|
|
|||
|
|
@ -157,6 +157,9 @@ LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
|
|||
{
|
||||
if ((persist != PERSIST_NO) && mComment.empty())
|
||||
{
|
||||
// File isn't actually missing, but something is wrong with it
|
||||
// so the main point is to warn user to reinstall
|
||||
LLError::LLUserWarningMsg::showMissingFiles();
|
||||
LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL;
|
||||
}
|
||||
//Push back versus setValue'ing here, since we don't want to call a signal yet
|
||||
|
|
|
|||
|
|
@ -342,6 +342,7 @@ set(viewer_SOURCE_FILES
|
|||
llhudeffectpointat.cpp
|
||||
llhudeffecttrail.cpp
|
||||
llhudeffectblob.cpp
|
||||
llhudeffectresetskeleton.cpp
|
||||
llhudicon.cpp
|
||||
llhudmanager.cpp
|
||||
llhudnametag.cpp
|
||||
|
|
@ -367,6 +368,7 @@ set(viewer_SOURCE_FILES
|
|||
llinventorygallerymenu.cpp
|
||||
llinventoryicon.cpp
|
||||
llinventoryitemslist.cpp
|
||||
llinventorylistener.cpp
|
||||
llinventorylistitem.cpp
|
||||
llinventorymodel.cpp
|
||||
llinventorymodelbackgroundfetch.cpp
|
||||
|
|
@ -391,6 +393,7 @@ set(viewer_SOURCE_FILES
|
|||
llmaniprotate.cpp
|
||||
llmanipscale.cpp
|
||||
llmaniptranslate.cpp
|
||||
llfloatermarketplace.cpp
|
||||
llmarketplacefunctions.cpp
|
||||
llmarketplacenotifications.cpp
|
||||
llmaterialeditor.cpp
|
||||
|
|
@ -928,6 +931,7 @@ set(viewer_HEADER_FILES
|
|||
llfloaterlinkreplace.h
|
||||
llfloaterloadprefpreset.h
|
||||
llfloatermap.h
|
||||
llfloatermarketplace.h
|
||||
llfloatermarketplacelistings.h
|
||||
llfloatermediasettings.h
|
||||
llfloatermemleak.h
|
||||
|
|
@ -1016,6 +1020,7 @@ set(viewer_HEADER_FILES
|
|||
llhudeffectpointat.h
|
||||
llhudeffecttrail.h
|
||||
llhudeffectblob.h
|
||||
llhudeffectresetskeleton.h
|
||||
llhudicon.h
|
||||
llhudmanager.h
|
||||
llhudnametag.h
|
||||
|
|
@ -1040,6 +1045,7 @@ set(viewer_HEADER_FILES
|
|||
llinventorygallerymenu.h
|
||||
llinventoryicon.h
|
||||
llinventoryitemslist.h
|
||||
llinventorylistener.h
|
||||
llinventorylistitem.h
|
||||
llinventorymodel.h
|
||||
llinventorymodelbackgroundfetch.h
|
||||
|
|
@ -1664,7 +1670,7 @@ set(viewer_APPSETTINGS_FILES
|
|||
app_settings/toolbars.xml
|
||||
app_settings/trees.xml
|
||||
app_settings/viewerart.xml
|
||||
${CMAKE_SOURCE_DIR}/../etc/message.xml
|
||||
app_settings/message.xml
|
||||
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
|
||||
packages-info.txt
|
||||
featuretable.txt
|
||||
|
|
@ -1758,7 +1764,7 @@ if (WINDOWS)
|
|||
|
||||
set(COPY_INPUT_DEPENDENCIES
|
||||
# The following commented dependencies are determined at variably at build time. Can't do this here.
|
||||
${CMAKE_SOURCE_DIR}/../etc/message.xml
|
||||
app_settings/message.xml
|
||||
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
|
||||
${SHARED_LIB_STAGING_DIR}/openjp2.dll
|
||||
${SHARED_LIB_STAGING_DIR}/llwebrtc.dll
|
||||
|
|
@ -2187,9 +2193,6 @@ if (DARWIN)
|
|||
--grid=${GRID}
|
||||
--source=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
|
||||
DEPENDS
|
||||
${VIEWER_BINARY_NAME}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
|
||||
)
|
||||
|
||||
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_libvlc media_plugin_cef)
|
||||
|
|
@ -2224,8 +2227,6 @@ if (DARWIN)
|
|||
--touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/.${product}.bat
|
||||
--versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
|
||||
${SIGNING_SETTING}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
|
||||
)
|
||||
endif (PACKAGE)
|
||||
endif (DARWIN)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
7.2.0
|
||||
7.2.1
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@
|
|||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<real>300.0</real>
|
||||
<real>300</real>
|
||||
</map>
|
||||
<key>AckCollectTime</key>
|
||||
<map>
|
||||
|
|
@ -1159,7 +1159,7 @@
|
|||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>ShowDiscordActivityDetails</key>
|
||||
<map>
|
||||
|
|
@ -1908,6 +1908,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugSelectionLODs</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force selection to show specific LOD, -1 for off, 0 - lowest, 4 - high.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<key>AnimatedObjectsAllowLeftClick</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -14295,10 +14306,32 @@
|
|||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OutfitGallerySortByName</key>
|
||||
<key>OutfitGallerySortOrder</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Always sort outfits by name in Outfit Gallery</string>
|
||||
<string>Gallery sorting: 0 - sort outfits by name, 1 - images frst, 2 - favorites first</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OutfitListSortOrder</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>How outfit list in Avatar's floater is sorted. 0 - by name 1 - favorites to top</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>OutfitListFilterFullList</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string> 0 - show only matches. 1 - show all items in outfit as long as outfit or item inside matches.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -16179,6 +16212,50 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>InventoryFavoritesUseStar</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show star near favorited items in inventory</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>InventoryFavoritesUseHollowStar</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Show star near folders that contain favorites</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>InventoryFavoritesColorText</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>render favorite items using InventoryFavoriteText as color</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>InventoryAddAttachmentBehavior</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Defines behavior when hitting return on an inventory item</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>StatsReportMaxDuration</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@
|
|||
<key>KeepConversationLogTranscripts</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Keep a conversation log and transcripts</string>
|
||||
<string>Keep a conversation log and transcripts 2 - both, 1 - logs, 0 - none</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
|
|||
|
|
@ -589,7 +589,9 @@ bool Asset::prep()
|
|||
|
||||
for (U32 variant = 0; variant < LLGLSLShader::NUM_GLTF_VARIANTS; ++variant)
|
||||
{
|
||||
#ifdef SHOW_ASSERT
|
||||
U32 attribute_mask = 0;
|
||||
#endif
|
||||
// for each mesh
|
||||
for (auto& mesh : mMeshes)
|
||||
{
|
||||
|
|
@ -607,7 +609,9 @@ bool Asset::prep()
|
|||
|
||||
// all primitives of a given variant and material should all have the same attribute mask
|
||||
llassert(attribute_mask == 0 || primitive.mAttributeMask == attribute_mask);
|
||||
#ifdef SHOW_ASSERT
|
||||
attribute_mask |= primitive.mAttributeMask;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ void GLTFSceneManager::uploadSelection()
|
|||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
expected_upload_cost,
|
||||
LLUUID::null,
|
||||
false,
|
||||
finish,
|
||||
failure));
|
||||
|
|
@ -283,6 +284,7 @@ void GLTFSceneManager::uploadSelection()
|
|||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
expected_upload_cost,
|
||||
LLUUID::null,
|
||||
false,
|
||||
finish,
|
||||
failure));
|
||||
|
|
@ -559,6 +561,7 @@ void GLTFSceneManager::update()
|
|||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
expected_upload_cost,
|
||||
LLUUID::null,
|
||||
false,
|
||||
finish,
|
||||
failure));
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ const F32 MIN_FIDGET_TIME = 8.f; // seconds
|
|||
const F32 MAX_FIDGET_TIME = 20.f; // seconds
|
||||
|
||||
const S32 UI_FEATURE_VERSION = 1;
|
||||
// For version 1: 1 - inventory, 2 - gltf
|
||||
const S32 UI_FEATURE_FLAGS = 3;
|
||||
// For version 1, flag holds: 1 - inventory thumbnails, 2 - gltf, 4 - inventory favorites
|
||||
const S32 UI_FEATURE_FLAGS = 7;
|
||||
|
||||
// The agent instance.
|
||||
LLAgent gAgent;
|
||||
|
|
@ -223,7 +223,6 @@ private:
|
|||
LLVector3d mPosGlobal;
|
||||
};
|
||||
|
||||
|
||||
class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation
|
||||
{
|
||||
public:
|
||||
|
|
@ -604,7 +603,7 @@ void LLAgent::getFeatureVersionAndFlags(S32& version, S32& flags)
|
|||
if (feature_version.isInteger())
|
||||
{
|
||||
version = feature_version.asInteger();
|
||||
flags = 1; // inventory flag
|
||||
flags = 3; // show 'favorites' notification
|
||||
}
|
||||
else if (feature_version.isMap())
|
||||
{
|
||||
|
|
@ -630,13 +629,8 @@ void LLAgent::showLatestFeatureNotification(const std::string key)
|
|||
|
||||
if (key == "inventory")
|
||||
{
|
||||
// Notify user about new thumbnail support
|
||||
flag = 1;
|
||||
}
|
||||
|
||||
if (key == "gltf")
|
||||
{
|
||||
flag = 2;
|
||||
// Notify user about new favorites support
|
||||
flag = 4;
|
||||
}
|
||||
|
||||
if ((flags & flag) == 0)
|
||||
|
|
@ -843,7 +837,6 @@ void LLAgent::movePitch(F32 mag)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Does this parcel allow you to fly?
|
||||
bool LLAgent::canFly()
|
||||
{
|
||||
|
|
@ -923,7 +916,6 @@ void LLAgent::setFlying(bool fly, bool fail_sound)
|
|||
LLFloaterMove::setFlyingMode(fly);
|
||||
}
|
||||
|
||||
|
||||
// UI based mechanism of setting fly state
|
||||
//-----------------------------------------------------------------------------
|
||||
// toggleFlying()
|
||||
|
|
@ -1002,7 +994,6 @@ void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id, LLViewerRegion
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setRegion()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1108,7 +1099,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
|
|||
mRegionChangedSignal();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getRegion()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1117,7 +1107,6 @@ LLViewerRegion *LLAgent::getRegion() const
|
|||
return mRegionp;
|
||||
}
|
||||
|
||||
|
||||
LLHost LLAgent::getRegionHost() const
|
||||
{
|
||||
if (mRegionp)
|
||||
|
|
@ -1148,7 +1137,6 @@ bool LLAgent::inPrelude()
|
|||
return mRegionp && mRegionp->isPrelude();
|
||||
}
|
||||
|
||||
|
||||
std::string LLAgent::getRegionCapability(const std::string &name)
|
||||
{
|
||||
if (!mRegionp)
|
||||
|
|
@ -1157,7 +1145,6 @@ std::string LLAgent::getRegionCapability(const std::string &name)
|
|||
return mRegionp->getCapability(name);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// canManageEstate()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1185,7 +1172,6 @@ void LLAgent::sendMessage()
|
|||
gMessageSystem->sendMessage(mRegionp->getHost());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// sendReliableMessage()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1219,7 +1205,6 @@ LLVector3 LLAgent::getVelocity() const
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setPositionAgent()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1293,7 +1278,6 @@ const LLVector3 &LLAgent::getPositionAgent()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return mFrameAgent.getOrigin();
|
||||
}
|
||||
|
||||
|
|
@ -1302,7 +1286,6 @@ boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot
|
|||
return mOnPositionChanged.connect(fn);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getRegionsVisited()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1319,7 +1302,6 @@ F64 LLAgent::getDistanceTraveled() const
|
|||
return mDistanceTraveled;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getPosAgentFromGlobal()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1330,7 +1312,6 @@ LLVector3 LLAgent::getPosAgentFromGlobal(const LLVector3d &pos_global) const
|
|||
return pos_agent;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getPosGlobalFromAgent()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1346,7 +1327,6 @@ void LLAgent::sitDown()
|
|||
setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// resetAxes()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1355,7 +1335,6 @@ void LLAgent::resetAxes()
|
|||
mFrameAgent.resetAxes();
|
||||
}
|
||||
|
||||
|
||||
// Copied from LLCamera::setOriginAndLookAt
|
||||
// Look_at must be unit vector
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1384,7 +1363,6 @@ void LLAgent::resetAxes(const LLVector3 &look_at)
|
|||
mFrameAgent.setAxes(look_at, left, up);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// rotate()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1393,7 +1371,6 @@ void LLAgent::rotate(F32 angle, const LLVector3 &axis)
|
|||
mFrameAgent.rotate(angle, axis);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// rotate()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1402,7 +1379,6 @@ void LLAgent::rotate(F32 angle, F32 x, F32 y, F32 z)
|
|||
mFrameAgent.rotate(angle, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// rotate()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1411,7 +1387,6 @@ void LLAgent::rotate(const LLMatrix3 &matrix)
|
|||
mFrameAgent.rotate(matrix);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// rotate()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1420,7 +1395,6 @@ void LLAgent::rotate(const LLQuaternion &quaternion)
|
|||
mFrameAgent.rotate(quaternion);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getReferenceUpVector()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1449,7 +1423,6 @@ LLVector3 LLAgent::getReferenceUpVector()
|
|||
return up_vector;
|
||||
}
|
||||
|
||||
|
||||
// Radians, positive is forward into ground
|
||||
//-----------------------------------------------------------------------------
|
||||
// pitch()
|
||||
|
|
@ -1493,7 +1466,6 @@ void LLAgent::pitch(F32 angle)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// roll()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1502,7 +1474,6 @@ void LLAgent::roll(F32 angle)
|
|||
mFrameAgent.roll(angle);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// yaw()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1514,7 +1485,6 @@ void LLAgent::yaw(F32 angle)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns a quat that represents the rotation of the agent in the absolute frame
|
||||
//-----------------------------------------------------------------------------
|
||||
// getQuat()
|
||||
|
|
@ -1540,7 +1510,6 @@ void LLAgent::setControlFlags(U32 mask)
|
|||
mControlFlags |= mask;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// clearControlFlags()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1628,7 +1597,6 @@ bool LLAgent::isDoNotDisturb() const
|
|||
return mIsDoNotDisturb;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// startAutoPilotGlobal()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1734,7 +1702,6 @@ void LLAgent::startAutoPilotGlobal(
|
|||
mAutoPilotNoProgressFrameCount = 0;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setAutoPilotTargetGlobal
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1788,7 +1755,6 @@ void LLAgent::startFollowPilot(const LLUUID &leader_id, bool allow_flying, F32 s
|
|||
allow_flying);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// stopAutoPilot()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1830,7 +1796,6 @@ void LLAgent::stopAutoPilot(bool user_cancel)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns necessary agent pitch and yaw changes, radians.
|
||||
//-----------------------------------------------------------------------------
|
||||
// autoPilot()
|
||||
|
|
@ -2019,7 +1984,6 @@ void LLAgent::autoPilot(F32 *delta_yaw)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// propagate()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2040,18 +2004,19 @@ void LLAgent::propagate(const F32 dt)
|
|||
}
|
||||
|
||||
// handle rotation based on keyboard levels
|
||||
constexpr F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second
|
||||
F32 angle = YAW_RATE * gAgentCamera.getYawKey() * dt;
|
||||
if (fabs(angle) > 0.0f)
|
||||
if (fabs(dt) > 1e-6)
|
||||
{
|
||||
yaw(angle);
|
||||
if (fabs(gAgentCamera.getYawKey()) > 1e-6)
|
||||
{
|
||||
static const F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second
|
||||
yaw(YAW_RATE * gAgentCamera.getYawKey() * dt);
|
||||
}
|
||||
|
||||
constexpr F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second
|
||||
angle = PITCH_RATE * gAgentCamera.getPitchKey() * dt;
|
||||
if (fabs(angle) > 0.0f)
|
||||
if (fabs(gAgentCamera.getPitchKey()) > 1e-6)
|
||||
{
|
||||
pitch(angle);
|
||||
static const F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second
|
||||
pitch(PITCH_RATE * gAgentCamera.getPitchKey() * dt);
|
||||
}
|
||||
}
|
||||
|
||||
// handle auto-land behavior
|
||||
|
|
@ -2213,7 +2178,6 @@ void LLAgent::clearRenderState(U8 clearstate)
|
|||
mRenderState &= ~clearstate;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getRenderState()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2255,6 +2219,7 @@ void LLAgent::endAnimationUpdateUI()
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (gAgentCamera.getCameraMode() == gAgentCamera.getLastCameraMode())
|
||||
{
|
||||
// We're already done endAnimationUpdateUI for this transition.
|
||||
|
|
@ -2320,7 +2285,6 @@ void LLAgent::endAnimationUpdateUI()
|
|||
mViewsPushed = false;
|
||||
}
|
||||
|
||||
|
||||
gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
|
||||
if( gMorphView )
|
||||
{
|
||||
|
|
@ -2952,7 +2916,6 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferredMaturity)
|
||||
{
|
||||
U8 maturity = SIM_ACCESS_MIN;
|
||||
|
|
@ -3022,7 +2985,6 @@ void LLAgent::changeInterestListMode(const std::string &new_mode)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure)
|
||||
{
|
||||
if (getRegion())
|
||||
|
|
@ -3349,7 +3311,6 @@ void LLAgent::sendAnimationStateReset()
|
|||
sendReliableMessage();
|
||||
}
|
||||
|
||||
|
||||
// Send a message to the region to revoke sepecified permissions on ALL scripts in the region
|
||||
// If the target is an object in the region, permissions in scripts on that object are cleared.
|
||||
// If it is the region ID, all scripts clear the permissions for this agent
|
||||
|
|
@ -3469,14 +3430,11 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
|
|||
|
||||
bool LLAgent::leftButtonGrabbed() const
|
||||
{
|
||||
if (gAgentCamera.cameraMouselook())
|
||||
{
|
||||
return mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0;
|
||||
}
|
||||
const bool camera_mouse_look = gAgentCamera.cameraMouselook();
|
||||
return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
|
||||
|| (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
|
||||
|| (!camera_mouse_look && mControlsTakenPassedOnCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
|
||||
|| (camera_mouse_look && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
|
||||
}
|
||||
|
||||
bool LLAgent::rotateGrabbed() const
|
||||
|
|
@ -4282,7 +4240,6 @@ void LLAgent::onCapabilitiesReceivedAfterTeleport()
|
|||
check_merchant_status();
|
||||
}
|
||||
|
||||
|
||||
void LLAgent::teleportRequest(
|
||||
const U64& region_handle,
|
||||
const LLVector3& pos_local,
|
||||
|
|
@ -4396,7 +4353,6 @@ void LLAgent::doTeleportViaLure(const LLUUID& lure_id, bool godlike)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// James Cook, July 28, 2005
|
||||
void LLAgent::teleportCancel()
|
||||
{
|
||||
|
|
@ -4521,7 +4477,6 @@ LLAgent::ETeleportState LLAgent::getTeleportState() const
|
|||
TELEPORT_NONE : mTeleportState;
|
||||
}
|
||||
|
||||
|
||||
void LLAgent::setTeleportState(ETeleportState state)
|
||||
{
|
||||
if (mTeleportRequest && (state != TELEPORT_NONE) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed))
|
||||
|
|
@ -4566,7 +4521,6 @@ void LLAgent::setTeleportState(ETeleportState state)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAgent::stopCurrentAnimations()
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "Stopping current animations" << LL_ENDL;
|
||||
|
|
@ -4681,7 +4635,6 @@ void LLAgent::stopFidget()
|
|||
gAgent.sendAnimationRequests(anims, ANIM_REQUEST_STOP);
|
||||
}
|
||||
|
||||
|
||||
void LLAgent::requestEnterGodMode()
|
||||
{
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
|
|
@ -4802,7 +4755,6 @@ void LLAgent::sendAgentUpdateUserInfo(const std::string& directory_visibility)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLAgent::updateAgentUserInfoCoro(std::string capurl, std::string directory_visibility)
|
||||
{
|
||||
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
|
||||
|
|
|
|||
|
|
@ -1462,13 +1462,12 @@ void LLAgentCamera::updateCamera()
|
|||
// LL_INFOS() << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << LL_ENDL;
|
||||
|
||||
LLVector3 focus_agent = gAgent.getPosAgentFromGlobal(mFocusGlobal);
|
||||
LLVector3 position_agent = gAgent.getPosAgentFromGlobal(camera_pos_global);
|
||||
|
||||
mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global);
|
||||
// Try to move the camera
|
||||
|
||||
// Move the camera
|
||||
|
||||
LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
|
||||
//LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
|
||||
if (!LLViewerCamera::getInstance()->updateCameraLocation(position_agent, mCameraUpVector, focus_agent))
|
||||
return;
|
||||
|
||||
// Change FOV
|
||||
LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
|
||||
|
|
@ -1476,7 +1475,7 @@ void LLAgentCamera::updateCamera()
|
|||
// follow camera when in customize mode
|
||||
if (cameraCustomizeAvatar())
|
||||
{
|
||||
setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
|
||||
setLookAt(LOOKAT_TARGET_FOCUS, NULL, position_agent);
|
||||
}
|
||||
|
||||
// update the travel distance stat
|
||||
|
|
@ -1495,8 +1494,8 @@ void LLAgentCamera::updateCamera()
|
|||
LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() +
|
||||
LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() +
|
||||
LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();
|
||||
LLVector3 diff = mCameraPositionAgent - head_pos;
|
||||
diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();
|
||||
LLVector3 diff = position_agent - head_pos;
|
||||
diff *= ~gAgentAvatarp->mRoot->getWorldRotation();
|
||||
|
||||
LLJoint* torso_joint = gAgentAvatarp->mTorsop;
|
||||
LLJoint* chest_joint = gAgentAvatarp->mChestp;
|
||||
|
|
@ -1753,7 +1752,6 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor()
|
|||
LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(bool *hit_limit)
|
||||
{
|
||||
// Compute base camera position and look-at points.
|
||||
F32 camera_land_height;
|
||||
LLVector3d frame_center_global = !isAgentAvatarValid() ?
|
||||
gAgent.getPositionGlobal() :
|
||||
gAgent.getPosGlobalFromAgent(getAvatarRootPosition());
|
||||
|
|
@ -1990,10 +1988,11 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(bool *hit_limit)
|
|||
}
|
||||
}
|
||||
|
||||
// Don't let camera go underground
|
||||
F32 camera_min_off_ground = getCameraMinOffGround();
|
||||
camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global);
|
||||
F32 minZ = llmax(F_ALMOST_ZERO, camera_land_height + camera_min_off_ground);
|
||||
// Don't let camera go underground if constrained
|
||||
// If not constrained, permit going 1000m below 0, use case: retrieving objects
|
||||
F32 camera_min_off_ground = getCameraMinOffGround(); // checks isDisableCameraConstraints
|
||||
F32 camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global);
|
||||
F32 minZ = camera_land_height + camera_min_off_ground;
|
||||
if (camera_position_global.mdV[VZ] < minZ)
|
||||
{
|
||||
camera_position_global.mdV[VZ] = minZ;
|
||||
|
|
@ -2256,7 +2255,8 @@ void LLAgentCamera::changeCameraToFollow(bool animate)
|
|||
mCameraMode = CAMERA_MODE_FOLLOW;
|
||||
|
||||
// bang-in the current focus, position, and up vector of the follow cam
|
||||
mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis);
|
||||
const LLViewerCamera& camera = LLViewerCamera::instance();
|
||||
mFollowCam.reset(camera.getOrigin(), camera.getPointOfInterest(), LLVector3::z_axis);
|
||||
|
||||
if (gBasicToolset)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ private:
|
|||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void switchCameraPreset(ECameraPreset preset);
|
||||
ECameraPreset getCameraPreset() const { return mCameraPreset; }
|
||||
/** Determines default camera offset depending on the current camera preset */
|
||||
LLVector3 getCameraOffsetInitial();
|
||||
/** Determines default focus offset depending on the current camera preset */
|
||||
|
|
@ -143,8 +144,9 @@ public:
|
|||
F32 getCameraMinOffGround(); // Minimum height off ground for this mode, meters
|
||||
void setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; }
|
||||
bool calcCameraMinDistance(F32 &obj_min_distance);
|
||||
F32 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); }
|
||||
F32 getCurrentCameraBuildOffset() const { return (F32)mCameraFocusOffset.length(); }
|
||||
void clearCameraLag() { mCameraLag.clearVec(); }
|
||||
const LLVector3& getCameraUpVector() const { return mCameraUpVector; }
|
||||
private:
|
||||
LLVector3 getAvatarRootPosition();
|
||||
|
||||
|
|
@ -154,7 +156,6 @@ private:
|
|||
F32 mCameraCurrentFOVZoomFactor; // Interpolated fov zoom
|
||||
LLVector4 mCameraCollidePlane; // Colliding plane for camera
|
||||
F32 mCameraZoomFraction; // Mousewheel driven fraction of zoom
|
||||
LLVector3 mCameraPositionAgent; // Camera position in agent coordinates
|
||||
LLVector3 mCameraVirtualPositionAgent; // Camera virtual position (target) before performing FOV zoom
|
||||
LLVector3d mCameraSmoothingLastPositionGlobal;
|
||||
LLVector3d mCameraSmoothingLastPositionAgent;
|
||||
|
|
@ -278,7 +279,7 @@ public:
|
|||
F32 getAgentHUDTargetZoom();
|
||||
|
||||
void resetCameraZoomFraction();
|
||||
F32 getCurrentCameraZoomFraction() { return mCameraZoomFraction; }
|
||||
F32 getCurrentCameraZoomFraction() const { return mCameraZoomFraction; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Pan
|
||||
|
|
|
|||
|
|
@ -322,9 +322,7 @@ void LLAgentPilot::moveCamera()
|
|||
|
||||
LLViewerCamera::getInstance()->setView(view);
|
||||
LLViewerCamera::getInstance()->setOrigin(origin);
|
||||
LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]);
|
||||
LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]);
|
||||
LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]);
|
||||
LLViewerCamera::getInstance()->setAxes(mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -839,7 +839,7 @@ void AISAPI::onUpdateReceived(const LLSD& update, COMMAND_TYPE type, const LLSD&
|
|||
if ( (type == UPDATECATEGORY || type == UPDATEITEM)
|
||||
&& gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
|
||||
{
|
||||
dump_sequential_xml(gAgentAvatarp->getFullname() + "_ais_update", update);
|
||||
dump_sequential_xml(gAgentAvatarp->getDebugName() + "_ais_update", update);
|
||||
}
|
||||
|
||||
AISUpdate ais_update(update, type, request_body);
|
||||
|
|
|
|||
|
|
@ -2045,7 +2045,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
|
|||
}
|
||||
|
||||
// Moved from LLWearableList::ContextMenu for wider utility.
|
||||
bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const
|
||||
bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids, bool warn_on_type_mismatch) const
|
||||
{
|
||||
// TODO: investigate wearables may not be loaded at this point EXT-8231
|
||||
|
||||
|
|
@ -2074,8 +2074,11 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const
|
|||
return isAgentAvatarValid();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (warn_on_type_mismatch)
|
||||
{
|
||||
LL_WARNS() << "Unexpected wearable type" << LL_ENDL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2266,7 +2269,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
|
|||
}
|
||||
if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
|
||||
{
|
||||
dump_sequential_xml(gAgentAvatarp->getFullname() + "_slam_request", contents);
|
||||
dump_sequential_xml(gAgentAvatarp->getDebugName() + "_slam_request", contents);
|
||||
}
|
||||
slam_inventory_folder(getCOF(), contents, link_waiter);
|
||||
|
||||
|
|
@ -3959,7 +3962,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
|
|||
LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
|
||||
if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
|
||||
{
|
||||
dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", result);
|
||||
dump_sequential_xml(gAgentAvatarp->getDebugName() + "_appearance_request_ok", result);
|
||||
}
|
||||
|
||||
} while (bRetry);
|
||||
|
|
@ -3968,7 +3971,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
|
|||
/*static*/
|
||||
void LLAppearanceMgr::debugAppearanceUpdateCOF(const LLSD& content)
|
||||
{
|
||||
dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
|
||||
dump_sequential_xml(gAgentAvatarp->getDebugName() + "_appearance_request_error", content);
|
||||
|
||||
LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
|
||||
<< " ================================= " << LL_ENDL;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public:
|
|||
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Can we add all referenced items to the avatar?
|
||||
bool canAddWearables(const uuid_vec_t& item_ids) const;
|
||||
bool canAddWearables(const uuid_vec_t& item_ids, bool warn_on_type_mismatch = true) const;
|
||||
|
||||
// Copy all items in a category.
|
||||
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
|
|
|
|||
|
|
@ -453,14 +453,29 @@ static bool app_metrics_qa_mode = false;
|
|||
|
||||
void idle_afk_check()
|
||||
{
|
||||
// Don't check AFK status during startup states
|
||||
if (LLStartUp::getStartupState() < STATE_STARTED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check idle timers
|
||||
F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32();
|
||||
static LLCachedControl<S32> afk_timeout(gSavedSettings, "AFKTimeout", 300);
|
||||
if (afk_timeout() && (current_idle > (F32)afk_timeout()) && !gAgent.getAFK())
|
||||
if (afk_timeout() && (current_idle > afk_timeout()))
|
||||
{
|
||||
if (!gAgent.getAFK())
|
||||
{
|
||||
LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL;
|
||||
gAgent.setAFK();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Refresh timer so that random one click or hover won't clear the status.
|
||||
// But expanding the window still should lift afk status
|
||||
gAwayTimer.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A callback set in LLAppViewer::init()
|
||||
|
|
@ -1852,36 +1867,6 @@ bool LLAppViewer::cleanup()
|
|||
// Clean up before GL is shut down because we might be holding on to objects with texture references
|
||||
LLSelectMgr::cleanupGlobals();
|
||||
|
||||
LL_INFOS() << "Shutting down OpenGL" << LL_ENDL;
|
||||
|
||||
// Shut down OpenGL
|
||||
if( gViewerWindow)
|
||||
{
|
||||
gViewerWindow->shutdownGL();
|
||||
|
||||
// Destroy window, and make sure we're not fullscreen
|
||||
// This may generate window reshape and activation events.
|
||||
// Therefore must do this before destroying the message system.
|
||||
delete gViewerWindow;
|
||||
gViewerWindow = NULL;
|
||||
LL_INFOS() << "ViewerWindow deleted" << LL_ENDL;
|
||||
}
|
||||
|
||||
LLSplashScreen::show();
|
||||
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
|
||||
|
||||
LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;
|
||||
|
||||
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
|
||||
delete gKeyboard;
|
||||
gKeyboard = NULL;
|
||||
|
||||
if (LLViewerJoystick::instanceExists())
|
||||
{
|
||||
// Turn off Space Navigator and similar devices
|
||||
LLViewerJoystick::getInstance()->terminate();
|
||||
}
|
||||
|
||||
LL_INFOS() << "Cleaning up Objects" << LL_ENDL;
|
||||
|
||||
LLViewerObject::cleanupVOClasses();
|
||||
|
|
@ -2042,6 +2027,36 @@ bool LLAppViewer::cleanup()
|
|||
sTextureFetch->shutDownTextureCacheThread() ;
|
||||
LLLFSThread::sLocal->shutdown();
|
||||
|
||||
LL_INFOS() << "Shutting down OpenGL" << LL_ENDL;
|
||||
|
||||
// Shut down OpenGL
|
||||
if (gViewerWindow)
|
||||
{
|
||||
gViewerWindow->shutdownGL();
|
||||
|
||||
// Destroy window, and make sure we're not fullscreen
|
||||
// This may generate window reshape and activation events.
|
||||
// Therefore must do this before destroying the message system.
|
||||
delete gViewerWindow;
|
||||
gViewerWindow = NULL;
|
||||
LL_INFOS() << "ViewerWindow deleted" << LL_ENDL;
|
||||
}
|
||||
|
||||
LLSplashScreen::show();
|
||||
LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
|
||||
|
||||
LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL;
|
||||
|
||||
// viewer UI relies on keyboard so keep it aound until viewer UI isa gone
|
||||
delete gKeyboard;
|
||||
gKeyboard = NULL;
|
||||
|
||||
if (LLViewerJoystick::instanceExists())
|
||||
{
|
||||
// Turn off Space Navigator and similar devices
|
||||
LLViewerJoystick::getInstance()->terminate();
|
||||
}
|
||||
|
||||
LL_INFOS() << "Shutting down message system" << LL_ENDL;
|
||||
end_messaging_system();
|
||||
|
||||
|
|
@ -4527,6 +4542,7 @@ void LLAppViewer::forceDisconnect(const std::string& mesg)
|
|||
}
|
||||
else
|
||||
{
|
||||
sendSimpleLogoutRequest();
|
||||
args["MESSAGE"] = big_reason;
|
||||
LLNotificationsUtil::add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect );
|
||||
}
|
||||
|
|
@ -5307,6 +5323,27 @@ void LLAppViewer::sendLogoutRequest()
|
|||
}
|
||||
}
|
||||
|
||||
void LLAppViewer::sendSimpleLogoutRequest()
|
||||
{
|
||||
if (!mLogoutRequestSent && gMessageSystem)
|
||||
{
|
||||
gLogoutInProgress = true;
|
||||
|
||||
LLMessageSystem* msg = gMessageSystem;
|
||||
msg->newMessageFast(_PREHASH_LogoutRequest);
|
||||
msg->nextBlockFast(_PREHASH_AgentData);
|
||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
LL_INFOS("Agent") << "Logging out as agent: " << gAgent.getID() << " Session: " << gAgent.getSessionID() << LL_ENDL;
|
||||
|
||||
gLogoutTimer.reset();
|
||||
gLogoutMaxTime = LOGOUT_REQUEST_TIME;
|
||||
mLogoutRequestSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLAppViewer::updateNameLookupUrl(const LLViewerRegion * regionp)
|
||||
{
|
||||
if (!regionp || !regionp->capabilitiesReceived())
|
||||
|
|
@ -5926,100 +5963,21 @@ void LLAppViewer::initDiscordSocial()
|
|||
gDiscordPartyMaxSize = 0;
|
||||
gDiscordTimestampsStart = time(nullptr);
|
||||
gDiscordClient = std::make_shared<discordpp::Client>();
|
||||
gDiscordClient->SetStatusChangedCallback([](discordpp::Client::Status status, discordpp::Client::Error, int32_t) {
|
||||
if (status == discordpp::Client::Status::Ready)
|
||||
{
|
||||
gDiscordClient->SetApplicationId(1394782217405862001);
|
||||
updateDiscordActivity();
|
||||
}
|
||||
});
|
||||
if (gSavedSettings.getBOOL("EnableDiscord"))
|
||||
{
|
||||
auto credential = gSecAPIHandler->loadCredential("Discord");
|
||||
if (credential.notNull())
|
||||
{
|
||||
gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) {
|
||||
if (result.Successful())
|
||||
gDiscordClient->Connect();
|
||||
else
|
||||
LL_WARNS("Discord") << result.Error() << LL_ENDL;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Discord") << "Integration was enabled, but no credentials. Disabling integration." << LL_ENDL;
|
||||
gSavedSettings.setBOOL("EnableDiscord", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLAppViewer::toggleDiscordIntegration(const LLSD& value)
|
||||
{
|
||||
static const uint64_t APPLICATION_ID = 1394782217405862001;
|
||||
if (value.asBoolean())
|
||||
{
|
||||
discordpp::AuthorizationArgs args{};
|
||||
args.SetClientId(APPLICATION_ID);
|
||||
args.SetScopes(discordpp::Client::GetDefaultPresenceScopes());
|
||||
auto codeVerifier = gDiscordClient->CreateAuthorizationCodeVerifier();
|
||||
args.SetCodeChallenge(codeVerifier.Challenge());
|
||||
gDiscordClient->Authorize(args, [codeVerifier](auto result, auto code, auto redirectUri) {
|
||||
if (result.Successful())
|
||||
{
|
||||
gDiscordClient->GetToken(APPLICATION_ID, code, codeVerifier.Verifier(), redirectUri, [](discordpp::ClientResult result, std::string accessToken, std::string, discordpp::AuthorizationTokenType, int32_t, std::string) {
|
||||
if (result.Successful())
|
||||
{
|
||||
gDiscordClient->UpdateToken(discordpp::AuthorizationTokenType::Bearer, accessToken, [accessToken](discordpp::ClientResult result) {
|
||||
if (result.Successful())
|
||||
{
|
||||
LLSD authenticator = LLSD::emptyMap();
|
||||
authenticator["token"] = accessToken;
|
||||
gSecAPIHandler->saveCredential(gSecAPIHandler->createCredential("Discord", LLSD::emptyMap(), authenticator), true);
|
||||
gDiscordClient->Connect();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Discord") << result.Error() << LL_ENDL;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Discord") << result.Error() << LL_ENDL;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Discord") << result.Error() << LL_ENDL;
|
||||
gSavedSettings.setBOOL("EnableDiscord", false);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
gDiscordClient->Disconnect();
|
||||
auto credential = gSecAPIHandler->loadCredential("Discord");
|
||||
if (credential.notNull())
|
||||
{
|
||||
gDiscordClient->RevokeToken(APPLICATION_ID, credential->getAuthenticator()["token"].asString(), [](discordpp::ClientResult result) {
|
||||
if (result.Successful())
|
||||
LL_INFOS("Discord") << "Access token successfully revoked." << LL_ENDL;
|
||||
else
|
||||
LL_WARNS("Discord") << "No access token to revoke." << LL_ENDL;
|
||||
});
|
||||
auto cred = new LLCredential("Discord");
|
||||
gSecAPIHandler->deleteCredential(cred);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Discord") << "Credentials are already nonexistent." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLAppViewer::updateDiscordActivity()
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
static LLCachedControl<bool> integration_enabled(gSavedSettings, "EnableDiscord", true);
|
||||
if (!integration_enabled)
|
||||
{
|
||||
gDiscordClient->ClearRichPresence();
|
||||
return;
|
||||
}
|
||||
|
||||
discordpp::Activity activity;
|
||||
activity.SetType(discordpp::ActivityTypes::Playing);
|
||||
discordpp::ActivityTimestamps timestamps;
|
||||
|
|
@ -6047,9 +6005,6 @@ void LLAppViewer::updateDiscordActivity()
|
|||
activity.SetDetails(gDiscordActivityDetails);
|
||||
}
|
||||
|
||||
static LLCachedControl<bool> show_state(gSavedSettings, "ShowDiscordActivityState", false);
|
||||
if (show_state)
|
||||
{
|
||||
auto agent_pos_region = gAgent.getPositionAgent();
|
||||
S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f);
|
||||
S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f);
|
||||
|
|
@ -6069,7 +6024,13 @@ void LLAppViewer::updateDiscordActivity()
|
|||
pos_x -= pos_x % 2;
|
||||
pos_y -= pos_y % 2;
|
||||
}
|
||||
auto location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z);
|
||||
|
||||
std::string location = "Hidden Region";
|
||||
static LLCachedControl<bool> show_state(gSavedSettings, "ShowDiscordActivityState", false);
|
||||
if (show_state)
|
||||
{
|
||||
location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z);
|
||||
}
|
||||
activity.SetState(location);
|
||||
|
||||
discordpp::ActivityParty party;
|
||||
|
|
@ -6077,7 +6038,6 @@ void LLAppViewer::updateDiscordActivity()
|
|||
party.SetCurrentSize(gDiscordPartyCurrentSize);
|
||||
party.SetMaxSize(gDiscordPartyMaxSize);
|
||||
activity.SetParty(party);
|
||||
}
|
||||
|
||||
gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,7 +254,6 @@ public:
|
|||
|
||||
#ifdef LL_DISCORD
|
||||
static void initDiscordSocial();
|
||||
static void toggleDiscordIntegration(const LLSD& value);
|
||||
static void updateDiscordActivity();
|
||||
static void updateDiscordPartyCurrentSize(int32_t size);
|
||||
static void updateDiscordPartyMaxSize(int32_t size);
|
||||
|
|
@ -312,6 +311,10 @@ private:
|
|||
void sendLogoutRequest();
|
||||
void disconnectViewer();
|
||||
|
||||
// Does not create a marker file. For lost network case,
|
||||
// to at least attempt to remove the ghost from the world.
|
||||
void sendSimpleLogoutRequest();
|
||||
|
||||
// *FIX: the app viewer class should be some sort of singleton, no?
|
||||
// Perhaps its child class is the singleton and this should be an abstract base.
|
||||
static LLAppViewer* sInstance;
|
||||
|
|
|
|||
|
|
@ -536,11 +536,12 @@ LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::replaceList(const LL
|
|||
S32 search_index;
|
||||
LLSD targetList;
|
||||
// The following is working around the fact that LLSD arrays containing maps also seem to have undefined entries... see LLSD-30
|
||||
for ( search_index = 0, targetList = mLists[0];
|
||||
for ( search_index = 0;
|
||||
!listFound && search_index < mLists.size();
|
||||
search_index += 1, targetList = mLists[search_index]
|
||||
search_index += 1
|
||||
)
|
||||
{
|
||||
targetList = mLists[search_index];
|
||||
if ( targetList.isMap() )
|
||||
{
|
||||
if ( listNameMatches( targetList, listName) )
|
||||
|
|
|
|||
|
|
@ -189,7 +189,14 @@ public:
|
|||
std::string url = "secondlife://" + mObjectData["slurl"].asString();
|
||||
LLUrlAction::teleportToLocation(url);
|
||||
}
|
||||
|
||||
else if (level == "obj_zoom_in")
|
||||
{
|
||||
LLUUID obj_id = mObjectData["object_id"];
|
||||
if (obj_id.notNull())
|
||||
{
|
||||
handle_zoom_to_object(obj_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool onObjectIconContextMenuItemVisible(const LLSD& userdata)
|
||||
|
|
@ -203,6 +210,15 @@ public:
|
|||
{
|
||||
return !LLMuteList::getInstance()->isMuted(getAvatarId(), mFrom, LLMute::flagTextChat);
|
||||
}
|
||||
else if (level == "obj_zoom_in")
|
||||
{
|
||||
LLUUID obj_id = mObjectData["object_id"];
|
||||
if (obj_id.notNull())
|
||||
{
|
||||
return nullptr != gObjectList.findObject(mAvatarID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -936,7 +952,7 @@ protected:
|
|||
menu->setItemEnabled("Voice Call", false);
|
||||
menu->setItemEnabled("Chat History", false);
|
||||
menu->setItemEnabled("Invite Group", false);
|
||||
menu->setItemEnabled("Zoom In", false);
|
||||
menu->setItemEnabled("Zoom In", true);
|
||||
menu->setItemEnabled("Share", false);
|
||||
menu->setItemEnabled("Pay", false);
|
||||
menu->setItemEnabled("Block Unblock", false);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "lllocalcliprect.h"
|
||||
#include "lltrans.h"
|
||||
#include "llfloaterimnearbychat.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "llviewermenu.h"
|
||||
|
||||
#include "llviewercontrol.h"
|
||||
#include "llagentdata.h"
|
||||
|
|
@ -75,6 +77,23 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
if (verb == "zoomin")
|
||||
{
|
||||
if (!handle_zoom_to_object(object_id) && params.size() > 2)
|
||||
{
|
||||
// zoom faled, show location
|
||||
// secondlife:///app/object/object_id/zoomin/{LOCATION}/{COORDS} SLapp
|
||||
const std::string region_name = LLURI::unescape(params[0].asString());
|
||||
S32 x = (params.size() > 1) ? params[1].asInteger() : 128;
|
||||
S32 y = (params.size() > 2) ? params[2].asInteger() : 128;
|
||||
S32 z = (params.size() > 3) ? params[3].asInteger() : 0;
|
||||
|
||||
LLFloaterWorldMap::getInstance()->trackURL(region_name, x, y, z);
|
||||
LLFloaterReg::showInstance("world_map", "center");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -129,14 +129,14 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_
|
|||
{
|
||||
LLVector3 pos_box_offset = point_to_box_offset(vol_pos, unshift_extents);
|
||||
F32 offset_dist = pos_box_offset.length();
|
||||
if (offset_dist > MAX_LEGAL_OFFSET && offset_dist > 0.f)
|
||||
if (offset_dist > max_legal_offset && offset_dist > 0.f)
|
||||
{
|
||||
F32 target_dist = (offset_dist - MAX_LEGAL_OFFSET);
|
||||
F32 target_dist = (offset_dist - max_legal_offset);
|
||||
new_pos_fixup = (target_dist/offset_dist)*pos_box_offset;
|
||||
}
|
||||
if (new_pos_fixup != mPositionConstraintFixup)
|
||||
{
|
||||
LL_DEBUGS("ConstraintFix") << getFullname() << " pos fix, offset_dist " << offset_dist << " pos fixup "
|
||||
LL_DEBUGS("ConstraintFix") << getDebugName() << " pos fix, offset_dist " << offset_dist << " pos fixup "
|
||||
<< new_pos_fixup << " was " << mPositionConstraintFixup << LL_ENDL;
|
||||
LL_DEBUGS("ConstraintFix") << "vol_pos " << vol_pos << LL_ENDL;
|
||||
LL_DEBUGS("ConstraintFix") << "extents " << extents[0] << " " << extents[1] << LL_ENDL;
|
||||
|
|
@ -144,11 +144,11 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_
|
|||
|
||||
}
|
||||
}
|
||||
if (box_size/mScaleConstraintFixup > MAX_LEGAL_SIZE)
|
||||
if (box_size/mScaleConstraintFixup > max_legal_size)
|
||||
{
|
||||
new_scale_fixup = mScaleConstraintFixup* MAX_LEGAL_SIZE /box_size;
|
||||
LL_DEBUGS("ConstraintFix") << getFullname() << " scale fix, box_size " << box_size << " fixup "
|
||||
<< mScaleConstraintFixup << " max legal " << MAX_LEGAL_SIZE
|
||||
new_scale_fixup = mScaleConstraintFixup*max_legal_size/box_size;
|
||||
LL_DEBUGS("ConstraintFix") << getDebugName() << " scale fix, box_size " << box_size << " fixup "
|
||||
<< mScaleConstraintFixup << " max legal " << max_legal_size
|
||||
<< " -> new scale " << new_scale_fixup << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ void LLControlAvatar::matchVolumeTransform()
|
|||
const LLMeshSkinInfo* skin_info = mRootVolp->getSkinInfo();
|
||||
if (skin_info)
|
||||
{
|
||||
LL_DEBUGS("BindShape") << getFullname() << " bind shape " << skin_info->mBindShapeMatrix << LL_ENDL;
|
||||
LL_DEBUGS("BindShape") << getDebugName() << " bind shape " << skin_info->mBindShapeMatrix << LL_ENDL;
|
||||
bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(skin_info->mBindShapeMatrix));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -663,7 +663,7 @@ void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD&
|
|||
{
|
||||
mConversations.clear();
|
||||
notifyObservers();
|
||||
cache();
|
||||
saveToFile(getFileName());
|
||||
deleteBackupLogs();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic
|
|||
|
||||
for (auto itemp : mChildren)
|
||||
{
|
||||
LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp);
|
||||
LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp.get());
|
||||
// Add the avatar uuid to the list (except if it's the own agent uuid)
|
||||
if (current_participant->getUUID() != gAgentID)
|
||||
{
|
||||
|
|
@ -329,6 +329,7 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic
|
|||
|
||||
void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
|
||||
{
|
||||
LLPointer<LLFolderViewModelItem> holder(participant);
|
||||
removeChild(participant);
|
||||
mNeedsRefresh = true;
|
||||
updateName(participant);
|
||||
|
|
@ -360,15 +361,10 @@ void LLConversationItemSession::clearAndDeparentModels()
|
|||
for (child_list_t::iterator it = mChildren.begin(); it != mChildren.end();)
|
||||
{
|
||||
LLFolderViewModelItem* child = *it;
|
||||
if (child->getNumRefs() == 0)
|
||||
// Note that model might still be assigned to some view/widget
|
||||
// and have a different parent
|
||||
if (child->getParent() == this)
|
||||
{
|
||||
// LLConversationItemParticipant can be created but not assigned to any view,
|
||||
// it was waiting for an "add_participant" event to be processed
|
||||
delete child;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Model is still assigned to some view/widget
|
||||
child->setParent(NULL);
|
||||
}
|
||||
it = mChildren.erase(it);
|
||||
|
|
@ -383,7 +379,7 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const
|
|||
child_list_t::iterator iter;
|
||||
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
|
||||
{
|
||||
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
|
||||
participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get());
|
||||
if (participant && participant->hasSameValue(participant_id))
|
||||
{
|
||||
break;
|
||||
|
|
@ -493,7 +489,7 @@ const bool LLConversationItemSession::getTime(F64& time) const
|
|||
child_list_t::const_iterator iter;
|
||||
for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
|
||||
{
|
||||
participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
|
||||
participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get());
|
||||
F64 participant_time;
|
||||
if (participant && participant->getTime(participant_time))
|
||||
{
|
||||
|
|
@ -517,7 +513,7 @@ void LLConversationItemSession::dumpDebugData(bool dump_children)
|
|||
{
|
||||
for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++)
|
||||
{
|
||||
LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
|
||||
LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get());
|
||||
if (participant)
|
||||
{
|
||||
participant->dumpDebugData();
|
||||
|
|
|
|||
|
|
@ -79,6 +79,9 @@ public:
|
|||
virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
|
||||
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
|
||||
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
|
||||
virtual bool isFavorite() const { return false; }
|
||||
virtual bool isAgentInventory() const { return false; }
|
||||
virtual bool isAgentInventoryRoot() const { return false; }
|
||||
virtual bool isItemRenameable() const { return true; }
|
||||
virtual bool renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return true; }
|
||||
virtual bool isItemMovable( void ) const { return false; }
|
||||
|
|
|
|||
|
|
@ -143,7 +143,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
|
|||
gGL.setColorMask(true, true);
|
||||
|
||||
LLColor3 light_diffuse(0, 0, 0);
|
||||
F32 light_exp = 0.0f;
|
||||
|
||||
LLEnvironment& environment = LLEnvironment::instance();
|
||||
LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
|
||||
|
|
@ -170,7 +169,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
|
|||
// Apply magic numbers translating light direction into intensities
|
||||
light_dir.normalize();
|
||||
F32 ground_proj_sq = light_dir.mV[0] * light_dir.mV[0] + light_dir.mV[1] * light_dir.mV[1];
|
||||
light_exp = llmax(32.f, 256.f * powf(ground_proj_sq, 16.0f));
|
||||
if (0.f < light_diffuse.normalize()) // Normalizing a color? Puzzling...
|
||||
{
|
||||
light_diffuse *= (1.5f + (6.f * ground_proj_sq));
|
||||
|
|
|
|||
|
|
@ -422,7 +422,13 @@ bool LLFloaterAutoReplaceSettings::callbackNewListName(const LLSD& notification,
|
|||
|
||||
LLSD newList = notification["payload"]["list"];
|
||||
|
||||
if ( response.has("listname") && response["listname"].isString() )
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option != 1) // Must also match RenameAutoReplaceList
|
||||
{
|
||||
// user cancelled
|
||||
return false;
|
||||
}
|
||||
else if (response.has("listname") && response["listname"].isString() )
|
||||
{
|
||||
std::string newName = response["listname"].asString();
|
||||
LLAutoReplaceSettings::setListName(newList, newName);
|
||||
|
|
@ -508,12 +514,53 @@ bool LLFloaterAutoReplaceSettings::callbackListNameConflict(const LLSD& notifica
|
|||
return false;
|
||||
}
|
||||
|
||||
bool LLFloaterAutoReplaceSettings::callbackRemoveList(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
std::string listName = notification["payload"]["list"];
|
||||
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
switch (option)
|
||||
{
|
||||
case 1:
|
||||
if (mSettings.removeReplacementList(listName))
|
||||
{
|
||||
LL_INFOS("AutoReplace") << "deleted list '" << listName << "'" << LL_ENDL;
|
||||
mReplacementsList->deleteSelectedItems(); // remove from the scrolling list
|
||||
mSelectedListName.clear();
|
||||
updateListNames();
|
||||
updateListNamesControls();
|
||||
updateReplacementsList();
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
LL_ERRS("AutoReplace") << "invalid selected option " << option << LL_ENDL;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterAutoReplaceSettings::onDeleteList()
|
||||
{
|
||||
std::string listName = mListNames->getSelectedValue().asString();
|
||||
if ( ! listName.empty() )
|
||||
{
|
||||
if ( mSettings.removeReplacementList(listName) )
|
||||
const LLSD* mappings = mSettings.getListEntries(mSelectedListName);
|
||||
if (mappings->size() > 0)
|
||||
{
|
||||
LLSD payload;
|
||||
payload["list"] = listName;
|
||||
|
||||
LLSD args;
|
||||
args["MAP_SIZE"] = llformat("%d",mappings->size());
|
||||
args["LIST_NAME"] = listName;
|
||||
|
||||
LLNotificationsUtil::add("RemoveAutoReplaceList", args, payload,
|
||||
boost::bind(&LLFloaterAutoReplaceSettings::callbackRemoveList, this, _1, _2));
|
||||
}
|
||||
else if ( mSettings.removeReplacementList(listName) )
|
||||
{
|
||||
LL_INFOS("AutoReplace")<<"deleted list '"<<listName<<"'"<<LL_ENDL;
|
||||
mReplacementsList->deleteSelectedItems(); // remove from the scrolling list
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ private:
|
|||
bool callbackNewListName(const LLSD& notification, const LLSD& response);
|
||||
/// called from the RenameAutoReplaceList notification dialog
|
||||
bool callbackListNameConflict(const LLSD& notification, const LLSD& response);
|
||||
/// called from the RemoveAutoReplaceList notification dialog
|
||||
bool callbackRemoveList(const LLSD& notification, const LLSD& response);
|
||||
|
||||
bool selectedListIsFirst();
|
||||
bool selectedListIsLast();
|
||||
|
|
|
|||
|
|
@ -118,8 +118,8 @@ std::string STATUS[] =
|
|||
//-----------------------------------------------------------------------------
|
||||
// LLFloaterBvhPreview()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLFloaterBvhPreview::LLFloaterBvhPreview(const std::string& filename) :
|
||||
LLFloaterNameDesc(filename)
|
||||
LLFloaterBvhPreview::LLFloaterBvhPreview(const LLSD& args) :
|
||||
LLFloaterNameDesc(args)
|
||||
{
|
||||
mLastMouseX = 0;
|
||||
mLastMouseY = 0;
|
||||
|
|
@ -1028,7 +1028,8 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
|
|||
LLFloaterPerms::getNextOwnerPerms("Uploads"),
|
||||
LLFloaterPerms::getGroupPerms("Uploads"),
|
||||
LLFloaterPerms::getEveryonePerms("Uploads"),
|
||||
expected_upload_cost));
|
||||
expected_upload_cost,
|
||||
floaterp->mDestinationFolderId));
|
||||
|
||||
upload_new_resource(assetUploadInfo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ protected:
|
|||
class LLFloaterBvhPreview : public LLFloaterNameDesc
|
||||
{
|
||||
public:
|
||||
LLFloaterBvhPreview(const std::string& filename);
|
||||
LLFloaterBvhPreview(const LLSD& args);
|
||||
virtual ~LLFloaterBvhPreview();
|
||||
|
||||
bool postBuild();
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ uuid_vec_t LLFloaterChatMentionPicker::getParticipantIds()
|
|||
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
|
||||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
|
||||
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get());
|
||||
if (participant_model)
|
||||
{
|
||||
avatar_ids.push_back(participant_model->getUUID());
|
||||
|
|
|
|||
|
|
@ -133,7 +133,8 @@ protected:
|
|||
LLSettingsEditPanel() :
|
||||
LLPanel(),
|
||||
mIsDirty(false),
|
||||
mOnDirtyChanged()
|
||||
mOnDirtyChanged(),
|
||||
mCanEdit(false)
|
||||
{}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ const S32 PREVIEW_TEXTURE_HEIGHT = 320;
|
|||
//-----------------------------------------------------------------------------
|
||||
// LLFloaterImagePreview()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) :
|
||||
LLFloaterNameDesc(filename),
|
||||
LLFloaterImagePreview::LLFloaterImagePreview(const LLSD& args) :
|
||||
LLFloaterNameDesc(args),
|
||||
|
||||
mAvatarPreview(NULL),
|
||||
mSculptedPreview(NULL),
|
||||
|
|
@ -288,7 +288,9 @@ void LLFloaterImagePreview::onBtnOK()
|
|||
}
|
||||
else
|
||||
{
|
||||
LLNotificationsUtil::add("ErrorEncodingImage");
|
||||
LLSD args;
|
||||
args["REASON"] = LLImage::getLastThreadError();
|
||||
LLNotificationsUtil::add("ErrorEncodingImage", args);
|
||||
LL_WARNS() << "Error encoding image" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
|
@ -423,6 +425,18 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
// raw image is limited to 256MB so need at least some upper limit that fits into that
|
||||
constexpr S32 MAX_IMAGE_AREA = 8096 * 8096;
|
||||
|
||||
if (image_info.getWidth() * image_info.getHeight() > MAX_IMAGE_AREA)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["PIXELS"] = llformat("%dM", (S32)(MAX_IMAGE_AREA / 1000000));
|
||||
|
||||
mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the image
|
||||
LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
|
||||
if (image.isNull())
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ protected:
|
|||
class LLFloaterImagePreview : public LLFloaterNameDesc
|
||||
{
|
||||
public:
|
||||
LLFloaterImagePreview(const std::string& filename);
|
||||
LLFloaterImagePreview(const LLSD& args);
|
||||
virtual ~LLFloaterImagePreview();
|
||||
|
||||
bool postBuild() override;
|
||||
|
|
|
|||
|
|
@ -460,7 +460,7 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
|
|||
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
|
||||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get());
|
||||
if (participant_model)
|
||||
{
|
||||
// Get the avatar name for this participant id from the cache and update the model
|
||||
|
|
@ -511,7 +511,7 @@ void LLFloaterIMContainer::idleUpdate()
|
|||
bool can_ban = haveAbilityToBan();
|
||||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get());
|
||||
if (participant_model)
|
||||
{
|
||||
participant_model->setModeratorOptionsVisible(is_moderator);
|
||||
|
|
@ -1540,6 +1540,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v
|
|||
// Beyond that point, if only the user agent is selected, everything is disabled
|
||||
if (is_single_select && (single_id == gAgentID))
|
||||
{
|
||||
if ("can_zoom_in" == item)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (is_moderator_option)
|
||||
{
|
||||
return enableModerateContextMenuItem(item, true);
|
||||
|
|
@ -1874,7 +1878,7 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID&
|
|||
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
|
||||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
|
||||
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get());
|
||||
LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
|
||||
participant_view->addToFolder(widget);
|
||||
current_participant_model++;
|
||||
|
|
|
|||
|
|
@ -107,26 +107,6 @@ LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
|
|||
delete mRefreshTimer;
|
||||
LLIMMgr::instance().removeSessionObserver(this);
|
||||
mEmojiCloseConn.disconnect();
|
||||
|
||||
LLFloaterIMContainer* im_container = LLFloaterIMContainer::findInstance();
|
||||
if (im_container)
|
||||
{
|
||||
LLParticipantList* session = dynamic_cast<LLParticipantList*>(im_container->getSessionModel(mSessionID));
|
||||
if (session)
|
||||
{
|
||||
for (const conversations_widgets_map::value_type& widget_pair : mConversationsWidgets)
|
||||
{
|
||||
LLFolderViewItem* widget = widget_pair.second;
|
||||
LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
|
||||
if (item_vmi && item_vmi->getNumRefs() == 1)
|
||||
{
|
||||
// This is the last pointer, remove participant from session
|
||||
// before participant gets deleted on destroyView.
|
||||
session->removeChild(item_vmi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
@ -730,7 +710,7 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
|
|||
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
|
||||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
|
||||
LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get());
|
||||
if (participant_model)
|
||||
{
|
||||
addConversationViewParticipant(participant_model);
|
||||
|
|
@ -774,27 +754,6 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
|
|||
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
|
||||
if (widget)
|
||||
{
|
||||
LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
|
||||
if (item_vmi && item_vmi->getNumRefs() == 1)
|
||||
{
|
||||
// This is the last pointer, remove participant from session
|
||||
// before participant gets deleted on destroyView.
|
||||
//
|
||||
// Floater (widget) and participant's view can simultaneously
|
||||
// co-own the model, in which case view is responsible for
|
||||
// the deletion and floater is free to clear and recreate
|
||||
// the list, yet there are cases where only widget owns
|
||||
// the pointer so it should do the cleanup.
|
||||
// See "add_participant".
|
||||
//
|
||||
// Todo: If it keeps causing issues turn participants
|
||||
// into LLPointers in the session
|
||||
LLParticipantList* session = getParticipantList();
|
||||
if (session)
|
||||
{
|
||||
session->removeChild(item_vmi);
|
||||
}
|
||||
}
|
||||
widget->destroyView();
|
||||
}
|
||||
mConversationsWidgets.erase(participant_id);
|
||||
|
|
@ -860,7 +819,7 @@ void LLFloaterIMSessionTab::refreshConversation()
|
|||
LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
|
||||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get());
|
||||
if (speaker_mgr && participant_model)
|
||||
{
|
||||
LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
|
||||
|
|
|
|||
|
|
@ -28,9 +28,14 @@
|
|||
|
||||
#include "llfloaterinventorysettings.h"
|
||||
|
||||
#include "llcolorswatch.h"
|
||||
#include "llviewercontrol.h"
|
||||
|
||||
LLFloaterInventorySettings::LLFloaterInventorySettings(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("ScriptPref.applyUIColor", boost::bind(&LLFloaterInventorySettings::applyUIColor, this, _1, _2));
|
||||
mCommitCallbackRegistrar.add("ScriptPref.getUIColor", boost::bind(&LLFloaterInventorySettings::getUIColor, this, _1, _2));
|
||||
}
|
||||
|
||||
LLFloaterInventorySettings::~LLFloaterInventorySettings()
|
||||
|
|
@ -39,6 +44,29 @@ LLFloaterInventorySettings::~LLFloaterInventorySettings()
|
|||
bool LLFloaterInventorySettings::postBuild()
|
||||
{
|
||||
getChild<LLButton>("ok_btn")->setCommitCallback(boost::bind(&LLFloater::closeFloater, this, false));
|
||||
|
||||
getChild<LLUICtrl>("favorites_color")->setCommitCallback(boost::bind(&LLFloaterInventorySettings::updateColorSwatch, this));
|
||||
|
||||
bool enable_color = gSavedSettings.getBOOL("InventoryFavoritesColorText");
|
||||
getChild<LLUICtrl>("favorites_swatch")->setEnabled(enable_color);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLFloaterInventorySettings::updateColorSwatch()
|
||||
{
|
||||
bool val = getChild<LLUICtrl>("favorites_color")->getValue();
|
||||
getChild<LLUICtrl>("favorites_swatch")->setEnabled(val);
|
||||
}
|
||||
|
||||
void LLFloaterInventorySettings::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
|
||||
{
|
||||
LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
|
||||
}
|
||||
|
||||
void LLFloaterInventorySettings::getUIColor(LLUICtrl* ctrl, const LLSD& param)
|
||||
{
|
||||
LLColorSwatchCtrl* color_swatch = (LLColorSwatchCtrl*)ctrl;
|
||||
color_swatch->setOriginal(LLUIColorTable::instance().getColor(param.asString()));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ public:
|
|||
private:
|
||||
LLFloaterInventorySettings(const LLSD& key);
|
||||
~LLFloaterInventorySettings();
|
||||
|
||||
void updateColorSwatch();
|
||||
|
||||
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
|
||||
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file llfloatermarketplace.cpp
|
||||
* @brief floater for the Marketplace web site
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llfloatermarketplace.h"
|
||||
#include "lluictrlfactory.h"
|
||||
|
||||
LLFloaterMarketplace::LLFloaterMarketplace(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
{
|
||||
}
|
||||
|
||||
LLFloaterMarketplace::~LLFloaterMarketplace()
|
||||
{
|
||||
}
|
||||
|
||||
bool LLFloaterMarketplace::postBuild()
|
||||
{
|
||||
enableResizeCtrls(true, true, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* @file llfloatermarketplace.h
|
||||
* @brief floater for the Marketplace web site
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLFloaterMarketplace:
|
||||
public LLFloater
|
||||
{
|
||||
friend class LLFloaterReg;
|
||||
private:
|
||||
LLFloaterMarketplace(const LLSD& key);
|
||||
~LLFloaterMarketplace();
|
||||
bool postBuild() override;
|
||||
};
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ bool LLFloaterModelPreview::postBuild()
|
|||
for (S32 lod = 0; lod <= LLModel::LOD_HIGH; ++lod)
|
||||
{
|
||||
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[lod]);
|
||||
lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod, true));
|
||||
lod_source_combo->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLoDSourceCommit, this, lod));
|
||||
lod_source_combo->setCurrentByIndex(mLODMode[lod]);
|
||||
|
||||
getChild<LLButton>("lod_browse_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onBrowseLOD, this, lod));
|
||||
|
|
@ -350,14 +350,14 @@ void LLFloaterModelPreview::initModelPreview()
|
|||
}
|
||||
|
||||
//static
|
||||
bool LLFloaterModelPreview::showModelPreview()
|
||||
void LLFloaterModelPreview::showModelPreview(const LLUUID& dest_folder)
|
||||
{
|
||||
LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)LLFloaterReg::getInstance("upload_model");
|
||||
if (fmp && !fmp->isModelLoading())
|
||||
{
|
||||
fmp->setUploadDestination(dest_folder);
|
||||
fmp->loadHighLodModel();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl)
|
||||
|
|
@ -506,7 +506,7 @@ void LLFloaterModelPreview::onClickCalculateBtn()
|
|||
gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale,
|
||||
childGetValue("upload_textures").asBoolean(),
|
||||
upload_skinweights, upload_joint_positions, lock_scale_if_joint_position,
|
||||
mUploadModelUrl, false,
|
||||
mUploadModelUrl, mDestinationFolderId, false,
|
||||
getWholeModelFeeObserverHandle());
|
||||
|
||||
toggleCalculateButton(false);
|
||||
|
|
@ -766,7 +766,7 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
|
|||
LLComboBox* lod_source_combo = getChild<LLComboBox>("lod_source_" + lod_name[i]);
|
||||
if (lod_source_combo->getCurrentIndex() == LLModelPreview::USE_LOD_ABOVE)
|
||||
{
|
||||
onLoDSourceCommit(i, false);
|
||||
onLoDSourceCommit(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1659,7 +1659,7 @@ void LLFloaterModelPreview::onUpload(void* user_data)
|
|||
gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale,
|
||||
mp->childGetValue("upload_textures").asBoolean(),
|
||||
upload_skinweights, upload_joint_positions, lock_scale_if_joint_position,
|
||||
mp->mUploadModelUrl,
|
||||
mp->mUploadModelUrl, mp->mDestinationFolderId,
|
||||
true, LLHandle<LLWholeModelFeeObserver>(), mp->getWholeModelUploadObserverHandle());
|
||||
}
|
||||
|
||||
|
|
@ -1760,7 +1760,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible)
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterModelPreview::onLoDSourceCommit(S32 lod, bool refresh_ui)
|
||||
void LLFloaterModelPreview::onLoDSourceCommit(S32 lod)
|
||||
{
|
||||
mModelPreview->updateLodControls(lod);
|
||||
|
||||
|
|
@ -1773,12 +1773,10 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod, bool refresh_ui)
|
|||
// rebuild LoD to update triangle counts
|
||||
onLODParamCommit(lod, true);
|
||||
}
|
||||
else if (refresh_ui && index == LLModelPreview::USE_LOD_ABOVE)
|
||||
if (index == LLModelPreview::USE_LOD_ABOVE)
|
||||
{
|
||||
// Update mUploadData for updateStatusMessages
|
||||
mModelPreview->rebuildUploadData();
|
||||
// Update UI with new triangle values
|
||||
mModelPreview->updateStatusMessages();
|
||||
// refresh to pick triangle counts
|
||||
mModelPreview->mDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue