Merge branch 'master' of https://github.com/FirestormViewer/phoenix-firestorm
# Conflicts: # indra/newview/llskinningutil.cpp # indra/newview/llvoavatar.cpp # indra/newview/skins/default/xui/ja/strings.xmlmaster
commit
6cb5a7425f
|
|
@ -922,11 +922,11 @@
|
||||||
<key>archive</key>
|
<key>archive</key>
|
||||||
<map>
|
<map>
|
||||||
<key>hash</key>
|
<key>hash</key>
|
||||||
<string>ff3057e8763bdbe87a478a3d77067b5a</string>
|
<string>19e40aa358c1784b49eccd547e704647</string>
|
||||||
<key>hash_algorithm</key>
|
<key>hash_algorithm</key>
|
||||||
<string>md5</string>
|
<string>md5</string>
|
||||||
<key>url</key>
|
<key>url</key>
|
||||||
<string>file:///opt/firestorm/fmodstudio-2.02.26-darwin64-243641704.tar.bz2</string>
|
<string>file:///opt/firestorm/fmodstudio-2.03.07-darwin64-251121740.tar.bz2</string>
|
||||||
</map>
|
</map>
|
||||||
<key>name</key>
|
<key>name</key>
|
||||||
<string>darwin64</string>
|
<string>darwin64</string>
|
||||||
|
|
@ -936,11 +936,11 @@
|
||||||
<key>archive</key>
|
<key>archive</key>
|
||||||
<map>
|
<map>
|
||||||
<key>hash</key>
|
<key>hash</key>
|
||||||
<string>41265f539399e365601a22d108287e91</string>
|
<string>a459e2967306ff56a835a321dc00718c</string>
|
||||||
<key>hash_algorithm</key>
|
<key>hash_algorithm</key>
|
||||||
<string>md5</string>
|
<string>md5</string>
|
||||||
<key>url</key>
|
<key>url</key>
|
||||||
<string>file:///opt/firestorm/fmodstudio-2.02.26-linux64-243641703.tar.bz2</string>
|
<string>file:///opt/firestorm/fmodstudio-2.03.07-linux64-251121739.tar.bz2</string>
|
||||||
</map>
|
</map>
|
||||||
<key>name</key>
|
<key>name</key>
|
||||||
<string>linux64</string>
|
<string>linux64</string>
|
||||||
|
|
@ -950,11 +950,9 @@
|
||||||
<key>archive</key>
|
<key>archive</key>
|
||||||
<map>
|
<map>
|
||||||
<key>hash</key>
|
<key>hash</key>
|
||||||
<string>595e7aa51f2161b8d11c3afcc88e2197</string>
|
<string>4a0da36b4a31332df62dadf6438f935e</string>
|
||||||
<key>hash_algorithm</key>
|
|
||||||
<string>md5</string>
|
|
||||||
<key>url</key>
|
<key>url</key>
|
||||||
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.26-windows64-243641704.tar.bz2</string>
|
<string>file:///c:/cygwin/opt/firestorm/fmodstudio-2.03.07-windows64-251121127.tar.bz2</string>
|
||||||
</map>
|
</map>
|
||||||
<key>name</key>
|
<key>name</key>
|
||||||
<string>windows64</string>
|
<string>windows64</string>
|
||||||
|
|
|
||||||
|
|
@ -140,10 +140,9 @@ public:
|
||||||
LLVector3 mHeadOffset{}; // current head position
|
LLVector3 mHeadOffset{}; // current head position
|
||||||
LLAvatarJoint* mRoot{ nullptr };
|
LLAvatarJoint* mRoot{ nullptr };
|
||||||
|
|
||||||
// <FS:ND> This map gets queried a huge amount of time.
|
//<FS:Ansariel> Joint-lookup improvements
|
||||||
// typedef std::map<std::string, LLJoint*> joint_map_t;
|
// typedef std::map<std::string, LLJoint*> joint_map_t;
|
||||||
typedef std::unordered_map<U32, LLJoint*> joint_map_t;
|
typedef std::map<std::string, LLJoint*, std::less<>> joint_map_t;
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
joint_map_t mJointMap;
|
joint_map_t mJointMap;
|
||||||
|
|
||||||
|
|
@ -157,7 +156,7 @@ public:
|
||||||
public:
|
public:
|
||||||
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
||||||
const avatar_joint_list_t& getSkeleton() { return mSkeleton; }
|
const avatar_joint_list_t& getSkeleton() { return mSkeleton; }
|
||||||
typedef std::map<std::string, std::string> joint_alias_map_t;
|
typedef std::map<std::string, std::string, std::less<>> joint_alias_map_t;
|
||||||
const joint_alias_map_t& getJointAliases();
|
const joint_alias_map_t& getJointAliases();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@
|
||||||
|
|
||||||
#include "sound_ids.h"
|
#include "sound_ids.h"
|
||||||
|
|
||||||
const U32 EXTRA_SOUND_CHANNELS = 10;
|
constexpr U32 EXTRA_SOUND_CHANNELS = 10;
|
||||||
|
|
||||||
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels);
|
FMOD_RESULT F_CALL windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels);
|
||||||
|
|
||||||
FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
|
FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
|
||||||
|
|
||||||
|
|
@ -69,13 +69,13 @@ static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLUUID FMOD_GUID_to_LLUUID(FMOD_GUID guid)
|
static LLUUID FMOD_GUID_to_LLUUID(FMOD_GUID guid)
|
||||||
{
|
{
|
||||||
return LLUUID(llformat("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3,
|
return LLUUID(llformat("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3,
|
||||||
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]));
|
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_device(FMOD::System* system, const LLUUID& device_uuid)
|
static void set_device(FMOD::System* system, const LLUUID& device_uuid)
|
||||||
{
|
{
|
||||||
LL_INFOS() << "LLAudioEngine_FMODSTUDIO::setDevice with device_uuid=" << device_uuid << LL_ENDL;
|
LL_INFOS() << "LLAudioEngine_FMODSTUDIO::setDevice with device_uuid=" << device_uuid << LL_ENDL;
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ void set_device(FMOD::System* system, const LLUUID& device_uuid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FMOD_RESULT F_CALLBACK systemCallback(FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK_TYPE type, void *commanddata1, void *commanddata2, void* userdata)
|
FMOD_RESULT F_CALL systemCallback(FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK_TYPE type, void *commanddata1, void *commanddata2, void* userdata)
|
||||||
{
|
{
|
||||||
FMOD::System* sys = (FMOD::System*)system;
|
FMOD::System* sys = (FMOD::System*)system;
|
||||||
LLAudioEngine_FMODSTUDIO* audio_engine = (LLAudioEngine_FMODSTUDIO*)userdata;
|
LLAudioEngine_FMODSTUDIO* audio_engine = (LLAudioEngine_FMODSTUDIO*)userdata;
|
||||||
|
|
@ -881,7 +881,7 @@ void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d)
|
||||||
// not the main thread. May have implications for callees or audio
|
// not the main thread. May have implications for callees or audio
|
||||||
// engine shutdown.
|
// engine shutdown.
|
||||||
|
|
||||||
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels)
|
FMOD_RESULT F_CALL windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels)
|
||||||
{
|
{
|
||||||
// inbuffer = fmod's original mixbuffer.
|
// inbuffer = fmod's original mixbuffer.
|
||||||
// outbuffer = the buffer passed from the previous DSP unit.
|
// outbuffer = the buffer passed from the previous DSP unit.
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ LLQuaternion::Order bvhStringToOrder( char *str )
|
||||||
// LLBVHLoader()
|
// LLBVHLoader()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map )
|
LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map )
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
errorLine = 0;
|
errorLine = 0;
|
||||||
|
|
@ -156,9 +156,9 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recognize all names we've been told are legal.
|
// Recognize all names we've been told are legal.
|
||||||
for (std::map<std::string, std::string>::value_type& alias_pair : joint_alias_map)
|
for (const auto& [alias, joint] : joint_alias_map)
|
||||||
{
|
{
|
||||||
makeTranslation( alias_pair.first , alias_pair.second );
|
makeTranslation(alias, joint);
|
||||||
}
|
}
|
||||||
|
|
||||||
char error_text[128]; /* Flawfinder: ignore */
|
char error_text[128]; /* Flawfinder: ignore */
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ class LLBVHLoader
|
||||||
friend class LLKeyframeMotion;
|
friend class LLKeyframeMotion;
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map );
|
LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map );
|
||||||
~LLBVHLoader();
|
~LLBVHLoader();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,9 @@ LLCharacter::~LLCharacter()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// getJoint()
|
// getJoint()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
LLJoint *LLCharacter::getJoint( const std::string &name )
|
//<FS:Ansariel> Joint-lookup improvements
|
||||||
|
//LLJoint *LLCharacter::getJoint( const std::string &name )
|
||||||
|
LLJoint* LLCharacter::getJoint(std::string_view name)
|
||||||
{
|
{
|
||||||
LLJoint* joint = NULL;
|
LLJoint* joint = NULL;
|
||||||
|
|
||||||
|
|
@ -94,14 +96,6 @@ LLJoint *LLCharacter::getJoint( const std::string &name )
|
||||||
return joint;
|
return joint;
|
||||||
}
|
}
|
||||||
|
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
|
||||||
// Default fallback is string.
|
|
||||||
LLJoint *LLCharacter::getJoint( const JointKey &name )
|
|
||||||
{
|
|
||||||
return getJoint( name.mName );
|
|
||||||
}
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// registerMotion()
|
// registerMotion()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,9 @@ public:
|
||||||
// get the specified joint
|
// get the specified joint
|
||||||
// default implementation does recursive search,
|
// default implementation does recursive search,
|
||||||
// subclasses may optimize/cache results.
|
// subclasses may optimize/cache results.
|
||||||
|
//<FS:Ansariel> Joint-lookup improvements
|
||||||
// virtual LLJoint *getJoint( const std::string &name );
|
// virtual LLJoint *getJoint( const std::string &name );
|
||||||
|
virtual LLJoint* getJoint(std::string_view name);
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
|
||||||
virtual LLJoint *getJoint( const JointKey &name );
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
LLJoint *getJoint( const std::string &name );
|
|
||||||
|
|
||||||
// get the position of the character
|
// get the position of the character
|
||||||
virtual LLVector3 getCharacterPosition() = 0;
|
virtual LLVector3 getCharacterPosition() = 0;
|
||||||
|
|
|
||||||
|
|
@ -34,24 +34,6 @@
|
||||||
#include "llmath.h"
|
#include "llmath.h"
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
std::unordered_map<std::string, U32> mpStringToKeys;
|
|
||||||
|
|
||||||
JointKey JointKey::construct(const std::string& aName)
|
|
||||||
{
|
|
||||||
if (const auto itr = mpStringToKeys.find(aName); itr != mpStringToKeys.end())
|
|
||||||
{
|
|
||||||
return { aName, itr->second };
|
|
||||||
}
|
|
||||||
|
|
||||||
U32 size = static_cast<U32>(mpStringToKeys.size()) + 1;
|
|
||||||
mpStringToKeys.try_emplace(aName, size);
|
|
||||||
return { aName, size };
|
|
||||||
}
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
S32 LLJoint::sNumUpdates = 0;
|
S32 LLJoint::sNumUpdates = 0;
|
||||||
S32 LLJoint::sNumTouches = 0;
|
S32 LLJoint::sNumTouches = 0;
|
||||||
|
|
||||||
|
|
@ -260,7 +242,9 @@ LLJoint *LLJoint::getRoot()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// findJoint()
|
// findJoint()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
LLJoint *LLJoint::findJoint( const std::string &name )
|
//<FS:Ansariel> Joint-lookup improvements
|
||||||
|
//LLJoint *LLJoint::findJoint( const std::string &name )
|
||||||
|
LLJoint *LLJoint::findJoint(std::string_view name)
|
||||||
{
|
{
|
||||||
if (name == getName())
|
if (name == getName())
|
||||||
return this;
|
return this;
|
||||||
|
|
|
||||||
|
|
@ -40,31 +40,6 @@
|
||||||
#include "xform.h"
|
#include "xform.h"
|
||||||
#include "llmatrix4a.h"
|
#include "llmatrix4a.h"
|
||||||
|
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
|
||||||
struct JointKey
|
|
||||||
{
|
|
||||||
std::string mName;
|
|
||||||
U32 mKey;
|
|
||||||
|
|
||||||
static JointKey construct(const std::string& aName);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline bool operator==(JointKey const &aLHS, JointKey const &aRHS)
|
|
||||||
{
|
|
||||||
return aLHS.mName == aRHS.mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool operator!=(JointKey const &aLHS, JointKey const &aRHS)
|
|
||||||
{
|
|
||||||
return ! (aLHS == aRHS);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream &aLHS, JointKey const &aRHS)
|
|
||||||
{
|
|
||||||
return aLHS << aRHS.mName << " (" << aRHS.mKey << ")";
|
|
||||||
}
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
constexpr S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15;
|
constexpr S32 LL_CHARACTER_MAX_JOINTS_PER_MESH = 15;
|
||||||
// Need to set this to count of animate-able joints,
|
// Need to set this to count of animate-able joints,
|
||||||
// currently = #bones + #collision_volumes + #attachments + 2,
|
// currently = #bones + #collision_volumes + #attachments + 2,
|
||||||
|
|
@ -247,7 +222,9 @@ public:
|
||||||
LLJoint *getRoot();
|
LLJoint *getRoot();
|
||||||
|
|
||||||
// search for child joints by name
|
// search for child joints by name
|
||||||
LLJoint *findJoint( const std::string &name );
|
//<FS:Ansariel> Joint-lookup improvements
|
||||||
|
//LLJoint *findJoint( const std::string &name );
|
||||||
|
LLJoint* findJoint(std::string_view name);
|
||||||
|
|
||||||
// add/remove children
|
// add/remove children
|
||||||
void addChild( LLJoint *joint );
|
void addChild( LLJoint *joint );
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
|
||||||
|
|
||||||
U32 micro_sleep(U64 us, U32 max_yields)
|
U32 micro_sleep(U64 us, U32 max_yields)
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_SCOPED;
|
// LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> remove pointless profiling
|
||||||
#if 0
|
#if 0
|
||||||
LARGE_INTEGER ft;
|
LARGE_INTEGER ft;
|
||||||
ft.QuadPart = -static_cast<S64>(us * 10); // '-' using relative time
|
ft.QuadPart = -static_cast<S64>(us * 10); // '-' using relative time
|
||||||
|
|
@ -109,7 +109,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
|
||||||
|
|
||||||
void ms_sleep(U32 ms)
|
void ms_sleep(U32 ms)
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_SCOPED;
|
// LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> remove pointless profiling
|
||||||
micro_sleep(ms * 1000, 0);
|
micro_sleep(ms * 1000, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
|
||||||
ELoopSpeed loop(REQUEST_SLEEP);
|
ELoopSpeed loop(REQUEST_SLEEP);
|
||||||
while (! mExitRequested)
|
while (! mExitRequested)
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
// LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // <FS:Beq/> remove pointless profiling
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
loop = processRequestQueue(loop);
|
loop = processRequestQueue(loop);
|
||||||
|
|
|
||||||
|
|
@ -333,11 +333,21 @@ const std::string LLDiskCache::metaDataToFilepath(const LLUUID& id, LLAssetType:
|
||||||
|
|
||||||
const std::string LLDiskCache::getCacheInfo()
|
const std::string LLDiskCache::getCacheInfo()
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> add some instrumentation
|
||||||
std::ostringstream cache_info;
|
std::ostringstream cache_info;
|
||||||
|
|
||||||
F32 max_in_mb = (F32)mMaxSizeBytes / (1024.0f * 1024.0f);
|
F32 max_in_mb = (F32)mMaxSizeBytes / (1024.0f * 1024.0f);
|
||||||
F32 percent_used = ((F32)dirFileSize(sCacheDir) / (F32)mMaxSizeBytes) * 100.0f;
|
// <FS:Beq> stall prevention. We still need to make sure this initialised when called at startup.
|
||||||
|
F32 percent_used;
|
||||||
|
if (mStoredCacheSize > 0)
|
||||||
|
{
|
||||||
|
percent_used = ((F32)mStoredCacheSize / (F32)mMaxSizeBytes) * 100.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
percent_used = ((F32)dirFileSize(sCacheDir) / (F32)mMaxSizeBytes) * 100.0f;
|
||||||
|
}
|
||||||
|
// </FS:Beq>
|
||||||
cache_info << std::fixed;
|
cache_info << std::fixed;
|
||||||
cache_info << std::setprecision(1);
|
cache_info << std::setprecision(1);
|
||||||
cache_info << "Max size " << max_in_mb << " MB ";
|
cache_info << "Max size " << max_in_mb << " MB ";
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ LLCamera::LLCamera() :
|
||||||
LLCoordFrame(),
|
LLCoordFrame(),
|
||||||
mView(DEFAULT_FIELD_OF_VIEW),
|
mView(DEFAULT_FIELD_OF_VIEW),
|
||||||
mAspect(DEFAULT_ASPECT_RATIO),
|
mAspect(DEFAULT_ASPECT_RATIO),
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
//mInverseAspect(1.0f / DEFAULT_ASPECT_RATIO),
|
//mInverseAspect(1.0f / DEFAULT_ASPECT_RATIO),
|
||||||
mDrawDistanceMultiplier(1.0f),
|
mDrawDistanceMultiplier(1.0f),
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
@ -67,14 +67,14 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
|
||||||
}
|
}
|
||||||
|
|
||||||
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
|
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Store the inverse of the aspect ratio, so we can remove it from texture calculations
|
// Store the inverse of the aspect ratio, so we can remove it from texture calculations
|
||||||
//mInverseAspect = 1.0f / mAspect;
|
//mInverseAspect = 1.0f / mAspect;
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
|
mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
|
||||||
if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE;
|
if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE;
|
||||||
mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
|
mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Store the draw distance multiplier based upon how much bigger/smaller the far plan is then the default (64.0f)
|
// Store the draw distance multiplier based upon how much bigger/smaller the far plan is then the default (64.0f)
|
||||||
mDrawDistanceMultiplier = mFarPlane / DEFAULT_FAR_PLANE;
|
mDrawDistanceMultiplier = mFarPlane / DEFAULT_FAR_PLANE;
|
||||||
mDrawDistanceMultiplier = mDrawDistanceMultiplier < 1.0f ? 1.0f : mDrawDistanceMultiplier;
|
mDrawDistanceMultiplier = mDrawDistanceMultiplier < 1.0f ? 1.0f : mDrawDistanceMultiplier;
|
||||||
|
|
@ -141,7 +141,7 @@ void LLCamera::setViewHeightInPixels(S32 height)
|
||||||
void LLCamera::setAspect(F32 aspect_ratio)
|
void LLCamera::setAspect(F32 aspect_ratio)
|
||||||
{
|
{
|
||||||
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
|
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Store the inverse of the aspect ratio, so we can remove it from texture calculations
|
// Store the inverse of the aspect ratio, so we can remove it from texture calculations
|
||||||
//mInverseAspect = 1.0f / mAspect;
|
//mInverseAspect = 1.0f / mAspect;
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
@ -159,7 +159,7 @@ void LLCamera::setNear(F32 near_plane)
|
||||||
void LLCamera::setFar(F32 far_plane)
|
void LLCamera::setFar(F32 far_plane)
|
||||||
{
|
{
|
||||||
mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
|
mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Store the draw distance multiplier based upon how much bigger/smaller the far plan is then the default (64.0f)
|
// Store the draw distance multiplier based upon how much bigger/smaller the far plan is then the default (64.0f)
|
||||||
mDrawDistanceMultiplier = mFarPlane / DEFAULT_FAR_PLANE;
|
mDrawDistanceMultiplier = mFarPlane / DEFAULT_FAR_PLANE;
|
||||||
mDrawDistanceMultiplier = mDrawDistanceMultiplier < 1.0f ? 1.0f : mDrawDistanceMultiplier;
|
mDrawDistanceMultiplier = mDrawDistanceMultiplier < 1.0f ? 1.0f : mDrawDistanceMultiplier;
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ private:
|
||||||
|
|
||||||
F32 mView; // angle between top and bottom frustum planes in radians.
|
F32 mView; // angle between top and bottom frustum planes in radians.
|
||||||
F32 mAspect; // width/height
|
F32 mAspect; // width/height
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Store the inverse of the aspect ratio, for the texture's sizes
|
// Store the inverse of the aspect ratio, for the texture's sizes
|
||||||
//F32 mInverseAspect; // height/width
|
//F32 mInverseAspect; // height/width
|
||||||
F32 mDrawDistanceMultiplier; // mFarPlane / DEFAULT_FAR_PLANE
|
F32 mDrawDistanceMultiplier; // mFarPlane / DEFAULT_FAR_PLANE
|
||||||
|
|
@ -166,7 +166,7 @@ public:
|
||||||
F32 getView() const { return mView; } // vertical FOV in radians
|
F32 getView() const { return mView; } // vertical FOV in radians
|
||||||
S32 getViewHeightInPixels() const { return mViewHeightInPixels; }
|
S32 getViewHeightInPixels() const { return mViewHeightInPixels; }
|
||||||
F32 getAspect() const { return mAspect; } // width / height
|
F32 getAspect() const { return mAspect; } // width / height
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
//F32 getInverseAspect() const { return mInverseAspect; } // width / height
|
//F32 getInverseAspect() const { return mInverseAspect; } // width / height
|
||||||
F32 getDrawDistanceMultiplier() const { return mDrawDistanceMultiplier; } // mFarPlane / DEFAULT_FAR_PLANE (could also include near plane as well)
|
F32 getDrawDistanceMultiplier() const { return mDrawDistanceMultiplier; } // mFarPlane / DEFAULT_FAR_PLANE (could also include near plane as well)
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
|
||||||
|
|
@ -113,10 +113,11 @@ class LLMessageHandlerBridge : public LLHTTPNode
|
||||||
void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,
|
void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,
|
||||||
const LLSD& context, const LLSD& input) const
|
const LLSD& context, const LLSD& input) const
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||||
std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["message-name"];
|
std::string name = context[CONTEXT_REQUEST][CONTEXT_WILDCARD]["message-name"];
|
||||||
char* namePtr = LLMessageStringTable::getInstance()->getString(name.c_str());
|
char* namePtr = LLMessageStringTable::getInstance()->getString(name.c_str());
|
||||||
|
|
||||||
LL_DEBUGS() << "Setting mLastSender " << input["sender"].asString() << LL_ENDL;
|
LL_DEBUGS("Messaging") << "Setting mLastSender " << input["sender"].asString() << LL_ENDL;
|
||||||
gMessageSystem->mLastSender = LLHost(input["sender"].asString());
|
gMessageSystem->mLastSender = LLHost(input["sender"].asString());
|
||||||
gMessageSystem->mPacketsIn += 1;
|
gMessageSystem->mPacketsIn += 1;
|
||||||
gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]);
|
gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]);
|
||||||
|
|
@ -2050,6 +2051,7 @@ void LLMessageSystem::dispatch(
|
||||||
const std::string& msg_name,
|
const std::string& msg_name,
|
||||||
const LLSD& message)
|
const LLSD& message)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||||
LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create();
|
LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create();
|
||||||
dispatch(msg_name, message, responsep);
|
dispatch(msg_name, message, responsep);
|
||||||
}
|
}
|
||||||
|
|
@ -2060,6 +2062,7 @@ void LLMessageSystem::dispatch(
|
||||||
const LLSD& message,
|
const LLSD& message,
|
||||||
LLHTTPNode::ResponsePtr responsep)
|
LLHTTPNode::ResponsePtr responsep)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
|
||||||
if ((gMessageSystem->mMessageTemplates.find
|
if ((gMessageSystem->mMessageTemplates.find
|
||||||
(LLMessageStringTable::getInstance()->getString(msg_name.c_str())) ==
|
(LLMessageStringTable::getInstance()->getString(msg_name.c_str())) ==
|
||||||
gMessageSystem->mMessageTemplates.end()) &&
|
gMessageSystem->mMessageTemplates.end()) &&
|
||||||
|
|
|
||||||
|
|
@ -917,7 +917,7 @@ LLDAELoader::LLDAELoader(
|
||||||
void* opaque_userdata,
|
void* opaque_userdata,
|
||||||
JointTransformMap& jointTransformMap,
|
JointTransformMap& jointTransformMap,
|
||||||
JointNameSet& jointsFromNodes,
|
JointNameSet& jointsFromNodes,
|
||||||
std::map<std::string, std::string>& jointAliasMap,
|
std::map<std::string, std::string, std::less<>>& jointAliasMap,
|
||||||
U32 maxJointsPerMesh,
|
U32 maxJointsPerMesh,
|
||||||
U32 modelLimit,
|
U32 modelLimit,
|
||||||
// <FS:Beq> mesh loader suffix configuration
|
// <FS:Beq> mesh loader suffix configuration
|
||||||
|
|
@ -1467,10 +1467,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
||||||
{
|
{
|
||||||
name = mJointMap[name];
|
name = mJointMap[name];
|
||||||
}
|
}
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
model->mSkinInfo.mJointNames.push_back(name);
|
||||||
// model->mSkinInfo.mJointNames.push_back( name );
|
|
||||||
model->mSkinInfo.mJointNames.push_back( JointKey::construct( name ) );
|
|
||||||
// </FS:ND>
|
|
||||||
model->mSkinInfo.mJointNums.push_back(-1);
|
model->mSkinInfo.mJointNums.push_back(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1488,10 +1485,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
||||||
{
|
{
|
||||||
name = mJointMap[name];
|
name = mJointMap[name];
|
||||||
}
|
}
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
model->mSkinInfo.mJointNames.push_back(name);
|
||||||
// model->mSkinInfo.mJointNames.push_back( name );
|
|
||||||
model->mSkinInfo.mJointNames.push_back( JointKey::construct( name ) );
|
|
||||||
// </FS:ND>
|
|
||||||
model->mSkinInfo.mJointNums.push_back(-1);
|
model->mSkinInfo.mJointNums.push_back(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1533,10 +1527,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
||||||
//but does not use the skeleton).
|
//but does not use the skeleton).
|
||||||
buildJointToNodeMappingFromScene( root );
|
buildJointToNodeMappingFromScene( root );
|
||||||
|
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames );
|
||||||
// critiqueRigForUploadApplicability( model->mSkinInfo.mJointNames );
|
|
||||||
critiqueRigForUploadApplicability( toStringVector( model->mSkinInfo.mJointNames ) );
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
if ( !missingSkeletonOrScene )
|
if ( !missingSkeletonOrScene )
|
||||||
{
|
{
|
||||||
|
|
@ -1589,11 +1580,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
||||||
//with the skeleton are not stored in the same order as they are in the exported joint buffer.
|
//with the skeleton are not stored in the same order as they are in the exported joint buffer.
|
||||||
//This remaps the skeletal joints to be in the same order as the joints stored in the model.
|
//This remaps the skeletal joints to be in the same order as the joints stored in the model.
|
||||||
|
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
std::vector<std::string> ::const_iterator jointIt = model->mSkinInfo.mJointNames.begin();
|
||||||
// std::vector<std::string> ::const_iterator jointIt = model->mSkinInfo.mJointNames.begin();
|
|
||||||
std::vector< std::string > jointNames = toStringVector( model->mSkinInfo.mJointNames );
|
|
||||||
std::vector<std::string> ::const_iterator jointIt = jointNames.begin();
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
const int jointCnt = static_cast<int>(model->mSkinInfo.mJointNames.size());
|
const int jointCnt = static_cast<int>(model->mSkinInfo.mJointNames.size());
|
||||||
for ( int i=0; i<jointCnt; ++i, ++jointIt )
|
for ( int i=0; i<jointCnt; ++i, ++jointIt )
|
||||||
|
|
|
||||||
|
|
@ -49,22 +49,22 @@ public:
|
||||||
dae_model_map mModelsMap;
|
dae_model_map mModelsMap;
|
||||||
|
|
||||||
LLDAELoader(
|
LLDAELoader(
|
||||||
std::string filename,
|
std::string filename,
|
||||||
S32 lod,
|
S32 lod,
|
||||||
LLModelLoader::load_callback_t load_cb,
|
LLModelLoader::load_callback_t load_cb,
|
||||||
LLModelLoader::joint_lookup_func_t joint_lookup_func,
|
LLModelLoader::joint_lookup_func_t joint_lookup_func,
|
||||||
LLModelLoader::texture_load_func_t texture_load_func,
|
LLModelLoader::texture_load_func_t texture_load_func,
|
||||||
LLModelLoader::state_callback_t state_cb,
|
LLModelLoader::state_callback_t state_cb,
|
||||||
void* opaque_userdata,
|
void* opaque_userdata,
|
||||||
JointTransformMap& jointTransformMap,
|
JointTransformMap& jointTransformMap,
|
||||||
JointNameSet& jointsFromNodes,
|
JointNameSet& jointsFromNodes,
|
||||||
std::map<std::string, std::string>& jointAliasMap,
|
std::map<std::string, std::string, std::less<>>& jointAliasMap,
|
||||||
U32 maxJointsPerMesh,
|
U32 maxJointsPerMesh,
|
||||||
U32 modelLimit,
|
U32 modelLimit,
|
||||||
// <FS:Beq> configrable lod suffix support
|
// <FS:Beq> configrable lod suffix support
|
||||||
// bool preprocess);
|
// bool preprocess);
|
||||||
bool preprocess,
|
bool preprocess,
|
||||||
const LODSuffixArray& lod_suffix);
|
const LODSuffixArray& lod_suffix);
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
virtual ~LLDAELoader() ;
|
virtual ~LLDAELoader() ;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,19 +66,19 @@ static const std::string lod_suffix[LLModel::NUM_LODS] =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
LLGLTFLoader::LLGLTFLoader(std::string filename,
|
LLGLTFLoader::LLGLTFLoader(std::string filename,
|
||||||
S32 lod,
|
S32 lod,
|
||||||
LLModelLoader::load_callback_t load_cb,
|
LLModelLoader::load_callback_t load_cb,
|
||||||
LLModelLoader::joint_lookup_func_t joint_lookup_func,
|
LLModelLoader::joint_lookup_func_t joint_lookup_func,
|
||||||
LLModelLoader::texture_load_func_t texture_load_func,
|
LLModelLoader::texture_load_func_t texture_load_func,
|
||||||
LLModelLoader::state_callback_t state_cb,
|
LLModelLoader::state_callback_t state_cb,
|
||||||
void * opaque_userdata,
|
void * opaque_userdata,
|
||||||
JointTransformMap & jointTransformMap,
|
JointTransformMap & jointTransformMap,
|
||||||
JointNameSet & jointsFromNodes,
|
JointNameSet & jointsFromNodes,
|
||||||
std::map<std::string, std::string> &jointAliasMap,
|
std::map<std::string, std::string, std::less<>> & jointAliasMap,
|
||||||
U32 maxJointsPerMesh,
|
U32 maxJointsPerMesh,
|
||||||
U32 modelLimit) //,
|
U32 modelLimit) //,
|
||||||
//bool preprocess)
|
//bool preprocess)
|
||||||
: LLModelLoader( filename,
|
: LLModelLoader( filename,
|
||||||
lod,
|
lod,
|
||||||
load_cb,
|
load_cb,
|
||||||
|
|
|
||||||
|
|
@ -121,18 +121,18 @@ class LLGLTFLoader : public LLModelLoader
|
||||||
typedef std::map<std::string, LLImportMaterial> material_map;
|
typedef std::map<std::string, LLImportMaterial> material_map;
|
||||||
|
|
||||||
LLGLTFLoader(std::string filename,
|
LLGLTFLoader(std::string filename,
|
||||||
S32 lod,
|
S32 lod,
|
||||||
LLModelLoader::load_callback_t load_cb,
|
LLModelLoader::load_callback_t load_cb,
|
||||||
LLModelLoader::joint_lookup_func_t joint_lookup_func,
|
LLModelLoader::joint_lookup_func_t joint_lookup_func,
|
||||||
LLModelLoader::texture_load_func_t texture_load_func,
|
LLModelLoader::texture_load_func_t texture_load_func,
|
||||||
LLModelLoader::state_callback_t state_cb,
|
LLModelLoader::state_callback_t state_cb,
|
||||||
void * opaque_userdata,
|
void * opaque_userdata,
|
||||||
JointTransformMap & jointTransformMap,
|
JointTransformMap & jointTransformMap,
|
||||||
JointNameSet & jointsFromNodes,
|
JointNameSet & jointsFromNodes,
|
||||||
std::map<std::string, std::string> &jointAliasMap,
|
std::map<std::string, std::string,std::less<>> &jointAliasMap,
|
||||||
U32 maxJointsPerMesh,
|
U32 maxJointsPerMesh,
|
||||||
U32 modelLimit); //,
|
U32 modelLimit); //,
|
||||||
//bool preprocess );
|
//bool preprocess );
|
||||||
virtual ~LLGLTFLoader();
|
virtual ~LLGLTFLoader();
|
||||||
|
|
||||||
virtual bool OpenFile(const std::string &filename);
|
virtual bool OpenFile(const std::string &filename);
|
||||||
|
|
|
||||||
|
|
@ -1501,10 +1501,7 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
|
||||||
{
|
{
|
||||||
for (U32 i = 0; i < skin["joint_names"].size(); ++i)
|
for (U32 i = 0; i < skin["joint_names"].size(); ++i)
|
||||||
{
|
{
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
mJointNames.push_back( skin[ "joint_names" ][ i ] );
|
||||||
// mJointNames.push_back( skin[ "joint_names" ][ i ] );
|
|
||||||
mJointNames.push_back( JointKey::construct( skin[ "joint_names" ][ i ] ) );
|
|
||||||
// </FS>ND>
|
|
||||||
mJointNums.push_back(-1);
|
mJointNums.push_back(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1594,10 +1591,7 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi
|
||||||
|
|
||||||
for (U32 i = 0; i < mJointNames.size(); ++i)
|
for (U32 i = 0; i < mJointNames.size(); ++i)
|
||||||
{
|
{
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
ret[ "joint_names" ][ i ] = mJointNames[ i ];
|
||||||
// ret[ "joint_names" ][ i ] = mJointNames[ i ];
|
|
||||||
ret[ "joint_names" ][ i ] = mJointNames[ i ].mName;
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
for (U32 j = 0; j < 4; j++)
|
for (U32 j = 0; j < 4; j++)
|
||||||
{
|
{
|
||||||
|
|
@ -1648,9 +1642,7 @@ void LLMeshSkinInfo::updateHash()
|
||||||
//mJointNames
|
//mJointNames
|
||||||
for (auto& name : mJointNames)
|
for (auto& name : mJointNames)
|
||||||
{
|
{
|
||||||
// <FS:Ansariel> Joint lookup speedup
|
hash.update(name);
|
||||||
//hash.update(name);
|
|
||||||
hash.update(name.mName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//mJointNums
|
//mJointNums
|
||||||
|
|
@ -1676,10 +1668,7 @@ U32 LLMeshSkinInfo::sizeBytes() const
|
||||||
res += sizeof(std::vector<std::string>) + sizeof(std::string) * static_cast<U32>(mJointNames.size());
|
res += sizeof(std::vector<std::string>) + sizeof(std::string) * static_cast<U32>(mJointNames.size());
|
||||||
for (U32 i = 0; i < mJointNames.size(); ++i)
|
for (U32 i = 0; i < mJointNames.size(); ++i)
|
||||||
{
|
{
|
||||||
// <FS> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
res += static_cast<U32>(mJointNames[i].size()); // actual size, not capacity
|
||||||
//res += static_cast<U32>(mJointNames[i].size()); // actual size, not capacity
|
|
||||||
res += static_cast<U32>(mJointNames[i].mName.size()); // actual size, not capacity
|
|
||||||
// </FS>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res += sizeof(std::vector<S32>) + sizeof(S32) * static_cast<U32>(mJointNums.size());
|
res += sizeof(std::vector<S32>) + sizeof(S32) * static_cast<U32>(mJointNums.size());
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,7 @@ public:
|
||||||
U32 sizeBytes() const;
|
U32 sizeBytes() const;
|
||||||
|
|
||||||
LLUUID mMeshID;
|
LLUUID mMeshID;
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
std::vector<std::string> mJointNames;
|
||||||
// std::vector<std::string> mJointNames;
|
|
||||||
std::vector< JointKey > mJointNames;
|
|
||||||
// </FS:ND>
|
|
||||||
mutable std::vector<S32> mJointNums;
|
mutable std::vector<S32> mJointNums;
|
||||||
typedef std::vector<LLMatrix4a> matrix_list_t;
|
typedef std::vector<LLMatrix4a> matrix_list_t;
|
||||||
matrix_list_t mInvBindMatrix;
|
matrix_list_t mInvBindMatrix;
|
||||||
|
|
|
||||||
|
|
@ -257,10 +257,7 @@ bool LLModelLoader::loadFromSLM(const std::string& filename)
|
||||||
if (!loaded_model->mSkinInfo.mJointNames.empty())
|
if (!loaded_model->mSkinInfo.mJointNames.empty())
|
||||||
{
|
{
|
||||||
//check to see if rig is valid
|
//check to see if rig is valid
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames );
|
||||||
// critiqueRigForUploadApplicability( loaded_model->mSkinInfo.mJointNames );
|
|
||||||
critiqueRigForUploadApplicability( toStringVector( loaded_model->mSkinInfo.mJointNames ) );
|
|
||||||
// </FS:ND>
|
|
||||||
}
|
}
|
||||||
else if (mCacheOnlyHitIfRigged)
|
else if (mCacheOnlyHitIfRigged)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class LLJoint;
|
||||||
|
|
||||||
typedef std::map<std::string, LLMatrix4> JointTransformMap;
|
typedef std::map<std::string, LLMatrix4> JointTransformMap;
|
||||||
typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt;
|
typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt;
|
||||||
typedef std::map<std::string, std::string> JointMap;
|
typedef std::map<std::string, std::string, std::less<>> JointMap;
|
||||||
typedef std::deque<std::string> JointNameSet;
|
typedef std::deque<std::string> JointNameSet;
|
||||||
|
|
||||||
const S32 SLM_SUPPORTED_VERSION = 3;
|
const S32 SLM_SUPPORTED_VERSION = 3;
|
||||||
|
|
@ -196,18 +196,6 @@ public:
|
||||||
void clearLog() { mWarningsArray.clear(); }
|
void clearLog() { mWarningsArray.clear(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
|
||||||
std::vector< std::string > toStringVector( std::vector< JointKey > const &aIn ) const
|
|
||||||
{
|
|
||||||
std::vector< std::string > out;
|
|
||||||
|
|
||||||
for( std::vector< JointKey >::const_iterator itr = aIn.begin(); itr != aIn.end(); ++itr )
|
|
||||||
out.push_back( itr->mName );
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
LLModelLoader::load_callback_t mLoadCallback;
|
LLModelLoader::load_callback_t mLoadCallback;
|
||||||
LLModelLoader::joint_lookup_func_t mJointLookupFunc;
|
LLModelLoader::joint_lookup_func_t mJointLookupFunc;
|
||||||
LLModelLoader::texture_load_func_t mTextureLoadFunc;
|
LLModelLoader::texture_load_func_t mTextureLoadFunc;
|
||||||
|
|
|
||||||
|
|
@ -1074,6 +1074,7 @@ void LLGLManager::initWGL()
|
||||||
// return false if unable (or unwilling due to old drivers) to init GL
|
// return false if unable (or unwilling due to old drivers) to init GL
|
||||||
bool LLGLManager::initGL()
|
bool LLGLManager::initGL()
|
||||||
{
|
{
|
||||||
|
LL_INFOS("RenderInit") << "Initializing OpenGL" << LL_ENDL; // <FS:Beq/> Extra logging to confirm usage on Linux
|
||||||
if (mInited)
|
if (mInited)
|
||||||
{
|
{
|
||||||
LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
|
LL_ERRS("RenderInit") << "Calling init on LLGLManager after already initialized!" << LL_ENDL;
|
||||||
|
|
@ -1514,6 +1515,11 @@ void LLGLManager::initExtensions()
|
||||||
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations
|
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations
|
||||||
|
|
||||||
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
|
LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
|
||||||
|
// FIRE-34655 - VRAM detection failing on Linux. Load all the GL functions we need.
|
||||||
|
#if LL_LINUX && !LL_MESA_HEADLESS
|
||||||
|
mHasNVXGpuMemoryInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
|
||||||
|
mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
// </FS:Zi>
|
// </FS:Zi>
|
||||||
|
|
|
||||||
|
|
@ -1076,8 +1076,8 @@ void LLGLSLShader::bind()
|
||||||
|
|
||||||
void LLGLSLShader::bind(U8 variant)
|
void LLGLSLShader::bind(U8 variant)
|
||||||
{
|
{
|
||||||
llassert(mGLTFVariants.size() == LLGLSLShader::NUM_GLTF_VARIANTS);
|
llassert_always(mGLTFVariants.size() == LLGLSLShader::NUM_GLTF_VARIANTS);
|
||||||
llassert(variant < LLGLSLShader::NUM_GLTF_VARIANTS);
|
llassert_always(variant < LLGLSLShader::NUM_GLTF_VARIANTS);
|
||||||
mGLTFVariants[variant].bind();
|
mGLTFVariants[variant].bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1085,7 +1085,7 @@ void LLGLSLShader::bind(bool rigged)
|
||||||
{
|
{
|
||||||
if (rigged)
|
if (rigged)
|
||||||
{
|
{
|
||||||
llassert(mRiggedVariant);
|
llassert_always(mRiggedVariant);
|
||||||
mRiggedVariant->bind();
|
mRiggedVariant->bind();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ void LLGLTexture::setBoostLevel(S32 level)
|
||||||
if(mBoostLevel != LLGLTexture::BOOST_NONE
|
if(mBoostLevel != LLGLTexture::BOOST_NONE
|
||||||
&& mBoostLevel != LLGLTexture::BOOST_ICON
|
&& mBoostLevel != LLGLTexture::BOOST_ICON
|
||||||
&& mBoostLevel != LLGLTexture::BOOST_THUMBNAIL
|
&& mBoostLevel != LLGLTexture::BOOST_THUMBNAIL
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Add the new grass, light and tree boosts
|
// Add the new grass, light and tree boosts
|
||||||
&& mBoostLevel != LLGLTexture::BOOST_GRASS
|
&& mBoostLevel != LLGLTexture::BOOST_GRASS
|
||||||
&& mBoostLevel != LLGLTexture::BOOST_LIGHT
|
&& mBoostLevel != LLGLTexture::BOOST_LIGHT
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ public:
|
||||||
BOOST_AVATAR_BAKED ,
|
BOOST_AVATAR_BAKED ,
|
||||||
BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead.
|
BOOST_TERRAIN , // Needed for minimap generation for now. Lower than BOOST_HIGH so the texture stats don't get forced, i.e. texture stats are manually managed by minimap/terrain instead.
|
||||||
|
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
BOOST_GRASS , // Grass has a alternative calculation for virtual and face sizes.
|
BOOST_GRASS , // Grass has a alternative calculation for virtual and face sizes.
|
||||||
BOOST_TREE , // Tree has a alternative calculation for virtual and face sizes.
|
BOOST_TREE , // Tree has a alternative calculation for virtual and face sizes.
|
||||||
BOOST_LIGHT , // Light textures has a alternative calculation for virtual and face sizes.
|
BOOST_LIGHT , // Light textures has a alternative calculation for virtual and face sizes.
|
||||||
|
|
|
||||||
|
|
@ -565,7 +565,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, const LLFontGL* font, L
|
||||||
{
|
{
|
||||||
if ( !force_resize )
|
if ( !force_resize )
|
||||||
{
|
{
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// if ( mMaxWidth >= 0.0f
|
// if ( mMaxWidth >= 0.0f
|
||||||
//&& mMaxWidth < screen_width)
|
//&& mMaxWidth < screen_width)
|
||||||
// If viewer window was made as small as possible with the console enabled, it would cause an assert error
|
// If viewer window was made as small as possible with the console enabled, it would cause an assert error
|
||||||
|
|
|
||||||
|
|
@ -1530,7 +1530,19 @@ void LLTextBase::draw()
|
||||||
bg_rect.intersectWith( text_rect );
|
bg_rect.intersectWith( text_rect );
|
||||||
|
|
||||||
gl_rect_2d( text_rect, bg_color, true );
|
gl_rect_2d( text_rect, bg_color, true );
|
||||||
|
|
||||||
|
// <FS> Additionally set the font color of highlighted text instead of using LabelTextColor
|
||||||
|
const LLColor4& font_color = ll::ui::SearchableControl::getHighlightFontColor();
|
||||||
|
setColor(font_color);
|
||||||
|
// </FS>
|
||||||
}
|
}
|
||||||
|
// <FS> Set the font color back to LabelTextColor if not highlighted
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const LLColor4& font_color = LLUIColorTable::instance().getColor("LabelTextColor");
|
||||||
|
setColor(font_color);
|
||||||
|
}
|
||||||
|
// </FS>
|
||||||
|
|
||||||
bool should_clip = mClip || mScroller != NULL;
|
bool should_clip = mClip || mScroller != NULL;
|
||||||
// <FS:Zi> Fix text bleeding at top edge of scrolling text editors
|
// <FS:Zi> Fix text bleeding at top edge of scrolling text editors
|
||||||
|
|
|
||||||
|
|
@ -1249,7 +1249,7 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)
|
||||||
//
|
//
|
||||||
LLUrlEntryPlace::LLUrlEntryPlace()
|
LLUrlEntryPlace::LLUrlEntryPlace()
|
||||||
{
|
{
|
||||||
mPattern = boost::regex("((hop://[-\\w\\.\\:\\@]+/)|((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://)))\\S+(?:/?(-?\\d+/-?\\d+/-?\\d+|-?\\d+/-?\\d+)/?)?", // <AW: hop:// protocol>
|
mPattern = boost::regex("(((hop://[-\\w\\.\\:\\@]+/)|((x-grid-location-info://[-\\w\\.]+/region/)|(secondlife://)))\\S+/?(\\d+/\\d+/-?\\d+|\\d+/-?\\d+)/?)|(hop://[-\\w\\.\\:\\@]+/[^\\s/]+/?(?![^\\s]))", // <AW: hop:// protocol>
|
||||||
boost::regex::perl|boost::regex::icase);
|
boost::regex::perl|boost::regex::icase);
|
||||||
mMenuName = "menu_url_slurl.xml";
|
mMenuName = "menu_url_slurl.xml";
|
||||||
mTooltip = LLTrans::getString("TooltipSLURL");
|
mTooltip = LLTrans::getString("TooltipSLURL");
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,15 @@ U32 LLDXHardware::getMBVideoMemoryViaWMI()
|
||||||
//Getting the version of graphics controller driver via WMI
|
//Getting the version of graphics controller driver via WMI
|
||||||
std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
||||||
{
|
{
|
||||||
std::string mDriverVersion;
|
// <FS:Beq> Add caching for WMI query results
|
||||||
|
LL_PROFILE_ZONE_SCOPED;
|
||||||
|
static auto driver_version = std::string();
|
||||||
|
|
||||||
|
if (!driver_version.empty())
|
||||||
|
{
|
||||||
|
return driver_version; // Return cached version
|
||||||
|
}
|
||||||
|
// </FS:Beq>
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
|
CoInitializeEx(0, COINIT_APARTMENTTHREADED);
|
||||||
IWbemLocator *pLoc = NULL;
|
IWbemLocator *pLoc = NULL;
|
||||||
|
|
@ -435,11 +443,11 @@ std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
||||||
std::string str = ll_convert_wide_to_string(ws);
|
std::string str = ll_convert_wide_to_string(ws);
|
||||||
LL_INFOS("AppInit") << " DriverVersion : " << str << LL_ENDL;
|
LL_INFOS("AppInit") << " DriverVersion : " << str << LL_ENDL;
|
||||||
|
|
||||||
if (mDriverVersion.empty())
|
if (driver_version.empty()) // <FS:Beq/> caching version (also make the varname not stupid)
|
||||||
{
|
{
|
||||||
mDriverVersion = str;
|
driver_version = str; // <FS:Beq/> caching version (also make the varname not stupid)
|
||||||
}
|
}
|
||||||
else if (mDriverVersion != str)
|
else if (driver_version != str) // <FS:Beq/> caching version (also make the varname not stupid)
|
||||||
{
|
{
|
||||||
if (vendor == GPU_ANY)
|
if (vendor == GPU_ANY)
|
||||||
{
|
{
|
||||||
|
|
@ -475,7 +483,7 @@ std::string LLDXHardware::getDriverVersionWMI(EGPUVendor vendor)
|
||||||
// supposed to always call CoUninitialize even if init returned false
|
// supposed to always call CoUninitialize even if init returned false
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
|
|
||||||
return mDriverVersion;
|
return driver_version; // <FS:Beq/> caching version of driver query
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_wstring(IDxDiagContainer* containerp, const WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize)
|
void get_wstring(IDxDiagContainer* containerp, const WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize)
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ set(viewer_SOURCE_FILES
|
||||||
dialogstack.cpp
|
dialogstack.cpp
|
||||||
exoflickr.cpp
|
exoflickr.cpp
|
||||||
exoflickrauth.cpp
|
exoflickrauth.cpp
|
||||||
|
fsprimfeedauth.cpp
|
||||||
exogroupmutelist.cpp
|
exogroupmutelist.cpp
|
||||||
floatermedialists.cpp
|
floatermedialists.cpp
|
||||||
fsareasearch.cpp
|
fsareasearch.cpp
|
||||||
|
|
@ -164,6 +165,7 @@ set(viewer_SOURCE_FILES
|
||||||
fspose.cpp
|
fspose.cpp
|
||||||
fsposeranimator.cpp
|
fsposeranimator.cpp
|
||||||
fsposingmotion.cpp
|
fsposingmotion.cpp
|
||||||
|
fsprimfeedauth.cpp
|
||||||
fsradar.cpp
|
fsradar.cpp
|
||||||
fsradarentry.cpp
|
fsradarentry.cpp
|
||||||
fsradarlistctrl.cpp
|
fsradarlistctrl.cpp
|
||||||
|
|
@ -182,6 +184,8 @@ set(viewer_SOURCE_FILES
|
||||||
lfsimfeaturehandler.cpp
|
lfsimfeaturehandler.cpp
|
||||||
llflickrconnect.cpp
|
llflickrconnect.cpp
|
||||||
llfloaterflickr.cpp
|
llfloaterflickr.cpp
|
||||||
|
fsprimfeedconnect.cpp
|
||||||
|
fsfloaterprimfeed.cpp
|
||||||
llpanelopenregionsettings.cpp
|
llpanelopenregionsettings.cpp
|
||||||
# <FS:Ansariel> [Legacy Bake]
|
# <FS:Ansariel> [Legacy Bake]
|
||||||
llagentwearablesfetch.cpp
|
llagentwearablesfetch.cpp
|
||||||
|
|
@ -910,6 +914,7 @@ set(viewer_HEADER_FILES
|
||||||
dialogstack.h
|
dialogstack.h
|
||||||
exoflickr.h
|
exoflickr.h
|
||||||
exoflickrauth.h
|
exoflickrauth.h
|
||||||
|
fsprimfeedauth.h
|
||||||
exogroupmutelist.h
|
exogroupmutelist.h
|
||||||
floatermedialists.h
|
floatermedialists.h
|
||||||
fsareasearch.h
|
fsareasearch.h
|
||||||
|
|
@ -980,6 +985,7 @@ set(viewer_HEADER_FILES
|
||||||
fspose.h
|
fspose.h
|
||||||
fsposeranimator.h
|
fsposeranimator.h
|
||||||
fsposingmotion.h
|
fsposingmotion.h
|
||||||
|
fsprimfeedauth.h
|
||||||
fsradar.h
|
fsradar.h
|
||||||
fsradarentry.h
|
fsradarentry.h
|
||||||
fsradarlistctrl.h
|
fsradarlistctrl.h
|
||||||
|
|
@ -999,6 +1005,8 @@ set(viewer_HEADER_FILES
|
||||||
lfsimfeaturehandler.h
|
lfsimfeaturehandler.h
|
||||||
llflickrconnect.h
|
llflickrconnect.h
|
||||||
llfloaterflickr.h
|
llfloaterflickr.h
|
||||||
|
fsprimfeedconnect.h
|
||||||
|
fsfloaterprimfeed.h
|
||||||
# <FS:Ansariel> [Legacy Bake]
|
# <FS:Ansariel> [Legacy Bake]
|
||||||
llagentwearablesfetch.h
|
llagentwearablesfetch.h
|
||||||
vjlocalmesh.h
|
vjlocalmesh.h
|
||||||
|
|
|
||||||
|
|
@ -871,8 +871,23 @@ void FloaterAO::onAnimationChanged(const LLUUID& animation)
|
||||||
|
|
||||||
if (mCurrentBoldItem)
|
if (mCurrentBoldItem)
|
||||||
{
|
{
|
||||||
((LLScrollListIcon*)mCurrentBoldItem->getColumn(0))->setValue("FSAO_Animation_Stopped");
|
// <AS:Chanayane> Safer casts
|
||||||
((LLScrollListText*)mCurrentBoldItem->getColumn(1))->setFontStyle(LLFontGL::NORMAL);
|
if (LLScrollListCell* icon_cell = mCurrentBoldItem->getColumn(0))
|
||||||
|
{
|
||||||
|
if (LLScrollListIcon* icon = dynamic_cast<LLScrollListIcon*>(icon_cell))
|
||||||
|
{
|
||||||
|
icon->setValue("FSAO_Animation_Stopped");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LLScrollListCell* text_cell = mCurrentBoldItem->getColumn(1))
|
||||||
|
{
|
||||||
|
if (LLScrollListText* text = dynamic_cast<LLScrollListText*>(text_cell))
|
||||||
|
{
|
||||||
|
text->setFontStyle(LLFontGL::NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// </AS:Chanayane>
|
||||||
|
|
||||||
mCurrentBoldItem = nullptr;
|
mCurrentBoldItem = nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -882,21 +897,46 @@ void FloaterAO::onAnimationChanged(const LLUUID& animation)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// why do we have no LLScrollListCtrl::getItemByUserdata() ? -Zi
|
// <AS:Chanayane> Fix potential nullptr
|
||||||
for (auto item : mAnimationList->getAllData())
|
if (!mAnimationList)
|
||||||
{
|
{
|
||||||
LLUUID* id = (LLUUID*)item->getUserdata();
|
LL_WARNS("AO") << "Animation list control is null." << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// </AS:Chanayane>
|
||||||
|
|
||||||
if (id == &animation)
|
// <AS:Chanayane> Safer casts
|
||||||
|
// why do we have no LLScrollListCtrl::getItemByUserdata() ? -Zi
|
||||||
|
for (LLScrollListItem* item : mAnimationList->getAllData())
|
||||||
|
{
|
||||||
|
LLUUID* id = static_cast<LLUUID*>(item->getUserdata());
|
||||||
|
// <AS:Chanayane> compares the LLUUID values instead of pointer values
|
||||||
|
//if (id == &animation)
|
||||||
|
if (id && *id == animation)
|
||||||
|
// </AS:Chanayane>
|
||||||
{
|
{
|
||||||
mCurrentBoldItem = item;
|
mCurrentBoldItem = item;
|
||||||
|
|
||||||
((LLScrollListIcon*)mCurrentBoldItem->getColumn(0))->setValue("FSAO_Animation_Playing");
|
if (LLScrollListCell* icon_cell = mCurrentBoldItem->getColumn(0))
|
||||||
((LLScrollListText*)mCurrentBoldItem->getColumn(1))->setFontStyle(LLFontGL::BOLD);
|
{
|
||||||
|
if (LLScrollListIcon* icon = dynamic_cast<LLScrollListIcon*>(icon_cell))
|
||||||
|
{
|
||||||
|
icon->setValue("FSAO_Animation_Playing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LLScrollListCell* text_cell = mCurrentBoldItem->getColumn(1))
|
||||||
|
{
|
||||||
|
if (LLScrollListText* text = dynamic_cast<LLScrollListText*>(text_cell))
|
||||||
|
{
|
||||||
|
text->setFontStyle(LLFontGL::BOLD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// </AS:Chanayane>
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
|
|
|
||||||
|
|
@ -999,6 +999,13 @@ void AOEngine::playAnimation(const LLUUID& animation)
|
||||||
}
|
}
|
||||||
|
|
||||||
LLViewerInventoryItem* item = gInventory.getItem(animation);
|
LLViewerInventoryItem* item = gInventory.getItem(animation);
|
||||||
|
|
||||||
|
if (!item)
|
||||||
|
{
|
||||||
|
LL_WARNS("AOEngine") << "Inventory item for animation " << animation << " not found." << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AOSet::AOAnimation anim;
|
AOSet::AOAnimation anim;
|
||||||
anim.mName = item->LLInventoryItem::getName();
|
anim.mName = item->LLInventoryItem::getName();
|
||||||
anim.mInventoryUUID = item->getUUID();
|
anim.mInventoryUUID = item->getUUID();
|
||||||
|
|
@ -1007,12 +1014,21 @@ void AOEngine::playAnimation(const LLUUID& animation)
|
||||||
|
|
||||||
// if we can find the original animation already right here, save its asset ID, otherwise this will
|
// if we can find the original animation already right here, save its asset ID, otherwise this will
|
||||||
// be tried again in AOSet::getAnimationForState() and/or AOEngine::cycle()
|
// be tried again in AOSet::getAnimationForState() and/or AOEngine::cycle()
|
||||||
|
LLUUID newAnimation;
|
||||||
if (item->getLinkedItem())
|
if (item->getLinkedItem())
|
||||||
{
|
{
|
||||||
anim.mAssetUUID = item->getAssetUUID();
|
newAnimation = item->getAssetUUID();
|
||||||
|
//anim.mAssetUUID = item->getAssetUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
LLUUID newAnimation = anim.mAssetUUID;
|
if (newAnimation.isNull())
|
||||||
|
{
|
||||||
|
LL_WARNS("AOEngine") << "New animation UUID is null for animation " << animation << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
anim.mAssetUUID = newAnimation;
|
||||||
|
|
||||||
|
//LLUUID newAnimation = anim.mAssetUUID;
|
||||||
LLUUID oldAnimation = state->mCurrentAnimationID;
|
LLUUID oldAnimation = state->mCurrentAnimationID;
|
||||||
|
|
||||||
// don't do anything if the animation didn't change
|
// don't do anything if the animation didn't change
|
||||||
|
|
@ -1024,7 +1040,7 @@ void AOEngine::playAnimation(const LLUUID& animation)
|
||||||
mAnimationChangedSignal(LLUUID::null);
|
mAnimationChangedSignal(LLUUID::null);
|
||||||
|
|
||||||
// Searches for the index of the animation
|
// Searches for the index of the animation
|
||||||
U32 idx = -1;
|
S32 idx = -1;
|
||||||
for (U32 i = 0; i < state->mAnimations.size(); i++)
|
for (U32 i = 0; i < state->mAnimations.size(); i++)
|
||||||
{
|
{
|
||||||
if (state->mAnimations[i].mAssetUUID == newAnimation)
|
if (state->mAnimations[i].mAssetUUID == newAnimation)
|
||||||
|
|
@ -1033,18 +1049,22 @@ void AOEngine::playAnimation(const LLUUID& animation)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (idx < 0)
|
if (idx == -1)
|
||||||
{
|
{
|
||||||
idx = 0;
|
LL_WARNS("AOEngine") << "Animation index not found for animation " << animation << LL_ENDL;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->mCurrentAnimation = idx;
|
state->mCurrentAnimation = static_cast<U32>(idx);
|
||||||
state->mCurrentAnimationID = newAnimation;
|
state->mCurrentAnimationID = newAnimation;
|
||||||
if (newAnimation.notNull())
|
if (newAnimation.notNull())
|
||||||
{
|
{
|
||||||
LL_DEBUGS("AOEngine") << "requesting animation start for motion " << gAnimLibrary.animationName(mLastMotion) << ": " << newAnimation << LL_ENDL;
|
LL_DEBUGS("AOEngine") << "requesting animation start for motion " << gAnimLibrary.animationName(mLastMotion) << ": " << newAnimation << LL_ENDL;
|
||||||
gAgent.sendAnimationRequest(newAnimation, ANIM_REQUEST_START);
|
gAgent.sendAnimationRequest(newAnimation, ANIM_REQUEST_START);
|
||||||
mAnimationChangedSignal(state->mAnimations[state->mCurrentAnimation].mInventoryUUID);
|
if (state->mCurrentAnimation < state->mAnimations.size())
|
||||||
|
{
|
||||||
|
mAnimationChangedSignal(state->mAnimations[state->mCurrentAnimation].mInventoryUUID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,16 @@
|
||||||
is_running_function="Floater.IsOpen"
|
is_running_function="Floater.IsOpen"
|
||||||
is_running_parameters="flickr"
|
is_running_parameters="flickr"
|
||||||
/>
|
/>
|
||||||
|
<command name="primfeed"
|
||||||
|
available_in_toybox="true"
|
||||||
|
icon="Command_Primfeed_Icon"
|
||||||
|
label_ref="Command_Primfeed_Label"
|
||||||
|
tooltip_ref="Command_Primfeed_Tooltip"
|
||||||
|
execute_function="Floater.Toggle"
|
||||||
|
execute_parameters="primfeed"
|
||||||
|
is_running_function="Floater.IsOpen"
|
||||||
|
is_running_parameters="primfeed"
|
||||||
|
/>
|
||||||
<command name="speak"
|
<command name="speak"
|
||||||
available_in_toybox="true"
|
available_in_toybox="true"
|
||||||
icon="Command_Speak_Icon"
|
icon="Command_Speak_Icon"
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,17 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<string>http://phoenixviewer.com/app/fsdata/grids.xml</string>
|
<string>http://phoenixviewer.com/app/fsdata/grids.xml</string>
|
||||||
</map>
|
</map>
|
||||||
|
<key>FSPrimfeedViewerApiKey</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Viewer key for API login.</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<string>xAcXYt8SBius3Lor4wHle8L96PDHYlAZuWYXIYQUdW4b09mjhQUAwiqmWp5UNYXLpq5GSUtuKHuDYLwaueACPkew93l6MRY8jfBKSH09kv0zyGglpky07X7X7Sp4Rzin</string>
|
||||||
|
</map>
|
||||||
<key>FSGridBuilderURL</key>
|
<key>FSGridBuilderURL</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -18553,6 +18564,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
||||||
<string>world_map</string>
|
<string>world_map</string>
|
||||||
<string>preferences</string>
|
<string>preferences</string>
|
||||||
<string>flickr</string>
|
<string>flickr</string>
|
||||||
|
<string>primfeed</string>
|
||||||
</array>
|
</array>
|
||||||
<key>Backup</key>
|
<key>Backup</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
|
|
@ -24806,6 +24818,39 @@ Change of this parameter will affect the layout of buttons in notification toast
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>4</integer>
|
<integer>4</integer>
|
||||||
</map>
|
</map>
|
||||||
|
<key>FSLastSnapshotToPrimfeedHeight</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>The height of the last Primfeed snapshot, in px</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>S32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>768</integer>
|
||||||
|
</map>
|
||||||
|
<key>FSLastSnapshotToPrimfeedWidth</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>The width of the last Primfeed snapshot, in px</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>S32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>1024</integer>
|
||||||
|
</map>
|
||||||
|
<key>FSLastSnapshotToPrimfeedResolution</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>At what resolution should snapshots be posted on Primfeed. 0=Current Window, 1=320x240, 2=640x480, 3=800x600, 4=1024x768, 5=1280x1024, 6=1600x1200, 7=Custom</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>S32</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>4</integer>
|
||||||
|
</map>
|
||||||
<key>FSLastSnapshotToTwitterHeight</key>
|
<key>FSLastSnapshotToTwitterHeight</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -25092,6 +25137,19 @@ Change of this parameter will affect the layout of buttons in notification toast
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>1</integer>
|
<integer>1</integer>
|
||||||
</map>
|
</map>
|
||||||
|
<key>FSNoVersionPopup</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Disables version popup on the Firestorm Login page</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>HideFromEditor</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</map>
|
||||||
<key>FSllOwnerSayToScriptDebugWindowRouting</key>
|
<key>FSllOwnerSayToScriptDebugWindowRouting</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -26365,5 +26423,27 @@ Change of this parameter will affect the layout of buttons in notification toast
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</map>
|
</map>
|
||||||
|
<key>FSSnapshotLocalNamesWithTimestamps</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>include a timestamp in the filename when saving snapshots locally</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</map>
|
||||||
|
<key>FSRepeatedEnvTogglesShared</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Whether repeated presses of sky preset shortcuts should revert to shared environment</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</map>
|
||||||
</map>
|
</map>
|
||||||
</llsd>
|
</llsd>
|
||||||
|
|
|
||||||
|
|
@ -1358,6 +1358,83 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</map>
|
</map>
|
||||||
|
<key>FSPrimfeedOAuthToken</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>contains the secure authentication toke to post to your primfeed account (do not share)</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<string></string>
|
||||||
|
</map>
|
||||||
|
<key>FSPrimfeedProfileLink</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>The profile page for the account associated with the currently linked Primfeed account</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<string></string>
|
||||||
|
</map>
|
||||||
|
<key>FSPrimfeedPlan</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>The plan type associated with the currently linked Primfeed account</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<string></string>
|
||||||
|
</map>
|
||||||
|
<key>FSPrimfeedUsername</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>The username associated with the currently linked Primfeed account</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<string></string>
|
||||||
|
</map>
|
||||||
|
<key>FSPrimfeedCommercialContent</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Does this post contain commercial content</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</map>
|
||||||
|
<key>FSPrimfeedAddToPublicGallery</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Should this post go to the public gallery?</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</map>
|
||||||
|
<key>FSPrimfeedOpenURLOnPost</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>if true open the URL in a browser when the post completes</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</map>
|
||||||
<key>FSProtectedFolders</key>
|
<key>FSProtectedFolders</key>
|
||||||
<map>
|
<map>
|
||||||
<key>Comment</key>
|
<key>Comment</key>
|
||||||
|
|
@ -1369,5 +1446,49 @@
|
||||||
<key>Value</key>
|
<key>Value</key>
|
||||||
<array/>
|
<array/>
|
||||||
</map>
|
</map>
|
||||||
|
<key>FSPrimfeedPhotoRating</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Content rating to be shared with Primfeed.</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Integer</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</map>
|
||||||
|
<key>FSPrimfeedPhotoResolution</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Last used resolution for Primfeed photos.</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>LLSD</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<array/>
|
||||||
|
</map>
|
||||||
|
<key>FlickrPhotoResolution</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Last used resolution for Primfeed photos.</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>LLSD</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<array/>
|
||||||
|
</map>
|
||||||
|
<key>FlickrPhotoRating</key>
|
||||||
|
<map>
|
||||||
|
<key>Comment</key>
|
||||||
|
<string>Content rating to be shared with Flickr.</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Type</key>
|
||||||
|
<string>Integer</string>
|
||||||
|
<key>Value</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</map>
|
||||||
</map>
|
</map>
|
||||||
</llsd>
|
</llsd>
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ std::string BugSplatAttributes::to_xml_token(const std::string& input)
|
||||||
|
|
||||||
bool BugSplatAttributes::writeToFile(const std::string& file_path)
|
bool BugSplatAttributes::writeToFile(const std::string& file_path)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
|
||||||
// Write to a temporary file first
|
// Write to a temporary file first
|
||||||
|
|
@ -91,6 +92,7 @@ bool BugSplatAttributes::writeToFile(const std::string& file_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out all other categories
|
// Write out all other categories
|
||||||
|
// BugSplat chaanged the XML format and there is no strict category support now. For now we'll prefix the category to each attribute
|
||||||
for (const auto& cat_pair : mAttributes)
|
for (const auto& cat_pair : mAttributes)
|
||||||
{
|
{
|
||||||
const std::string& category = cat_pair.first;
|
const std::string& category = cat_pair.first;
|
||||||
|
|
@ -101,14 +103,12 @@ bool BugSplatAttributes::writeToFile(const std::string& file_path)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ofs << " <" << category << ">\n";
|
|
||||||
for (const auto& kv : cat_pair.second)
|
for (const auto& kv : cat_pair.second)
|
||||||
{
|
{
|
||||||
const std::string& key = kv.first;
|
const std::string& key = kv.first;
|
||||||
const std::string& val = kv.second;
|
const std::string& val = kv.second;
|
||||||
ofs << " <" << key << ">" << val << "</" << key << ">\n";
|
ofs << " <" << category << "-" << key << ">" << val << "</" << category << "-" << key << ">\n";
|
||||||
}
|
}
|
||||||
ofs << " </" << category << ">\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ofs << "</XmlCrashContext>\n";
|
ofs << "</XmlCrashContext>\n";
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ RenderReflectionProbeLevel 1 3
|
||||||
RenderMirrors 1 0
|
RenderMirrors 1 0
|
||||||
RenderHeroProbeResolution 1 1024
|
RenderHeroProbeResolution 1 1024
|
||||||
RenderHeroProbeDistance 1 16
|
RenderHeroProbeDistance 1 16
|
||||||
RenderHeroProbeUpdateRate 1 1
|
RenderHeroProbeUpdateRate 1 2
|
||||||
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
||||||
RenderCASSharpness 1 0.4
|
RenderCASSharpness 1 0.4
|
||||||
RenderExposure 1 1
|
RenderExposure 1 1
|
||||||
|
|
@ -375,7 +375,7 @@ RenderReflectionProbeLevel 1 3
|
||||||
RenderMirrors 1 0
|
RenderMirrors 1 0
|
||||||
RenderHeroProbeResolution 1 2048
|
RenderHeroProbeResolution 1 2048
|
||||||
RenderHeroProbeDistance 1 16
|
RenderHeroProbeDistance 1 16
|
||||||
RenderHeroProbeUpdateRate 1 1
|
RenderHeroProbeUpdateRate 1 2
|
||||||
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
||||||
RenderCASSharpness 1 0.4
|
RenderCASSharpness 1 0.4
|
||||||
RenderExposure 1 1
|
RenderExposure 1 1
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ RenderReflectionProbeLevel 1 3
|
||||||
RenderMirrors 1 0
|
RenderMirrors 1 0
|
||||||
RenderHeroProbeResolution 1 1024
|
RenderHeroProbeResolution 1 1024
|
||||||
RenderHeroProbeDistance 1 16
|
RenderHeroProbeDistance 1 16
|
||||||
RenderHeroProbeUpdateRate 1 1
|
RenderHeroProbeUpdateRate 1 2
|
||||||
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
||||||
RenderCASSharpness 1 0.4
|
RenderCASSharpness 1 0.4
|
||||||
RenderExposure 1 1
|
RenderExposure 1 1
|
||||||
|
|
@ -375,7 +375,7 @@ RenderReflectionProbeLevel 1 3
|
||||||
RenderMirrors 1 0
|
RenderMirrors 1 0
|
||||||
RenderHeroProbeResolution 1 2048
|
RenderHeroProbeResolution 1 2048
|
||||||
RenderHeroProbeDistance 1 16
|
RenderHeroProbeDistance 1 16
|
||||||
RenderHeroProbeUpdateRate 1 1
|
RenderHeroProbeUpdateRate 1 2
|
||||||
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
||||||
RenderCASSharpness 1 0.4
|
RenderCASSharpness 1 0.4
|
||||||
RenderExposure 1 1
|
RenderExposure 1 1
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ RenderReflectionProbeLevel 1 2
|
||||||
RenderMirrors 1 0
|
RenderMirrors 1 0
|
||||||
RenderHeroProbeResolution 1 512
|
RenderHeroProbeResolution 1 512
|
||||||
RenderHeroProbeDistance 1 16
|
RenderHeroProbeDistance 1 16
|
||||||
RenderHeroProbeUpdateRate 1 1
|
RenderHeroProbeUpdateRate 1 2
|
||||||
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
||||||
RenderCASSharpness 1 0.4
|
RenderCASSharpness 1 0.4
|
||||||
RenderExposure 1 1
|
RenderExposure 1 1
|
||||||
|
|
@ -375,7 +375,7 @@ RenderReflectionProbeLevel 1 3
|
||||||
RenderMirrors 1 0
|
RenderMirrors 1 0
|
||||||
RenderHeroProbeResolution 1 1024
|
RenderHeroProbeResolution 1 1024
|
||||||
RenderHeroProbeDistance 1 16
|
RenderHeroProbeDistance 1 16
|
||||||
RenderHeroProbeUpdateRate 1 1
|
RenderHeroProbeUpdateRate 1 2
|
||||||
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
RenderHeroProbeConservativeUpdateMultiplier 1 4
|
||||||
RenderCASSharpness 1 0.4
|
RenderCASSharpness 1 0.4
|
||||||
RenderExposure 1 1
|
RenderExposure 1 1
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ FSAreaSearch::FSAreaSearch(const LLSD& key) :
|
||||||
mFilterPhantom(false),
|
mFilterPhantom(false),
|
||||||
mFilterAttachment(false),
|
mFilterAttachment(false),
|
||||||
mFilterMoaP(false),
|
mFilterMoaP(false),
|
||||||
|
mFilterReflectionProbe(false),
|
||||||
mFilterDistance(false),
|
mFilterDistance(false),
|
||||||
mFilterDistanceMin(0),
|
mFilterDistanceMin(0),
|
||||||
mFilterDistanceMax(999999),
|
mFilterDistanceMax(999999),
|
||||||
|
|
@ -166,6 +167,7 @@ FSAreaSearch::FSAreaSearch(const LLSD& key) :
|
||||||
mBeacons(false),
|
mBeacons(false),
|
||||||
mExcludeAttachment(true),
|
mExcludeAttachment(true),
|
||||||
mExcludeTemporary(true),
|
mExcludeTemporary(true),
|
||||||
|
mExcludeReflectionProbe(false),
|
||||||
mExcludePhysics(true),
|
mExcludePhysics(true),
|
||||||
mExcludeChildPrims(true),
|
mExcludeChildPrims(true),
|
||||||
mExcludeNeighborRegions(true),
|
mExcludeNeighborRegions(true),
|
||||||
|
|
@ -545,6 +547,11 @@ bool FSAreaSearch::isSearchableObject(LLViewerObject* objectp, LLViewerRegion* o
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mExcludeReflectionProbe && objectp->mReflectionProbe.notNull())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -908,6 +915,11 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mFilterReflectionProbe && !objectp->mReflectionProbe.notNull())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
// Find text
|
// Find text
|
||||||
//-----------------------------------------------------------------------
|
//-----------------------------------------------------------------------
|
||||||
|
|
@ -2217,6 +2229,10 @@ bool FSPanelAreaSearchFilter::postBuild()
|
||||||
mCheckboxExcludetemporary->set(true);
|
mCheckboxExcludetemporary->set(true);
|
||||||
mCheckboxExcludetemporary->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
mCheckboxExcludetemporary->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||||
|
|
||||||
|
mCheckboxExcludeReflectionProbes = getChild<LLCheckBoxCtrl>("exclude_reflection_probes");
|
||||||
|
mCheckboxExcludeReflectionProbes->set(false);
|
||||||
|
mCheckboxExcludeReflectionProbes->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||||
|
|
||||||
mCheckboxExcludeChildPrim = getChild<LLCheckBoxCtrl>("exclude_childprim");
|
mCheckboxExcludeChildPrim = getChild<LLCheckBoxCtrl>("exclude_childprim");
|
||||||
mCheckboxExcludeChildPrim->set(true);
|
mCheckboxExcludeChildPrim->set(true);
|
||||||
mCheckboxExcludeChildPrim->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
mCheckboxExcludeChildPrim->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||||
|
|
@ -2240,6 +2256,9 @@ bool FSPanelAreaSearchFilter::postBuild()
|
||||||
mCheckboxMoaP = getChild<LLCheckBoxCtrl>("filter_moap");
|
mCheckboxMoaP = getChild<LLCheckBoxCtrl>("filter_moap");
|
||||||
mCheckboxMoaP->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
mCheckboxMoaP->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||||
|
|
||||||
|
mCheckboxReflectionProbe = getChild<LLCheckBoxCtrl>("filter_reflection_probe");
|
||||||
|
mCheckboxReflectionProbe->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||||
|
|
||||||
mCheckboxPermCopy = getChild<LLCheckBoxCtrl>("filter_perm_copy");
|
mCheckboxPermCopy = getChild<LLCheckBoxCtrl>("filter_perm_copy");
|
||||||
mCheckboxPermCopy->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
mCheckboxPermCopy->setCommitCallback(boost::bind(&FSPanelAreaSearchFilter::onCommitCheckbox, this));
|
||||||
|
|
||||||
|
|
@ -2262,6 +2281,7 @@ void FSPanelAreaSearchFilter::onCommitCheckbox()
|
||||||
mFSAreaSearch->setFilterForSale(mCheckboxForSale->get());
|
mFSAreaSearch->setFilterForSale(mCheckboxForSale->get());
|
||||||
mFSAreaSearch->setFilterDistance(mCheckboxDistance->get());
|
mFSAreaSearch->setFilterDistance(mCheckboxDistance->get());
|
||||||
mFSAreaSearch->setFilterMoaP(mCheckboxMoaP->get());
|
mFSAreaSearch->setFilterMoaP(mCheckboxMoaP->get());
|
||||||
|
mFSAreaSearch->setFilterReflectionProbe(mCheckboxReflectionProbe->get());
|
||||||
|
|
||||||
if (mCheckboxExcludePhysics->get())
|
if (mCheckboxExcludePhysics->get())
|
||||||
{
|
{
|
||||||
|
|
@ -2291,6 +2311,19 @@ void FSPanelAreaSearchFilter::onCommitCheckbox()
|
||||||
}
|
}
|
||||||
mFSAreaSearch->setFilterTemporary(mCheckboxTemporary->get());
|
mFSAreaSearch->setFilterTemporary(mCheckboxTemporary->get());
|
||||||
|
|
||||||
|
if (mCheckboxExcludeReflectionProbes->get())
|
||||||
|
{
|
||||||
|
mFSAreaSearch->setFilterReflectionProbe(false);
|
||||||
|
mCheckboxReflectionProbe->set(false);
|
||||||
|
mCheckboxReflectionProbe->setEnabled(false);
|
||||||
|
mFSAreaSearch->setExcludeReflectionProbe(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCheckboxReflectionProbe->setEnabled(true);
|
||||||
|
mFSAreaSearch->setExcludeReflectionProbe(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (mCheckboxExcludeAttachment->get())
|
if (mCheckboxExcludeAttachment->get())
|
||||||
{
|
{
|
||||||
mFSAreaSearch->setFilterAttachment(false);
|
mFSAreaSearch->setFilterAttachment(false);
|
||||||
|
|
|
||||||
|
|
@ -141,12 +141,14 @@ public:
|
||||||
void setFilterPhantom(bool b) { mFilterPhantom = b; }
|
void setFilterPhantom(bool b) { mFilterPhantom = b; }
|
||||||
void setFilterAttachment(bool b) { mFilterAttachment = b; }
|
void setFilterAttachment(bool b) { mFilterAttachment = b; }
|
||||||
void setFilterMoaP(bool b) { mFilterMoaP = b; }
|
void setFilterMoaP(bool b) { mFilterMoaP = b; }
|
||||||
|
void setFilterReflectionProbe(bool b) { mFilterReflectionProbe = b; }
|
||||||
|
|
||||||
void setRegexSearch(bool b) { mRegexSearch = b; }
|
void setRegexSearch(bool b) { mRegexSearch = b; }
|
||||||
void setBeacons(bool b) { mBeacons = b; }
|
void setBeacons(bool b) { mBeacons = b; }
|
||||||
|
|
||||||
void setExcludeAttachment(bool b) { mExcludeAttachment = b; }
|
void setExcludeAttachment(bool b) { mExcludeAttachment = b; }
|
||||||
void setExcludetemporary(bool b) { mExcludeTemporary = b; }
|
void setExcludetemporary(bool b) { mExcludeTemporary = b; }
|
||||||
|
void setExcludeReflectionProbe(bool b) { mExcludeReflectionProbe = b; }
|
||||||
void setExcludePhysics(bool b) { mExcludePhysics = b; }
|
void setExcludePhysics(bool b) { mExcludePhysics = b; }
|
||||||
void setExcludeChildPrims(bool b) { mExcludeChildPrims = b; }
|
void setExcludeChildPrims(bool b) { mExcludeChildPrims = b; }
|
||||||
void setExcludeNeighborRegions(bool b) { mExcludeNeighborRegions = b; }
|
void setExcludeNeighborRegions(bool b) { mExcludeNeighborRegions = b; }
|
||||||
|
|
@ -230,6 +232,7 @@ private:
|
||||||
|
|
||||||
bool mExcludeAttachment;
|
bool mExcludeAttachment;
|
||||||
bool mExcludeTemporary;
|
bool mExcludeTemporary;
|
||||||
|
bool mExcludeReflectionProbe;
|
||||||
bool mExcludePhysics;
|
bool mExcludePhysics;
|
||||||
bool mExcludeChildPrims;
|
bool mExcludeChildPrims;
|
||||||
bool mExcludeNeighborRegions;
|
bool mExcludeNeighborRegions;
|
||||||
|
|
@ -240,6 +243,7 @@ private:
|
||||||
bool mFilterPhantom;
|
bool mFilterPhantom;
|
||||||
bool mFilterAttachment;
|
bool mFilterAttachment;
|
||||||
bool mFilterMoaP;
|
bool mFilterMoaP;
|
||||||
|
bool mFilterReflectionProbe;
|
||||||
|
|
||||||
bool mFilterForSale;
|
bool mFilterForSale;
|
||||||
S32 mFilterForSaleMin;
|
S32 mFilterForSaleMin;
|
||||||
|
|
@ -382,6 +386,7 @@ private:
|
||||||
LLCheckBoxCtrl* mCheckboxLocked;
|
LLCheckBoxCtrl* mCheckboxLocked;
|
||||||
LLCheckBoxCtrl* mCheckboxPhantom;
|
LLCheckBoxCtrl* mCheckboxPhantom;
|
||||||
LLCheckBoxCtrl* mCheckboxMoaP;
|
LLCheckBoxCtrl* mCheckboxMoaP;
|
||||||
|
LLCheckBoxCtrl* mCheckboxReflectionProbe;
|
||||||
LLCheckBoxCtrl* mCheckboxDistance;
|
LLCheckBoxCtrl* mCheckboxDistance;
|
||||||
LLSpinCtrl* mSpinDistanceMinValue;
|
LLSpinCtrl* mSpinDistanceMinValue;
|
||||||
LLSpinCtrl* mSpinDistanceMaxValue;
|
LLSpinCtrl* mSpinDistanceMaxValue;
|
||||||
|
|
@ -393,6 +398,7 @@ private:
|
||||||
LLCheckBoxCtrl* mCheckboxExcludeAttachment;
|
LLCheckBoxCtrl* mCheckboxExcludeAttachment;
|
||||||
LLCheckBoxCtrl* mCheckboxExcludePhysics;
|
LLCheckBoxCtrl* mCheckboxExcludePhysics;
|
||||||
LLCheckBoxCtrl* mCheckboxExcludetemporary;
|
LLCheckBoxCtrl* mCheckboxExcludetemporary;
|
||||||
|
LLCheckBoxCtrl* mCheckboxExcludeReflectionProbes;
|
||||||
LLCheckBoxCtrl* mCheckboxExcludeChildPrim;
|
LLCheckBoxCtrl* mCheckboxExcludeChildPrim;
|
||||||
LLCheckBoxCtrl* mCheckboxExcludeNeighborRegions;
|
LLCheckBoxCtrl* mCheckboxExcludeNeighborRegions;
|
||||||
LLCheckBoxCtrl* mCheckboxPermCopy;
|
LLCheckBoxCtrl* mCheckboxPermCopy;
|
||||||
|
|
|
||||||
|
|
@ -479,6 +479,10 @@ void FSFloaterIM::sendMsgFromInputEditor(EChatType type)
|
||||||
{
|
{
|
||||||
str_version_tag = "Release";
|
str_version_tag = "Release";
|
||||||
}
|
}
|
||||||
|
else if( viewer_maturity == LLVersionInfo::FSViewerMaturity::STREAMING_VIEWER )
|
||||||
|
{
|
||||||
|
str_version_tag = "Streaming";
|
||||||
|
}
|
||||||
else if( viewer_maturity == LLVersionInfo::FSViewerMaturity::UNOFFICIAL_VIEWER )
|
else if( viewer_maturity == LLVersionInfo::FSViewerMaturity::UNOFFICIAL_VIEWER )
|
||||||
{
|
{
|
||||||
str_version_tag = "Unofficial";
|
str_version_tag = "Unofficial";
|
||||||
|
|
@ -502,6 +506,10 @@ void FSFloaterIM::sendMsgFromInputEditor(EChatType type)
|
||||||
{
|
{
|
||||||
str_version_tag = "Unofficial";
|
str_version_tag = "Unofficial";
|
||||||
}
|
}
|
||||||
|
if( viewer_maturity == LLVersionInfo::FSViewerMaturity::STREAMING_VIEWER )
|
||||||
|
{
|
||||||
|
str_version_tag = "Streaming";
|
||||||
|
}
|
||||||
else if( viewer_maturity != LLVersionInfo::FSViewerMaturity::RELEASE_VIEWER )
|
else if( viewer_maturity != LLVersionInfo::FSViewerMaturity::RELEASE_VIEWER )
|
||||||
{
|
{
|
||||||
str_version_tag = "pre-Release";
|
str_version_tag = "pre-Release";
|
||||||
|
|
@ -1245,6 +1253,22 @@ FSFloaterIM* FSFloaterIM::show(const LLUUID& session_id)
|
||||||
if (!gIMMgr->hasSession(session_id))
|
if (!gIMMgr->hasSession(session_id))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
// <AS:chanayane> [FIRE-34494] fixes unable to open an IM with someone who started a group chat
|
||||||
|
// Prevent showing non-IM sessions in FSFloaterIM::show()
|
||||||
|
LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
|
||||||
|
if (!session || (
|
||||||
|
IM_NOTHING_SPECIAL != session->mType
|
||||||
|
&& IM_SESSION_P2P_INVITE != session->mType
|
||||||
|
&& IM_SESSION_INVITE != session->mType
|
||||||
|
&& IM_SESSION_CONFERENCE_START != session->mType
|
||||||
|
&& IM_SESSION_GROUP_START != session->mType))
|
||||||
|
{
|
||||||
|
LL_WARNS("IMVIEW") << "Attempted to show FSFloaterIM for non-IM session: "
|
||||||
|
<< (session ? std::to_string(session->mType) : "null") << LL_ENDL;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
// </AS:chanayane>
|
||||||
|
|
||||||
if (!isChatMultiTab())
|
if (!isChatMultiTab())
|
||||||
{
|
{
|
||||||
//hide all
|
//hide all
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@
|
||||||
#include "llcheckboxctrl.h"
|
#include "llcheckboxctrl.h"
|
||||||
#include "llcommonutils.h"
|
#include "llcommonutils.h"
|
||||||
#include "llcontrolavatar.h"
|
#include "llcontrolavatar.h"
|
||||||
|
#include "llnotificationsutil.h"
|
||||||
#include "lldiriterator.h"
|
#include "lldiriterator.h"
|
||||||
#include "llsdserialize.h"
|
#include "llsdserialize.h"
|
||||||
#include "llscrolllistctrl.h"
|
#include "llscrolllistctrl.h"
|
||||||
|
|
@ -61,7 +62,10 @@ constexpr std::string_view POSER_TRACKPAD_SENSITIVITY_SAVE_KEY = "FSPoserTrackpa
|
||||||
constexpr std::string_view POSER_STOPPOSINGWHENCLOSED_SAVE_KEY = "FSPoserStopPosingWhenClosed";
|
constexpr std::string_view POSER_STOPPOSINGWHENCLOSED_SAVE_KEY = "FSPoserStopPosingWhenClosed";
|
||||||
constexpr std::string_view POSER_RESETBASEROTONEDIT_SAVE_KEY = "FSPoserResetBaseRotationOnEdit";
|
constexpr std::string_view POSER_RESETBASEROTONEDIT_SAVE_KEY = "FSPoserResetBaseRotationOnEdit";
|
||||||
constexpr std::string_view POSER_SAVEEXTERNALFORMAT_SAVE_KEY = "FSPoserSaveExternalFileAlso";
|
constexpr std::string_view POSER_SAVEEXTERNALFORMAT_SAVE_KEY = "FSPoserSaveExternalFileAlso";
|
||||||
constexpr std::string_view POSER_SAVECONFIRMREQUIRED_SAVE_KEY = "FSPoserOnSaveConfirmOverwrite";
|
constexpr std::string_view POSER_SAVECONFIRMREQUIRED_SAVE_KEY = "FSPoserOnSaveConfirmOverwrite";
|
||||||
|
constexpr char ICON_SAVE_OK[] = "icon_rotation_is_own_work";
|
||||||
|
constexpr char ICON_SAVE_FAILED[] = "icon_save_failed_button";
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -368,19 +372,8 @@ void FSFloaterPoser::onPoseFileSelect()
|
||||||
mLoadPosesBtn->setLabel(getString("LoadPoseLabel"));
|
mLoadPosesBtn->setLabel(getString("LoadPoseLabel"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSFloaterPoser::onClickPoseSave()
|
void FSFloaterPoser::doPoseSave(LLVOAvatar* avatar, const std::string& filename)
|
||||||
{
|
{
|
||||||
std::string filename = mPoseSaveNameEditor->getValue().asString();
|
|
||||||
if (filename.empty() && hasString("icon_save_failed_button"))
|
|
||||||
{
|
|
||||||
mSavePosesBtn->setImageOverlay(getString("icon_save_failed_button"), mSavePosesBtn->getImageOverlayHAlign());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (confirmFileOverwrite(filename))
|
|
||||||
return;
|
|
||||||
|
|
||||||
LLVOAvatar* avatar = getUiSelectedAvatar();
|
|
||||||
if (!avatar)
|
if (!avatar)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -393,43 +386,60 @@ void FSFloaterPoser::onClickPoseSave()
|
||||||
if (getSavingToBvh())
|
if (getSavingToBvh())
|
||||||
savePoseToBvh(avatar, filename);
|
savePoseToBvh(avatar, filename);
|
||||||
|
|
||||||
if (hasString("icon_rotation_is_own_work"))
|
if (hasString(ICON_SAVE_OK))
|
||||||
mSavePosesBtn->setImageOverlay(getString("icon_rotation_is_own_work"), mSavePosesBtn->getImageOverlayHAlign());
|
mSavePosesBtn->setImageOverlay(getString(ICON_SAVE_OK), mSavePosesBtn->getImageOverlayHAlign());
|
||||||
|
|
||||||
setSavePosesButtonText(!mPoserAnimator.allBaseRotationsAreZero(avatar));
|
setSavePosesButtonText(!mPoserAnimator.allBaseRotationsAreZero(avatar));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (hasString("icon_save_failed_button"))
|
if (hasString(ICON_SAVE_FAILED))
|
||||||
mSavePosesBtn->setImageOverlay(getString("icon_save_failed_button"), mSavePosesBtn->getImageOverlayHAlign());
|
mSavePosesBtn->setImageOverlay(getString(ICON_SAVE_FAILED), mSavePosesBtn->getImageOverlayHAlign());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FSFloaterPoser::confirmFileOverwrite(std::string fileName)
|
void FSFloaterPoser::onClickPoseSave()
|
||||||
{
|
{
|
||||||
if (fileName.empty())
|
std::string filename = mPoseSaveNameEditor->getValue().asString();
|
||||||
return false;
|
if (filename.empty() && hasString(ICON_SAVE_FAILED))
|
||||||
|
{
|
||||||
|
mSavePosesBtn->setImageOverlay(getString(ICON_SAVE_FAILED), mSavePosesBtn->getImageOverlayHAlign());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!gSavedSettings.getBOOL(POSER_SAVECONFIRMREQUIRED_SAVE_KEY))
|
LLVOAvatar* avatar = getUiSelectedAvatar();
|
||||||
return false;
|
if (!avatar)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!hasString("icon_save_query"))
|
// if prompts are disabled or file doesn't exist, do the save immediately:
|
||||||
return false;
|
const bool prompt = gSavedSettings.getBOOL(POSER_SAVECONFIRMREQUIRED_SAVE_KEY);
|
||||||
|
|
||||||
if (mSavePosesBtn->getImageOverlay().notNull() && mSavePosesBtn->getImageOverlay()->getName() == getString("icon_save_query"))
|
std::string fullPath = gDirUtilp->getExpandedFilename(
|
||||||
return false;
|
LL_PATH_USER_SETTINGS, POSE_SAVE_SUBDIRECTORY, filename + POSE_INTERNAL_FORMAT_FILE_EXT);
|
||||||
|
const bool exists = gDirUtilp->fileExists(fullPath);
|
||||||
|
|
||||||
std::string fullSavePath =
|
if (!prompt || !exists)
|
||||||
gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, POSE_SAVE_SUBDIRECTORY, fileName + POSE_INTERNAL_FORMAT_FILE_EXT);
|
{
|
||||||
|
// new file or no overwrite guard
|
||||||
|
doPoseSave(avatar, filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// show a modal dialog, passing the pose name along
|
||||||
|
LLSD args;
|
||||||
|
args["POSE_NAME"] = filename;
|
||||||
|
|
||||||
if (!gDirUtilp->fileExists(fullSavePath))
|
LLNotificationsUtil::add("ConfirmPoserOverwrite", args, LLSD(), // no payload
|
||||||
return false;
|
[this, avatar, filename](const LLSD& notification, const LLSD& response)
|
||||||
|
{
|
||||||
mSavePosesBtn->setImageOverlay(getString("icon_save_query"), mSavePosesBtn->getImageOverlayHAlign());
|
if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
|
||||||
if (hasString("OverWriteLabel"))
|
{
|
||||||
mSavePosesBtn->setLabel(getString("OverWriteLabel"));
|
// user clicked “Yes”
|
||||||
|
doPoseSave(avatar, filename);
|
||||||
return true;
|
}
|
||||||
|
// else do nothing (cancel)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSFloaterPoser::onMouseLeaveSavePoseBtn()
|
void FSFloaterPoser::onMouseLeaveSavePoseBtn()
|
||||||
|
|
@ -1645,13 +1655,14 @@ std::vector<FSPoserAnimator::FSPoserJoint*> FSFloaterPoser::getUiSelectedPoserJo
|
||||||
return joints;
|
return joints;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSFloaterPoser::updateManipWithFirstSelectedJoint(std::vector<FSPoserAnimator::FSPoserJoint*> joints)
|
void FSFloaterPoser::updateManipWithFirstSelectedJoint(std::vector<FSPoserAnimator::FSPoserJoint*> joints) const
|
||||||
{
|
{
|
||||||
if (!gAgentAvatarp || gAgentAvatarp.isNull())
|
auto avatarp = getUiSelectedAvatar();
|
||||||
|
if (!avatarp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (joints.size() >= 1)
|
if (joints.size() >= 1)
|
||||||
FSToolCompPose::getInstance()->setJoint(gAgentAvatarp->getJoint(JointKey::construct(joints[0]->jointName())));
|
FSToolCompPose::getInstance()->setJoint(avatarp->getJoint(joints[0]->jointName()));
|
||||||
else
|
else
|
||||||
FSToolCompPose::getInstance()->setJoint(nullptr);
|
FSToolCompPose::getInstance()->setJoint(nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,8 @@ public:
|
||||||
void redo() override { onRedoLastChange(); };
|
void redo() override { onRedoLastChange(); };
|
||||||
bool canRedo() const override { return true; }
|
bool canRedo() const override { return true; }
|
||||||
private:
|
private:
|
||||||
|
// Helper function to encapsualte save logic
|
||||||
|
void doPoseSave(LLVOAvatar* avatar, const std::string& filename);
|
||||||
bool postBuild() override;
|
bool postBuild() override;
|
||||||
void onOpen(const LLSD& key) override;
|
void onOpen(const LLSD& key) override;
|
||||||
void onClose(bool app_quitting) override;
|
void onClose(bool app_quitting) override;
|
||||||
|
|
@ -136,7 +138,7 @@ public:
|
||||||
/// Updates the visual with the first selected joint from the supplied collection, if any.
|
/// Updates the visual with the first selected joint from the supplied collection, if any.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="joints">The collection of selected joints.</param>
|
/// <param name="joints">The collection of selected joints.</param>
|
||||||
static void updateManipWithFirstSelectedJoint(std::vector<FSPoserAnimator::FSPoserJoint*> joints);
|
void updateManipWithFirstSelectedJoint(std::vector<FSPoserAnimator::FSPoserJoint*> joints) const;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a detectable avatar by its UUID.
|
/// Gets a detectable avatar by its UUID.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,912 @@
|
||||||
|
/**
|
||||||
|
* @file fsfloaterprimfeed.cpp
|
||||||
|
* @brief Implementation of primfeed floater
|
||||||
|
* @author beq@firestorm
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||||
|
* Phoenix Firestorm Viewer Source Code
|
||||||
|
* Copyright (C) 2025, Beq Janus
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||||
|
* http://www.firestormviewer.org
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
|
#include "fsfloaterprimfeed.h"
|
||||||
|
#include "fsprimfeedconnect.h"
|
||||||
|
#include "llagent.h"
|
||||||
|
#include "llagentui.h"
|
||||||
|
#include "llcheckboxctrl.h"
|
||||||
|
#include "llcombobox.h"
|
||||||
|
#include "llfloaterreg.h"
|
||||||
|
#include "lliconctrl.h"
|
||||||
|
#include "llimagefiltersmanager.h"
|
||||||
|
#include "llresmgr.h" // LLLocale
|
||||||
|
#include "llsdserialize.h"
|
||||||
|
#include "llloadingindicator.h"
|
||||||
|
#include "llslurl.h"
|
||||||
|
#include "lltrans.h"
|
||||||
|
#include "llfloatersnapshot.h"
|
||||||
|
#include "llsnapshotlivepreview.h"
|
||||||
|
#include "llfloaterbigpreview.h"
|
||||||
|
#include "llviewerregion.h"
|
||||||
|
#include "llviewercontrol.h"
|
||||||
|
#include "llviewermedia.h"
|
||||||
|
#include "lltabcontainer.h"
|
||||||
|
#include "llviewerparcelmgr.h"
|
||||||
|
#include "llviewerregion.h"
|
||||||
|
#include <boost/regex.hpp>
|
||||||
|
#include "llspinctrl.h"
|
||||||
|
|
||||||
|
#include "llviewernetwork.h"
|
||||||
|
#include "llnotificationsutil.h"
|
||||||
|
#include "fsprimfeedauth.h"
|
||||||
|
#include "llviewernetwork.h"
|
||||||
|
|
||||||
|
static LLPanelInjector<FSPrimfeedPhotoPanel> t_panel_photo("fsprimfeedphotopanel");
|
||||||
|
static LLPanelInjector<FSPrimfeedAccountPanel> t_panel_account("fsprimfeedaccountpanel");
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// FSPrimfeedPhotoPanel/////
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
FSPrimfeedPhotoPanel::FSPrimfeedPhotoPanel() :
|
||||||
|
mResolutionComboBox(nullptr),
|
||||||
|
mRefreshBtn(nullptr),
|
||||||
|
mWorkingLabel(nullptr),
|
||||||
|
mThumbnailPlaceholder(nullptr),
|
||||||
|
mDescriptionTextBox(nullptr),
|
||||||
|
mLocationCheckbox(nullptr),
|
||||||
|
mRatingComboBox(nullptr),
|
||||||
|
mPostButton(nullptr),
|
||||||
|
mBtnPreview(nullptr),
|
||||||
|
mBigPreviewFloater(nullptr)
|
||||||
|
{
|
||||||
|
mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", [this](LLUICtrl*, const LLSD&) { onSend(); });
|
||||||
|
mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", [this](LLUICtrl*, const LLSD&) { onClickNewSnapshot(); });
|
||||||
|
mCommitCallbackRegistrar.add("SocialSharing.BigPreview", [this](LLUICtrl*, const LLSD&) { onClickBigPreview(); });
|
||||||
|
mCommitCallbackRegistrar.add("Primfeed.Info",
|
||||||
|
[](LLUICtrl*, const LLSD& param)
|
||||||
|
{
|
||||||
|
const std::string url = param.asString();
|
||||||
|
LL_DEBUGS("primfeed") << "Info button clicked, opening " << url << LL_ENDL;
|
||||||
|
LLWeb::loadURLExternal(url);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
FSPrimfeedPhotoPanel::~FSPrimfeedPhotoPanel()
|
||||||
|
{
|
||||||
|
if (mPreviewHandle.get())
|
||||||
|
{
|
||||||
|
mPreviewHandle.get()->die();
|
||||||
|
}
|
||||||
|
|
||||||
|
FSPrimfeedAuth::sPrimfeedAuthPump->stopListening("FSPrimfeedAccountPanel");
|
||||||
|
|
||||||
|
gSavedSettings.setS32("FSLastSnapshotToPrimfeedResolution", getChild<LLComboBox>("resolution_combobox")->getCurrentIndex());
|
||||||
|
gSavedSettings.setS32("FSLastSnapshotToPrimfeedWidth", getChild<LLSpinCtrl>("custom_snapshot_width")->getValue().asInteger());
|
||||||
|
gSavedSettings.setS32("FSLastSnapshotToPrimfeedHeight", getChild<LLSpinCtrl>("custom_snapshot_height")->getValue().asInteger());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedPhotoPanel::postBuild()
|
||||||
|
{
|
||||||
|
setVisibleCallback([this](LLUICtrl*, bool visible) { onVisibilityChange(visible); });
|
||||||
|
|
||||||
|
mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox");
|
||||||
|
mResolutionComboBox->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||||
|
mFilterComboBox = getChild<LLUICtrl>("filters_combobox");
|
||||||
|
mFilterComboBox->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||||
|
mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn");
|
||||||
|
mBtnPreview = getChild<LLButton>("big_preview_btn");
|
||||||
|
mWorkingLabel = getChild<LLUICtrl>("working_lbl");
|
||||||
|
mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder");
|
||||||
|
mDescriptionTextBox = getChild<LLUICtrl>("photo_description");
|
||||||
|
mLocationCheckbox = getChild<LLUICtrl>("add_location_cb");
|
||||||
|
mCommercialCheckbox = getChild<LLUICtrl>("primfeed_commercial_content");
|
||||||
|
mPublicGalleryCheckbox = getChild<LLUICtrl>("primfeed_add_to_public_gallery");
|
||||||
|
mRatingComboBox = getChild<LLUICtrl>("rating_combobox");
|
||||||
|
mPostButton = getChild<LLUICtrl>("post_photo_btn");
|
||||||
|
mCancelButton = getChild<LLUICtrl>("cancel_photo_btn");
|
||||||
|
mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview"));
|
||||||
|
|
||||||
|
// Update custom resolution controls with lambdas
|
||||||
|
getChild<LLSpinCtrl>("custom_snapshot_width")->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||||
|
getChild<LLSpinCtrl>("custom_snapshot_height")->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||||
|
getChild<LLCheckBoxCtrl>("keep_aspect_ratio")->setCommitCallback([this](LLUICtrl*, const LLSD&) { updateResolution(true); });
|
||||||
|
|
||||||
|
getChild<LLComboBox>("resolution_combobox")->setCurrentByIndex(gSavedSettings.getS32("FSLastSnapshotToPrimfeedResolution"));
|
||||||
|
getChild<LLSpinCtrl>("custom_snapshot_width")->setValue(gSavedSettings.getS32("FSLastSnapshotToPrimfeedWidth"));
|
||||||
|
getChild<LLSpinCtrl>("custom_snapshot_height")->setValue(gSavedSettings.getS32("FSLastSnapshotToPrimfeedHeight"));
|
||||||
|
|
||||||
|
// Update filter list
|
||||||
|
std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList();
|
||||||
|
auto* filterbox = static_cast<LLComboBox*>(mFilterComboBox);
|
||||||
|
for (const std::string& filter : filter_list)
|
||||||
|
{
|
||||||
|
filterbox->add(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LLPanel::postBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void FSFloaterPrimfeed::update()
|
||||||
|
{
|
||||||
|
if (LLFloaterReg::instanceVisible("primfeed"))
|
||||||
|
{
|
||||||
|
LLFloaterSnapshotBase::ImplBase::updatePreviewList(true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual
|
||||||
|
S32 FSPrimfeedPhotoPanel::notify(const LLSD& info)
|
||||||
|
{
|
||||||
|
if (info.has("snapshot-updating"))
|
||||||
|
{
|
||||||
|
// Disable the Post button and whatever else while the snapshot is not updated
|
||||||
|
// updateControls();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.has("snapshot-updated"))
|
||||||
|
{
|
||||||
|
// Enable the send/post/save buttons.
|
||||||
|
updateControls();
|
||||||
|
|
||||||
|
// The refresh button is initially hidden. We show it after the first update,
|
||||||
|
// i.e. after snapshot is taken
|
||||||
|
|
||||||
|
if (LLUICtrl* refresh_button = getRefreshBtn(); !refresh_button->getVisible())
|
||||||
|
{
|
||||||
|
refresh_button->setVisible(true);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::draw()
|
||||||
|
{
|
||||||
|
auto previewp = static_cast<const LLSnapshotLivePreview*>(mPreviewHandle.get());
|
||||||
|
|
||||||
|
// Enable interaction only if no transaction with the service is on-going (prevent duplicated posts)
|
||||||
|
auto can_post = !(FSPrimfeedConnect::instance().isTransactionOngoing()) && FSPrimfeedAuth::isAuthorized();
|
||||||
|
|
||||||
|
mCancelButton->setEnabled(can_post);
|
||||||
|
mDescriptionTextBox->setEnabled(can_post);
|
||||||
|
mRatingComboBox->setEnabled(can_post);
|
||||||
|
mResolutionComboBox->setEnabled(can_post);
|
||||||
|
mFilterComboBox->setEnabled(can_post);
|
||||||
|
mRefreshBtn->setEnabled(can_post);
|
||||||
|
mBtnPreview->setEnabled(can_post);
|
||||||
|
mLocationCheckbox->setEnabled(can_post);
|
||||||
|
mPublicGalleryCheckbox->setEnabled(can_post);
|
||||||
|
mCommercialCheckbox->setEnabled(can_post);
|
||||||
|
|
||||||
|
// Reassign the preview floater if we have the focus and the preview exists
|
||||||
|
if (hasFocus() && isPreviewVisible())
|
||||||
|
{
|
||||||
|
attachPreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the button state as appropriate
|
||||||
|
bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>()));
|
||||||
|
mBtnPreview->setToggleState(preview_active);
|
||||||
|
|
||||||
|
// Display the preview if one is available
|
||||||
|
if (previewp && previewp->getThumbnailImage())
|
||||||
|
{
|
||||||
|
const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect();
|
||||||
|
const S32 thumbnail_w = previewp->getThumbnailWidth();
|
||||||
|
const S32 thumbnail_h = previewp->getThumbnailHeight();
|
||||||
|
|
||||||
|
// calc preview offset within the preview rect
|
||||||
|
const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2;
|
||||||
|
const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2;
|
||||||
|
S32 offset_x = thumbnail_rect.mLeft + local_offset_x;
|
||||||
|
S32 offset_y = thumbnail_rect.mBottom + local_offset_y;
|
||||||
|
|
||||||
|
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||||
|
// Apply floater transparency to the texture unless the floater is focused.
|
||||||
|
F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
|
||||||
|
LLColor4 color = LLColor4::white;
|
||||||
|
gl_draw_scaled_image(offset_x, offset_y, thumbnail_w, thumbnail_h, previewp->getThumbnailImage(), color % alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the visibility of the working (computing preview) label
|
||||||
|
mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate()));
|
||||||
|
|
||||||
|
// Enable Post if we have a preview to send and no on going connection being processed
|
||||||
|
mPostButton->setEnabled(can_post && (previewp && previewp->getSnapshotUpToDate()));
|
||||||
|
|
||||||
|
// Draw the rest of the panel on top of it
|
||||||
|
LLPanel::draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSnapshotLivePreview* FSPrimfeedPhotoPanel::getPreviewView()
|
||||||
|
{
|
||||||
|
auto previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
|
||||||
|
return previewp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::onVisibilityChange(bool visible)
|
||||||
|
{
|
||||||
|
if (visible)
|
||||||
|
{
|
||||||
|
if (mPreviewHandle.get())
|
||||||
|
{
|
||||||
|
LLSnapshotLivePreview* preview = getPreviewView();
|
||||||
|
if (preview)
|
||||||
|
{
|
||||||
|
LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL;
|
||||||
|
preview->updateSnapshot(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LLRect full_screen_rect = getRootView()->getRect();
|
||||||
|
LLSnapshotLivePreview::Params p;
|
||||||
|
p.rect(full_screen_rect);
|
||||||
|
auto previewp = new LLSnapshotLivePreview(p);
|
||||||
|
mPreviewHandle = previewp->getHandle();
|
||||||
|
|
||||||
|
previewp->setContainer(this);
|
||||||
|
previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB);
|
||||||
|
previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_PNG);
|
||||||
|
previewp->setThumbnailSubsampled(true); // We want the preview to reflect the *saved* image
|
||||||
|
previewp->setAllowRenderUI(false); // We do not want the rendered UI in our snapshots
|
||||||
|
previewp->setAllowFullScreenPreview(false); // No full screen preview in SL Share mode
|
||||||
|
previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect());
|
||||||
|
|
||||||
|
updateControls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::onClickNewSnapshot()
|
||||||
|
{
|
||||||
|
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||||
|
if (previewp)
|
||||||
|
{
|
||||||
|
previewp->updateSnapshot(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::onClickBigPreview()
|
||||||
|
{
|
||||||
|
// Toggle the preview
|
||||||
|
if (isPreviewVisible())
|
||||||
|
{
|
||||||
|
LLFloaterReg::hideInstance("big_preview");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attachPreview();
|
||||||
|
LLFloaterReg::showInstance("big_preview");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedPhotoPanel::isPreviewVisible() const
|
||||||
|
{
|
||||||
|
return (mBigPreviewFloater && mBigPreviewFloater->getVisible());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::attachPreview()
|
||||||
|
{
|
||||||
|
if (mBigPreviewFloater)
|
||||||
|
{
|
||||||
|
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||||
|
mBigPreviewFloater->setPreview(previewp);
|
||||||
|
mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::onSend()
|
||||||
|
{
|
||||||
|
sendPhoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedPhotoPanel::onPrimfeedConnectStateChange(const LLSD& /*data*/)
|
||||||
|
{
|
||||||
|
if (FSPrimfeedAuth::isAuthorized())
|
||||||
|
{
|
||||||
|
sendPhoto();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::sendPhoto()
|
||||||
|
{
|
||||||
|
auto ratingToString = [&](int rating)
|
||||||
|
{
|
||||||
|
static const std::array<std::string, 4> RATING_NAMES = {
|
||||||
|
"general", // 1
|
||||||
|
"moderate", // 2
|
||||||
|
"adult", // 3
|
||||||
|
"adult_plus" // 4
|
||||||
|
};
|
||||||
|
|
||||||
|
// clamp into [1,4]
|
||||||
|
int idx = llclamp(rating, 1, 4) - 1;
|
||||||
|
return RATING_NAMES[idx];
|
||||||
|
};
|
||||||
|
// Get the description (primfeed has no title/tags etc at this point)
|
||||||
|
std::string description = mDescriptionTextBox->getValue().asString();
|
||||||
|
|
||||||
|
// Get the content rating
|
||||||
|
int content_rating = mRatingComboBox->getValue().asInteger();
|
||||||
|
bool post_to_public_gallery = mPublicGalleryCheckbox->getValue().asBoolean();
|
||||||
|
bool commercial_content = mCommercialCheckbox->getValue().asBoolean();
|
||||||
|
|
||||||
|
// Get the image
|
||||||
|
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||||
|
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POSTING);
|
||||||
|
LLSD params;
|
||||||
|
params["rating"] = ratingToString(content_rating);
|
||||||
|
params["content"] = description;
|
||||||
|
params["is_commercial"] = commercial_content;
|
||||||
|
params["post_to_public_gallery"] = post_to_public_gallery;
|
||||||
|
// Add the location if required
|
||||||
|
|
||||||
|
if (bool add_location = mLocationCheckbox->getValue().asBoolean(); add_location)
|
||||||
|
{
|
||||||
|
// Get the SLURL for the location
|
||||||
|
LLSLURL slurl;
|
||||||
|
LLAgentUI::buildSLURL(slurl);
|
||||||
|
std::string slurl_string = slurl.getSLURLString();
|
||||||
|
|
||||||
|
params["location"] = slurl_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSPrimfeedConnect::instance().uploadPhoto(params, previewp->getFormattedImage().get(),
|
||||||
|
[this](bool success, const std::string& url)
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POSTED);
|
||||||
|
static LLCachedControl<bool> open_url_on_post(gSavedPerAccountSettings,
|
||||||
|
"FSPrimfeedOpenURLOnPost", true);
|
||||||
|
if (open_url_on_post)
|
||||||
|
{
|
||||||
|
LLWeb::loadURLExternal(url);
|
||||||
|
}
|
||||||
|
LLSD args;
|
||||||
|
args["PF_POSTURL"] = url;
|
||||||
|
LLNotificationsUtil::add("FSPrimfeedUploadComplete", args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mWorkingLabel->setValue("Error posting to Primfeed");
|
||||||
|
mPostButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
updateControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::clearAndClose()
|
||||||
|
{
|
||||||
|
mDescriptionTextBox->setValue("");
|
||||||
|
|
||||||
|
if (LLFloater* floater = getParentByType<LLFloater>())
|
||||||
|
{
|
||||||
|
floater->closeFloater();
|
||||||
|
if (mBigPreviewFloater)
|
||||||
|
{
|
||||||
|
mBigPreviewFloater->closeOnFloaterOwnerClosing(floater);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::updateControls()
|
||||||
|
{
|
||||||
|
// LLSnapshotLivePreview* previewp = getPreviewView();
|
||||||
|
updateResolution(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::updateResolution(bool do_update)
|
||||||
|
{
|
||||||
|
auto combobox = static_cast<LLComboBox*>(mResolutionComboBox);
|
||||||
|
auto filterbox = static_cast<LLComboBox*>(mFilterComboBox);
|
||||||
|
|
||||||
|
std::string sdstring = combobox->getSelectedValue();
|
||||||
|
LLSD sdres;
|
||||||
|
std::stringstream sstream(sdstring);
|
||||||
|
LLSDSerialize::fromNotation(sdres, sstream, sdstring.size());
|
||||||
|
|
||||||
|
S32 width = sdres[0];
|
||||||
|
S32 height = sdres[1];
|
||||||
|
|
||||||
|
// Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale
|
||||||
|
std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : "");
|
||||||
|
|
||||||
|
if (auto previewp = static_cast<LLSnapshotLivePreview*>(mPreviewHandle.get()); previewp && combobox->getCurrentIndex() >= 0)
|
||||||
|
{
|
||||||
|
checkAspectRatio(width);
|
||||||
|
|
||||||
|
S32 original_width = 0;
|
||||||
|
S32 original_height = 0;
|
||||||
|
previewp->getSize(original_width, original_height);
|
||||||
|
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
{
|
||||||
|
// take resolution from current window size
|
||||||
|
LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x"
|
||||||
|
<< gViewerWindow->getWindowHeightRaw() << LL_ENDL;
|
||||||
|
previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
|
||||||
|
}
|
||||||
|
else if (width == -1 || height == -1)
|
||||||
|
{
|
||||||
|
// take resolution from custom size
|
||||||
|
LLSpinCtrl* width_spinner = getChild<LLSpinCtrl>("custom_snapshot_width");
|
||||||
|
LLSpinCtrl* height_spinner = getChild<LLSpinCtrl>("custom_snapshot_height");
|
||||||
|
S32 custom_width = width_spinner->getValue().asInteger();
|
||||||
|
S32 custom_height = height_spinner->getValue().asInteger();
|
||||||
|
if (checkImageSize(previewp, custom_width, custom_height, true, previewp->getMaxImageSize()))
|
||||||
|
{
|
||||||
|
width_spinner->set((F32)custom_width);
|
||||||
|
height_spinner->set((F32)custom_height);
|
||||||
|
}
|
||||||
|
LL_DEBUGS() << "Setting preview res from custom: " << custom_width << "x" << custom_height << LL_ENDL;
|
||||||
|
previewp->setSize(custom_width, custom_height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// use the resolution from the selected pre-canned drop-down choice
|
||||||
|
LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL;
|
||||||
|
previewp->setSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
previewp->getSize(width, height);
|
||||||
|
if ((original_width != width) || (original_height != height))
|
||||||
|
{
|
||||||
|
previewp->setSize(width, height);
|
||||||
|
if (do_update)
|
||||||
|
{
|
||||||
|
previewp->updateSnapshot(true, true);
|
||||||
|
updateControls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Get the old filter, compare to the current one "filter_name" and set if changed
|
||||||
|
std::string original_filter = previewp->getFilter();
|
||||||
|
if (original_filter != filter_name)
|
||||||
|
{
|
||||||
|
previewp->setFilter(filter_name);
|
||||||
|
if (do_update)
|
||||||
|
{
|
||||||
|
previewp->updateSnapshot(false, true);
|
||||||
|
updateControls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool custom_resolution = static_cast<LLComboBox*>(mResolutionComboBox)->getSelectedValue().asString() == "[i-1,i-1]";
|
||||||
|
getChild<LLSpinCtrl>("custom_snapshot_width")->setEnabled(custom_resolution);
|
||||||
|
getChild<LLSpinCtrl>("custom_snapshot_height")->setEnabled(custom_resolution);
|
||||||
|
getChild<LLCheckBoxCtrl>("keep_aspect_ratio")->setEnabled(custom_resolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::checkAspectRatio(S32 index)
|
||||||
|
{
|
||||||
|
LLSnapshotLivePreview* previewp = getPreviewView();
|
||||||
|
|
||||||
|
bool keep_aspect = false;
|
||||||
|
|
||||||
|
if (0 == index) // current window size
|
||||||
|
{
|
||||||
|
keep_aspect = true;
|
||||||
|
}
|
||||||
|
else if (-1 == index)
|
||||||
|
{
|
||||||
|
keep_aspect = getChild<LLCheckBoxCtrl>("keep_aspect_ratio")->get();
|
||||||
|
}
|
||||||
|
else // predefined resolution
|
||||||
|
{
|
||||||
|
keep_aspect = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previewp)
|
||||||
|
{
|
||||||
|
previewp->mKeepAspectRatio = keep_aspect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LLUICtrl* FSPrimfeedPhotoPanel::getRefreshBtn()
|
||||||
|
{
|
||||||
|
return mRefreshBtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::onOpen(const LLSD& key)
|
||||||
|
{
|
||||||
|
if (!FSPrimfeedAuth::isAuthorized())
|
||||||
|
{
|
||||||
|
// Reauthorise if necessary.
|
||||||
|
FSPrimfeedAuth::initiateAuthRequest();
|
||||||
|
LLSD dummy;
|
||||||
|
onPrimfeedConnectStateChange(dummy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::uploadCallback(bool success, const LLSD& response)
|
||||||
|
{
|
||||||
|
LLSD args;
|
||||||
|
if (success && response["stat"].asString() == "ok")
|
||||||
|
{
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POSTED);
|
||||||
|
args["PF_POSTURL"] = response["postUrl"];
|
||||||
|
LLNotificationsUtil::add("FSPrimfeedUploadComplete", args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_POST_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedPhotoPanel::primfeedAuthResponse(bool success, const LLSD& response)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
if (response.has("status") && response["status"].asString() == "reset")
|
||||||
|
{
|
||||||
|
LL_INFOS("Primfeed") << "Primfeed authorization has been reset." << LL_ENDL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Complain about failed auth here.
|
||||||
|
LL_WARNS("Primfeed") << "Primfeed authentication failed." << LL_ENDL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onPrimfeedConnectStateChange(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedPhotoPanel::checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, bool isWidthChanged, S32 max_value)
|
||||||
|
{
|
||||||
|
S32 w = width;
|
||||||
|
S32 h = height;
|
||||||
|
|
||||||
|
if (previewp && previewp->mKeepAspectRatio)
|
||||||
|
{
|
||||||
|
if (gViewerWindow->getWindowWidthRaw() < 1 || gViewerWindow->getWindowHeightRaw() < 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// aspect ratio of the current window
|
||||||
|
F32 aspect_ratio = static_cast<F32>(gViewerWindow->getWindowWidthRaw()) / static_cast<F32>(gViewerWindow->getWindowHeightRaw());
|
||||||
|
|
||||||
|
// change another value proportionally
|
||||||
|
if (isWidthChanged)
|
||||||
|
{
|
||||||
|
height = ll_round(static_cast<F32>(width) / aspect_ratio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width = ll_round(static_cast<F32>(height) * aspect_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
// bound w/h by the max_value
|
||||||
|
if (width > max_value || height > max_value)
|
||||||
|
{
|
||||||
|
if (width > height)
|
||||||
|
{
|
||||||
|
width = max_value;
|
||||||
|
height = ll_round(static_cast<F32>(width) / aspect_ratio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
height = max_value;
|
||||||
|
width = ll_round(static_cast<F32>(height) * aspect_ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (w != width || h != height);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// FSPrimfeedAccountPanel///
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
FSPrimfeedAccountPanel::FSPrimfeedAccountPanel() :
|
||||||
|
mAccountConnectedAsLabel(nullptr),
|
||||||
|
mAccountNameLink(nullptr),
|
||||||
|
mAccountPlan(nullptr),
|
||||||
|
mPanelButtons(nullptr),
|
||||||
|
mConnectButton(nullptr),
|
||||||
|
mDisconnectButton(nullptr)
|
||||||
|
{
|
||||||
|
mCommitCallbackRegistrar.add("SocialSharing.Connect", [this](LLUICtrl*, const LLSD&) { onConnect(); });
|
||||||
|
mCommitCallbackRegistrar.add("SocialSharing.Disconnect", [this](LLUICtrl*, const LLSD&) { onDisconnect(); });
|
||||||
|
|
||||||
|
FSPrimfeedAuth::sPrimfeedAuthPump->listen("FSPrimfeedAccountPanel",
|
||||||
|
[this](const LLSD& data)
|
||||||
|
{
|
||||||
|
bool success = data["success"].asBoolean();
|
||||||
|
primfeedAuthResponse(success, data);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
setVisibleCallback([this](LLUICtrl*, bool visible) { onVisibilityChange(visible); });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedAccountPanel::postBuild()
|
||||||
|
{
|
||||||
|
mAccountConnectedAsLabel = getChild<LLTextBox>("connected_as_label");
|
||||||
|
mAccountNameLink = getChild<LLTextBox>("primfeed_account_name");
|
||||||
|
mAccountPlan = getChild<LLTextBox>("primfeed_account_plan");
|
||||||
|
mPanelButtons = getChild<LLUICtrl>("panel_buttons");
|
||||||
|
mConnectButton = getChild<LLUICtrl>("connect_btn");
|
||||||
|
mDisconnectButton = getChild<LLUICtrl>("disconnect_btn");
|
||||||
|
|
||||||
|
LLSD dummy;
|
||||||
|
onPrimfeedConnectStateChange(dummy);
|
||||||
|
return LLPanel::postBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::draw()
|
||||||
|
{
|
||||||
|
FSPrimfeedConnect::EConnectionState connection_state = FSPrimfeedConnect::instance().getConnectionState();
|
||||||
|
static FSPrimfeedConnect::EConnectionState last_state = FSPrimfeedConnect::PRIMFEED_DISCONNECTED;
|
||||||
|
|
||||||
|
// Update the connection state if it has changed
|
||||||
|
if (connection_state != last_state)
|
||||||
|
{
|
||||||
|
onPrimfeedConnectStateChange(LLSD());
|
||||||
|
last_state = connection_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLPanel::draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::primfeedAuthResponse(bool success, const LLSD& response)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
LL_WARNS("Primfeed") << "Primfeed authentication failed." << LL_ENDL;
|
||||||
|
LLWeb::loadURLExternal("https://www.primfeed.com/login");
|
||||||
|
}
|
||||||
|
onPrimfeedConnectStateChange(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::onVisibilityChange(bool visible)
|
||||||
|
{
|
||||||
|
if (visible)
|
||||||
|
{
|
||||||
|
// Connected
|
||||||
|
if (FSPrimfeedAuth::isAuthorized())
|
||||||
|
{
|
||||||
|
showConnectedLayout();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showDisconnectedLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedAccountPanel::onPrimfeedConnectStateChange(const LLSD&)
|
||||||
|
{
|
||||||
|
if (FSPrimfeedAuth::isAuthorized() || FSPrimfeedConnect::instance().getConnectionState() == FSPrimfeedConnect::PRIMFEED_CONNECTING)
|
||||||
|
{
|
||||||
|
showConnectedLayout();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showDisconnectedLayout();
|
||||||
|
}
|
||||||
|
onPrimfeedConnectInfoChange();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedAccountPanel::onPrimfeedConnectInfoChange()
|
||||||
|
{
|
||||||
|
std::string clickable_name{ "" };
|
||||||
|
|
||||||
|
static LLCachedControl<std::string> primfeed_username(gSavedPerAccountSettings, "FSPrimfeedUsername");
|
||||||
|
static LLCachedControl<std::string> primfeed_profile_link(gSavedPerAccountSettings, "FSPrimfeedProfileLink");
|
||||||
|
static LLCachedControl<std::string> primfeed_plan(gSavedPerAccountSettings, "FSPrimfeedPlan");
|
||||||
|
|
||||||
|
// Strings of format [http://www.somewebsite.com Click Me] become clickable text
|
||||||
|
if (!primfeed_username().empty())
|
||||||
|
{
|
||||||
|
clickable_name = std::string("[") + std::string(primfeed_profile_link) + " " + std::string(primfeed_username) + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
mAccountNameLink->setText(clickable_name);
|
||||||
|
mAccountPlan->setText(primfeed_plan());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::showConnectButton()
|
||||||
|
{
|
||||||
|
if (!mConnectButton->getVisible())
|
||||||
|
{
|
||||||
|
mConnectButton->setVisible(true);
|
||||||
|
mDisconnectButton->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::hideConnectButton()
|
||||||
|
{
|
||||||
|
if (mConnectButton->getVisible())
|
||||||
|
{
|
||||||
|
mConnectButton->setVisible(false);
|
||||||
|
mDisconnectButton->setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::showDisconnectedLayout()
|
||||||
|
{
|
||||||
|
mAccountConnectedAsLabel->setText(getString("primfeed_disconnected"));
|
||||||
|
mAccountNameLink->setText(std::string(""));
|
||||||
|
mAccountPlan->setText(getString("primfeed_plan_unknown"));
|
||||||
|
showConnectButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::showConnectedLayout()
|
||||||
|
{
|
||||||
|
mAccountConnectedAsLabel->setText(getString("primfeed_connected"));
|
||||||
|
hideConnectButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::onConnect()
|
||||||
|
{
|
||||||
|
FSPrimfeedAuth::initiateAuthRequest();
|
||||||
|
LLSD dummy;
|
||||||
|
onPrimfeedConnectStateChange(dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAccountPanel::onDisconnect()
|
||||||
|
{
|
||||||
|
FSPrimfeedAuth::resetAuthStatus();
|
||||||
|
LLSD dummy;
|
||||||
|
onPrimfeedConnectStateChange(dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// FSFloaterPrimfeed/////
|
||||||
|
////////////////////////
|
||||||
|
|
||||||
|
FSFloaterPrimfeed::FSFloaterPrimfeed(const LLSD& key) :
|
||||||
|
LLFloater(key),
|
||||||
|
mPrimfeedPhotoPanel(nullptr),
|
||||||
|
mStatusErrorText(nullptr),
|
||||||
|
mStatusLoadingText(nullptr),
|
||||||
|
mStatusLoadingIndicator(nullptr),
|
||||||
|
mPrimfeedAccountPanel(nullptr)
|
||||||
|
{
|
||||||
|
mCommitCallbackRegistrar.add("SocialSharing.Cancel", [this](LLUICtrl*, const LLSD&) { onCancel(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSFloaterPrimfeed::onClose(bool app_quitting)
|
||||||
|
{
|
||||||
|
if (auto big_preview_floater = LLFloaterReg::getTypedInstance<LLFloaterBigPreview>("big_preview"))
|
||||||
|
{
|
||||||
|
big_preview_floater->closeOnFloaterOwnerClosing(this);
|
||||||
|
}
|
||||||
|
LLFloater::onClose(app_quitting);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSFloaterPrimfeed::onCancel()
|
||||||
|
{
|
||||||
|
if (auto big_preview_floater = LLFloaterReg::getTypedInstance<LLFloaterBigPreview>("big_preview"))
|
||||||
|
{
|
||||||
|
big_preview_floater->closeOnFloaterOwnerClosing(this);
|
||||||
|
}
|
||||||
|
closeFloater();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSFloaterPrimfeed::postBuild()
|
||||||
|
{
|
||||||
|
// Keep tab of the Photo Panel
|
||||||
|
mPrimfeedPhotoPanel = static_cast<FSPrimfeedPhotoPanel*>(getChild<LLUICtrl>("panel_primfeed_photo"));
|
||||||
|
mPrimfeedAccountPanel = static_cast<FSPrimfeedAccountPanel*>(getChild<LLUICtrl>("panel_primfeed_account"));
|
||||||
|
// Connection status widgets
|
||||||
|
mStatusErrorText = getChild<LLTextBox>("connection_error_text");
|
||||||
|
mStatusLoadingText = getChild<LLTextBox>("connection_loading_text");
|
||||||
|
mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator");
|
||||||
|
|
||||||
|
return LLFloater::postBuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSFloaterPrimfeed::showPhotoPanel()
|
||||||
|
{
|
||||||
|
auto parent = dynamic_cast<LLTabContainer*>(mPrimfeedPhotoPanel->getParent());
|
||||||
|
if (!parent)
|
||||||
|
{
|
||||||
|
LL_WARNS() << "Cannot find panel container" << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent->selectTabPanel(mPrimfeedPhotoPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSFloaterPrimfeed::draw()
|
||||||
|
{
|
||||||
|
if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator)
|
||||||
|
{
|
||||||
|
mStatusErrorText->setVisible(false);
|
||||||
|
mStatusLoadingText->setVisible(false);
|
||||||
|
mStatusLoadingIndicator->setVisible(false);
|
||||||
|
|
||||||
|
FSPrimfeedConnect::EConnectionState connection_state = FSPrimfeedConnect::instance().getConnectionState();
|
||||||
|
std::string status_text;
|
||||||
|
|
||||||
|
if (FSPrimfeedAuth::isAuthorized())
|
||||||
|
{
|
||||||
|
switch (connection_state)
|
||||||
|
{
|
||||||
|
case FSPrimfeedConnect::PRIMFEED_POSTING:
|
||||||
|
{
|
||||||
|
// Posting indicator
|
||||||
|
mStatusLoadingText->setVisible(true);
|
||||||
|
status_text = LLTrans::getString("SocialPrimfeedPosting");
|
||||||
|
mStatusLoadingText->setValue(status_text);
|
||||||
|
mStatusLoadingIndicator->setVisible(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FSPrimfeedConnect::PRIMFEED_POST_FAILED:
|
||||||
|
{
|
||||||
|
// Error posting to the service
|
||||||
|
mStatusErrorText->setVisible(true);
|
||||||
|
status_text = LLTrans::getString("SocialPrimfeedErrorPosting");
|
||||||
|
mStatusErrorText->setValue(status_text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
// LL_WARNS("Prmfeed") << "unexpected state" << connection_state << LL_ENDL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (FSPrimfeedAuth::isPendingAuth())
|
||||||
|
{
|
||||||
|
// Show the status text when authorisation is pending
|
||||||
|
mStatusLoadingText->setVisible(true);
|
||||||
|
status_text = LLTrans::getString("SocialPrimfeedConnecting");
|
||||||
|
mStatusLoadingText->setValue(status_text);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Show the status text when not authorised
|
||||||
|
mStatusErrorText->setVisible(true);
|
||||||
|
status_text = LLTrans::getString("SocialPrimfeedNotAuthorized");
|
||||||
|
mStatusErrorText->setValue(status_text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LLFloater::draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSFloaterPrimfeed::onOpen(const LLSD& key)
|
||||||
|
{
|
||||||
|
mPrimfeedPhotoPanel->onOpen(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLSnapshotLivePreview* FSFloaterPrimfeed::getPreviewView()
|
||||||
|
{
|
||||||
|
if (mPrimfeedPhotoPanel)
|
||||||
|
{
|
||||||
|
return mPrimfeedPhotoPanel->getPreviewView();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
/**
|
||||||
|
* @file fsfloaterprimfeed.cpp
|
||||||
|
* @brief Declaration of primfeed floater
|
||||||
|
* @author beq@firestorm
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||||
|
* Phoenix Firestorm Viewer Source Code
|
||||||
|
* Copyright (C) 2025, Beq Janus
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||||
|
* http://www.firestormviewer.org
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
#ifndef FS_FLOATERPRIMFEED_H
|
||||||
|
#define FS_FLOATERPRIMFEED_H
|
||||||
|
|
||||||
|
#include "llfloater.h"
|
||||||
|
#include "lltextbox.h"
|
||||||
|
#include "llviewertexture.h"
|
||||||
|
|
||||||
|
class LLIconCtrl;
|
||||||
|
class LLCheckBoxCtrl;
|
||||||
|
class LLSnapshotLivePreview;
|
||||||
|
class LLFloaterBigPreview;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (TODO) Beq: Refactor this with Flickr
|
||||||
|
* Primfeed floater is copied heavily from the LLFlaoterFlickr class and deliberately implemetns much of the underlying plumbinng into the connector class.
|
||||||
|
* Once this is bedded in and any initial issues are addressed, it would be sensible to refactor both the flickr and primfeed classes to share a common base.
|
||||||
|
* In particular a ref counted test for the livepreview would eliminate the need for the static update method in the app mainloop.
|
||||||
|
*/
|
||||||
|
class FSPrimfeedPhotoPanel : public LLPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FSPrimfeedPhotoPanel();
|
||||||
|
~FSPrimfeedPhotoPanel();
|
||||||
|
|
||||||
|
bool postBuild() override;
|
||||||
|
S32 notify(const LLSD& info);
|
||||||
|
void draw() override;
|
||||||
|
|
||||||
|
LLSnapshotLivePreview* getPreviewView();
|
||||||
|
void onVisibilityChange(bool new_visibility);
|
||||||
|
void onClickNewSnapshot();
|
||||||
|
void onClickBigPreview();
|
||||||
|
void onSend();
|
||||||
|
bool onPrimfeedConnectStateChange(const LLSD& data);
|
||||||
|
|
||||||
|
void sendPhoto();
|
||||||
|
void clearAndClose();
|
||||||
|
|
||||||
|
void updateControls();
|
||||||
|
void updateResolution(bool do_update);
|
||||||
|
void checkAspectRatio(S32 index);
|
||||||
|
LLUICtrl* getRefreshBtn();
|
||||||
|
|
||||||
|
void onOpen(const LLSD& key) override;
|
||||||
|
void primfeedAuthResponse(bool success, const LLSD& response);
|
||||||
|
void uploadCallback(bool success, const LLSD& response);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool isPreviewVisible() const;
|
||||||
|
void attachPreview();
|
||||||
|
|
||||||
|
bool checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, bool isWidthChanged, S32 max_value);
|
||||||
|
|
||||||
|
LLHandle<LLView> mPreviewHandle;
|
||||||
|
|
||||||
|
LLUICtrl * mResolutionComboBox;
|
||||||
|
LLUICtrl * mFilterComboBox;
|
||||||
|
LLUICtrl * mRefreshBtn;
|
||||||
|
LLUICtrl * mWorkingLabel;
|
||||||
|
LLUICtrl * mThumbnailPlaceholder;
|
||||||
|
LLUICtrl * mDescriptionTextBox;
|
||||||
|
LLUICtrl * mLocationCheckbox;
|
||||||
|
|
||||||
|
LLUICtrl * mCommercialCheckbox;
|
||||||
|
LLUICtrl * mPublicGalleryCheckbox;
|
||||||
|
LLUICtrl * mRatingComboBox;
|
||||||
|
LLUICtrl * mPostButton;
|
||||||
|
LLUICtrl * mCancelButton;
|
||||||
|
LLButton * mBtnPreview;
|
||||||
|
|
||||||
|
LLFloaterBigPreview * mBigPreviewFloater;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FSPrimfeedAccountPanel : public LLPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FSPrimfeedAccountPanel();
|
||||||
|
bool postBuild() override;
|
||||||
|
void draw() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void onVisibilityChange(bool new_visibility);
|
||||||
|
void primfeedAuthResponse(bool success, const LLSD& response);
|
||||||
|
bool onPrimfeedConnectStateChange(const LLSD& data);
|
||||||
|
bool onPrimfeedConnectInfoChange();
|
||||||
|
void onConnect();
|
||||||
|
void onDisconnect();
|
||||||
|
|
||||||
|
void showConnectButton();
|
||||||
|
void hideConnectButton();
|
||||||
|
void showDisconnectedLayout();
|
||||||
|
void showConnectedLayout();
|
||||||
|
|
||||||
|
LLTextBox* mAccountConnectedAsLabel;
|
||||||
|
LLTextBox* mAccountNameLink;
|
||||||
|
LLTextBox* mAccountPlan;
|
||||||
|
LLUICtrl* mPanelButtons;
|
||||||
|
LLUICtrl* mConnectButton;
|
||||||
|
LLUICtrl* mDisconnectButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FSFloaterPrimfeed : public LLFloater
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit FSFloaterPrimfeed(const LLSD& key);
|
||||||
|
static void update();
|
||||||
|
bool postBuild() override;
|
||||||
|
void draw() override;
|
||||||
|
void onClose(bool app_quitting) override;
|
||||||
|
void onCancel();
|
||||||
|
|
||||||
|
void showPhotoPanel();
|
||||||
|
|
||||||
|
void onOpen(const LLSD& key) override;
|
||||||
|
LLSnapshotLivePreview* getPreviewView();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FSPrimfeedPhotoPanel* mPrimfeedPhotoPanel;
|
||||||
|
FSPrimfeedAccountPanel* mPrimfeedAccountPanel;
|
||||||
|
LLTextBox* mStatusErrorText;
|
||||||
|
LLTextBox* mStatusLoadingText;
|
||||||
|
LLUICtrl* mStatusLoadingIndicator;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LL_FSFLOATERPRIMFEED_H
|
||||||
|
|
||||||
|
|
@ -923,6 +923,12 @@ void FSPanelLogin::loadLoginPage()
|
||||||
// login page (web) content version
|
// login page (web) content version
|
||||||
params["login_content_version"] = gSavedSettings.getString("LoginContentVersion");
|
params["login_content_version"] = gSavedSettings.getString("LoginContentVersion");
|
||||||
|
|
||||||
|
// No version popup
|
||||||
|
if (gSavedSettings.getBOOL("FSNoVersionPopup"))
|
||||||
|
{
|
||||||
|
params["noversionpopup"] = "true";
|
||||||
|
}
|
||||||
|
|
||||||
// Make an LLURI with this augmented info
|
// Make an LLURI with this augmented info
|
||||||
std::string url = login_page.scheme().empty()? login_page.authority() : login_page.scheme() + "://" + login_page.authority();
|
std::string url = login_page.scheme().empty()? login_page.authority() : login_page.scheme() + "://" + login_page.authority();
|
||||||
LLURI login_uri(LLURI::buildHTTP(url,
|
LLURI login_uri(LLURI::buildHTTP(url,
|
||||||
|
|
|
||||||
|
|
@ -190,18 +190,18 @@ public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An ordered list of poser joints, clustered by body-area.
|
/// An ordered list of poser joints, clustered by body-area.
|
||||||
/// Order is based on ease-of-use.
|
/// Order is based on ease-of-use.
|
||||||
/// Not necessarily exhaustive, just the joints we care to edit without adding UI clutter.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// For an implementation of something other than LLJoints, different name(s) may be required.
|
/// For an implementation of something other than LLJoints, different name(s) may be required.
|
||||||
|
/// A bvhEndSiteValue is only required if the bone has no descendants.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
const std::vector<FSPoserJoint> PoserJoints{
|
const std::vector<FSPoserJoint> PoserJoints{
|
||||||
// head, torso, legs
|
// head, torso, legs
|
||||||
{ "mHead", "", BODY, { "mEyeLeft", "mEyeRight", "mFaceRoot" }, "0.000 0.076 0.000" },
|
{ "mHead", "", BODY, { "mEyeLeft", "mEyeRight", "mFaceRoot", "mSkull" }, "0.000 0.076 0.000" },
|
||||||
{ "mNeck", "", BODY, { "mHead" }, "0.000 0.251 -0.010" },
|
{ "mNeck", "", BODY, { "mHead" }, "0.000 0.251 -0.010" },
|
||||||
{ "mPelvis", "", WHOLEAVATAR, { "mTorso", "mHipLeft", "mHipRight", "mTail1", "mGroin", "mHindLimbsRoot" }, "0.000000 0.000000 0.000000" },
|
{ "mPelvis", "", WHOLEAVATAR, { "mSpine1", "mHipLeft", "mHipRight", "mTail1", "mGroin", "mHindLimbsRoot" }, "0.000000 0.000000 0.000000" },
|
||||||
{ "mChest", "", BODY, { "mNeck", "mCollarLeft", "mCollarRight", "mWingsRoot" }, "0.000 0.205 -0.015" },
|
{ "mChest", "", BODY, { "mNeck", "mCollarLeft", "mCollarRight", "mWingsRoot" }, "0.000 0.205 -0.015" },
|
||||||
{ "mTorso", "", BODY, { "mChest" }, "0.000 0.084 0.000" },
|
{ "mTorso", "", BODY, { "mSpine3" }, "0.000 0.084 0.000" },
|
||||||
{ "mCollarLeft", "mCollarRight", BODY, { "mShoulderLeft" }, "0.085 0.165 -0.021" },
|
{ "mCollarLeft", "mCollarRight", BODY, { "mShoulderLeft" }, "0.085 0.165 -0.021" },
|
||||||
{ "mShoulderLeft", "mShoulderRight", BODY, { "mElbowLeft" }, "0.079 0.000 0.000" },
|
{ "mShoulderLeft", "mShoulderRight", BODY, { "mElbowLeft" }, "0.079 0.000 0.000" },
|
||||||
{ "mElbowLeft", "mElbowRight", BODY, { "mWristLeft" }, "0.248 0.000 0.000" },
|
{ "mElbowLeft", "mElbowRight", BODY, { "mWristLeft" }, "0.248 0.000 0.000" },
|
||||||
|
|
@ -212,10 +212,12 @@ public:
|
||||||
{ "mWristRight", "mWristLeft", BODY, { "mHandThumb1Right", "mHandIndex1Right", "mHandMiddle1Right", "mHandRing1Right", "mHandPinky1Right" }, "-0.205 0.000 0.000", "", true },
|
{ "mWristRight", "mWristLeft", BODY, { "mHandThumb1Right", "mHandIndex1Right", "mHandMiddle1Right", "mHandRing1Right", "mHandPinky1Right" }, "-0.205 0.000 0.000", "", true },
|
||||||
{ "mHipLeft", "mHipRight", BODY, { "mKneeLeft" }, "0.127 -0.041 0.034" },
|
{ "mHipLeft", "mHipRight", BODY, { "mKneeLeft" }, "0.127 -0.041 0.034" },
|
||||||
{ "mKneeLeft", "mKneeRight", BODY, { "mAnkleLeft" }, "-0.046 -0.491 -0.001" },
|
{ "mKneeLeft", "mKneeRight", BODY, { "mAnkleLeft" }, "-0.046 -0.491 -0.001" },
|
||||||
{ "mAnkleLeft", "mAnkleRight", BODY, {}, "0.001 -0.468 -0.029", "0.000 -0.061 0.112" },
|
{ "mAnkleLeft", "mAnkleRight", BODY, { "mToeLeft" }, "0.001 -0.468 -0.029" },
|
||||||
{ "mHipRight", "mHipLeft", BODY, { "mKneeRight" }, "-0.129 -0.041 0.034", "0.000 -0.061 0.112", true },
|
{ "mToeLeft", "mToeRight", BODY, {}, "0.000 0.109 0.000", "0.000 0.020 0.000" },
|
||||||
|
{ "mHipRight", "mHipLeft", BODY, { "mKneeRight" }, "-0.129 -0.041 0.034", "", true },
|
||||||
{ "mKneeRight", "mKneeLeft", BODY, { "mAnkleRight" }, "0.049 -0.491 -0.001", "", true },
|
{ "mKneeRight", "mKneeLeft", BODY, { "mAnkleRight" }, "0.049 -0.491 -0.001", "", true },
|
||||||
{ "mAnkleRight", "mAnkleLeft", BODY, {}, "0.000 -0.468 -0.029", "0.000 -0.061 0.112", true },
|
{ "mAnkleRight", "mAnkleLeft", BODY, { "mToeRight" }, "0.000 -0.468 -0.029", "", true },
|
||||||
|
{ "mToeRight", "mToeLeft", BODY, {}, "0.000 0.109 0.000", "0.000 0.020 0.000", true },
|
||||||
|
|
||||||
// face
|
// face
|
||||||
{ "mFaceRoot",
|
{ "mFaceRoot",
|
||||||
|
|
@ -225,10 +227,10 @@ public:
|
||||||
"mFaceForeheadLeft", "mFaceForeheadCenter", "mFaceForeheadRight",
|
"mFaceForeheadLeft", "mFaceForeheadCenter", "mFaceForeheadRight",
|
||||||
"mFaceEyebrowOuterLeft", "mFaceEyebrowCenterLeft", "mFaceEyebrowInnerLeft",
|
"mFaceEyebrowOuterLeft", "mFaceEyebrowCenterLeft", "mFaceEyebrowInnerLeft",
|
||||||
"mFaceEyebrowOuterRight", "mFaceEyebrowCenterRight", "mFaceEyebrowInnerRight",
|
"mFaceEyebrowOuterRight", "mFaceEyebrowCenterRight", "mFaceEyebrowInnerRight",
|
||||||
"mFaceEyeLidUpperLeft", "mFaceEyeLidLowerLeft",
|
"mFaceEyeLidUpperLeft", "mFaceEyeLidLowerLeft", "mFaceEyecornerInnerLeft",
|
||||||
"mFaceEyeLidUpperRight", "mFaceEyeLidLowerRight",
|
"mFaceEyeLidUpperRight", "mFaceEyeLidLowerRight", "mFaceEyecornerInnerRight",
|
||||||
"mFaceEar1Left", "mFaceEar1Right",
|
"mFaceEar1Left", "mFaceEar1Right",
|
||||||
"mFaceNoseLeft", "mFaceNoseCenter", "mFaceNoseRight",
|
"mFaceNoseBase", "mFaceNoseBridge", "mFaceNoseLeft", "mFaceNoseCenter", "mFaceNoseRight",
|
||||||
"mFaceCheekUpperLeft", "mFaceCheekLowerLeft",
|
"mFaceCheekUpperLeft", "mFaceCheekLowerLeft",
|
||||||
"mFaceCheekUpperRight", "mFaceCheekLowerRight",
|
"mFaceCheekUpperRight", "mFaceCheekLowerRight",
|
||||||
"mFaceJaw", "mFaceTeethUpper"
|
"mFaceJaw", "mFaceTeethUpper"
|
||||||
|
|
@ -247,14 +249,18 @@ public:
|
||||||
{ "mEyeLeft", "mEyeRight", FACE, {}, "-0.036 0.079 0.098", "0.000 0.000 0.025" },
|
{ "mEyeLeft", "mEyeRight", FACE, {}, "-0.036 0.079 0.098", "0.000 0.000 0.025" },
|
||||||
{ "mEyeRight", "mEyeLeft", FACE, {}, "0.036 0.079 0.098", "0.000 0.000 0.025", true },
|
{ "mEyeRight", "mEyeLeft", FACE, {}, "0.036 0.079 0.098", "0.000 0.000 0.025", true },
|
||||||
{ "mFaceEyeLidUpperLeft", "mFaceEyeLidUpperRight", FACE, {}, "0.036 0.034 0.073", "0.000 0.005 0.027" },
|
{ "mFaceEyeLidUpperLeft", "mFaceEyeLidUpperRight", FACE, {}, "0.036 0.034 0.073", "0.000 0.005 0.027" },
|
||||||
|
{ "mFaceEyecornerInnerLeft", "mFaceEyecornerInnerRight", FACE, {}, "0.032 0.075 0.017", "0.000 0.016 0.000" },
|
||||||
{ "mFaceEyeLidLowerLeft", "mFaceEyeLidLowerRight", FACE, {}, "0.036 0.034 0.073", "0.000 -0.007 0.024" },
|
{ "mFaceEyeLidLowerLeft", "mFaceEyeLidLowerRight", FACE, {}, "0.036 0.034 0.073", "0.000 -0.007 0.024" },
|
||||||
{ "mFaceEyeLidUpperRight", "mFaceEyeLidUpperLeft", FACE, {}, "-0.036 0.034 0.073", "0.000 0.005 0.027", true },
|
{ "mFaceEyeLidUpperRight", "mFaceEyeLidUpperLeft", FACE, {}, "-0.036 0.034 0.073", "0.000 0.005 0.027", true },
|
||||||
|
{ "mFaceEyecornerInnerRight", "mFaceEyecornerInnerLeft", FACE, {}, "0.032 0.075 -0.017", "0.000 0.016 0.000", true },
|
||||||
{ "mFaceEyeLidLowerRight", "mFaceEyeLidLowerLeft", FACE, {}, "-0.036 0.034 0.073", "0.000 -0.007 0.024", true },
|
{ "mFaceEyeLidLowerRight", "mFaceEyeLidLowerLeft", FACE, {}, "-0.036 0.034 0.073", "0.000 -0.007 0.024", true },
|
||||||
|
|
||||||
{ "mFaceEar1Left", "mFaceEar1Right", FACE, { "mFaceEar2Left" }, "0.080 0.002 0.000", "" },
|
{ "mFaceEar1Left", "mFaceEar1Right", FACE, { "mFaceEar2Left" }, "0.080 0.002 0.000", "" },
|
||||||
{ "mFaceEar2Left", "mFaceEar2Right", FACE, {}, "0.018 0.025 -0.019", "0.000 0.033 0.000" },
|
{ "mFaceEar2Left", "mFaceEar2Right", FACE, {}, "0.018 0.025 -0.019", "0.000 0.033 0.000" },
|
||||||
{ "mFaceEar1Right", "mFaceEar1Left", FACE, { "mFaceEar2Right" }, "-0.080 0.002 0.000", "", true },
|
{ "mFaceEar1Right", "mFaceEar1Left", FACE, { "mFaceEar2Right" }, "-0.080 0.002 0.000", "", true },
|
||||||
{ "mFaceEar2Right", "mFaceEar2Left", FACE, {}, "-0.018 0.025 -0.019", "0.000 0.033 0.000", true },
|
{ "mFaceEar2Right", "mFaceEar2Left", FACE, {}, "-0.018 0.025 -0.019", "0.000 0.033 0.000", true },
|
||||||
|
{ "mFaceNoseBase", "", FACE, {}, "-0.016 0.094 0.000", "0.000 0.014 0.000" },
|
||||||
|
{ "mFaceNoseBridge", "", FACE, {}, "0.020 0.091 0.000", "0.008 0.015 0.000" },
|
||||||
{ "mFaceNoseLeft", "mFaceNoseRight", FACE, {}, "0.015 -0.004 0.086", "0.004 0.000 0.015" },
|
{ "mFaceNoseLeft", "mFaceNoseRight", FACE, {}, "0.015 -0.004 0.086", "0.004 0.000 0.015" },
|
||||||
{ "mFaceNoseCenter", "", FACE, {}, "0.000 0.000 0.102", "0.000 0.000 0.025" },
|
{ "mFaceNoseCenter", "", FACE, {}, "0.000 0.000 0.102", "0.000 0.000 0.025" },
|
||||||
{ "mFaceNoseRight", "mFaceNoseLeft", FACE, {}, "-0.015 -0.004 0.086", "-0.004 0.000 0.015", true },
|
{ "mFaceNoseRight", "mFaceNoseLeft", FACE, {}, "-0.015 -0.004 0.086", "-0.004 0.000 0.015", true },
|
||||||
|
|
@ -343,11 +349,39 @@ public:
|
||||||
{ "mWing4Right", "mWing4Left", MISC, {}, "-0.173 0.000 -0.171", "-0.132 0.000 -0.146", true },
|
{ "mWing4Right", "mWing4Left", MISC, {}, "-0.173 0.000 -0.171", "-0.132 0.000 -0.146", true },
|
||||||
{ "mWing4FanRight", "mWing4FanLeft", MISC, {}, "-0.173 0.000 -0.171", "-0.062 -0.159 -0.068", true },
|
{ "mWing4FanRight", "mWing4FanLeft", MISC, {}, "-0.173 0.000 -0.171", "-0.062 -0.159 -0.068", true },
|
||||||
|
|
||||||
|
// Misc body parts
|
||||||
|
{ "mSkull", "", MISC, {}, "0.079 0.000 0.000", "0.033 0.000 0.000" },
|
||||||
|
{ "mSpine1", "", MISC, { "mSpine2" }, "0.084 0.000 0.000" },
|
||||||
|
{ "mSpine2", "", MISC, { "mTorso", }, "-0.084 0.000 0.000" },
|
||||||
|
{ "mSpine3", "", MISC, { "mSpine4" }, "0.205 -0.015 0.000" },
|
||||||
|
{ "mSpine4", "", MISC, { "mChest", }, "-0.205 0.015 0.000" },
|
||||||
|
|
||||||
// Collision Volumes
|
// Collision Volumes
|
||||||
|
{ "HEAD", "", COL_VOLUMES },
|
||||||
|
{ "NECK", "", COL_VOLUMES },
|
||||||
|
{ "L_CLAVICLE", "R_CLAVICLE", COL_VOLUMES },
|
||||||
|
{ "R_CLAVICLE", "L_CLAVICLE", COL_VOLUMES, {}, "", "", true },
|
||||||
|
{ "CHEST", "", COL_VOLUMES },
|
||||||
{ "LEFT_PEC", "RIGHT_PEC", COL_VOLUMES },
|
{ "LEFT_PEC", "RIGHT_PEC", COL_VOLUMES },
|
||||||
{ "RIGHT_PEC", "LEFT_PEC", COL_VOLUMES, {}, "", "", true },
|
{ "RIGHT_PEC", "LEFT_PEC", COL_VOLUMES, {}, "", "", true },
|
||||||
|
{ "UPPER_BACK", "", COL_VOLUMES },
|
||||||
|
{ "LEFT_HANDLE", "RIGHT_HANDLE", COL_VOLUMES },
|
||||||
|
{ "RIGHT_HANDLE", "LEFT_HANDLE", COL_VOLUMES, {}, "", "", true },
|
||||||
{ "BELLY", "", COL_VOLUMES },
|
{ "BELLY", "", COL_VOLUMES },
|
||||||
|
{ "PELVIS", "", COL_VOLUMES },
|
||||||
{ "BUTT", "", COL_VOLUMES },
|
{ "BUTT", "", COL_VOLUMES },
|
||||||
|
{ "L_UPPER_ARM", "R_UPPER_ARM", COL_VOLUMES },
|
||||||
|
{ "R_UPPER_ARM", "L_UPPER_ARM", COL_VOLUMES, {}, "", "", true },
|
||||||
|
{ "L_LOWER_ARM", "R_LOWER_ARM", COL_VOLUMES },
|
||||||
|
{ "R_LOWER_ARM", "L_LOWER_ARM", COL_VOLUMES, {}, "", "", true },
|
||||||
|
{ "L_HAND", "R_HAND", COL_VOLUMES },
|
||||||
|
{ "R_HAND", "L_HAND", COL_VOLUMES, {}, "", "", true },
|
||||||
|
{ "L_UPPER_LEG", "R_UPPER_LEG", COL_VOLUMES },
|
||||||
|
{ "R_UPPER_LEG", "L_UPPER_LEG", COL_VOLUMES, {}, "", "", true },
|
||||||
|
{ "L_LOWER_LEG", "R_LOWER_LEG", COL_VOLUMES },
|
||||||
|
{ "R_LOWER_LEG", "L_LOWER_LEG", COL_VOLUMES, {}, "", "", true },
|
||||||
|
{ "L_FOOT", "R_FOOT", COL_VOLUMES },
|
||||||
|
{ "R_FOOT", "L_FOOT", COL_VOLUMES, {}, "", "", true },
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,450 @@
|
||||||
|
/**
|
||||||
|
* @file fsprimfeedauth.cpp
|
||||||
|
* @file fsprimfeedauth.h
|
||||||
|
* @brief Primfeed Authorisation workflow class
|
||||||
|
* @author beq@firestorm
|
||||||
|
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||||
|
* Phoenix Firestorm Viewer Source Code
|
||||||
|
* Copyright (C) 2025, Beq Janus
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||||
|
* http://www.firestormviewer.org
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles Primfeed authentication and authorisation through a multi-factor OAuth flow.
|
||||||
|
*
|
||||||
|
* This module integrates with Primfeed’s Third Party Viewers API.
|
||||||
|
* The authentication flow is as follows:
|
||||||
|
* 1. Initiate a login request:
|
||||||
|
* POST https://api.primfeed.com/pf/viewer/create-login-request
|
||||||
|
* Headers:
|
||||||
|
* pf-viewer-api-key: <viewer_api_key>
|
||||||
|
* pf-user-uuid: <avatar_uuid>
|
||||||
|
* Response:
|
||||||
|
* { "requestId": "<64-char string>" }
|
||||||
|
*
|
||||||
|
* 2. Redirect the user to:
|
||||||
|
* https://www.primfeed.com/oauth/viewer?r=<requestId>&v=<viewer_api_key>
|
||||||
|
*
|
||||||
|
* 3. The user is shown an approval screen. When they click Authorize,
|
||||||
|
* an in-world message is sent:
|
||||||
|
* #PRIMFEED_OAUTH: <oauth_token>
|
||||||
|
* We intercept this code through an onChat handle then call onOauthTokenReceived().
|
||||||
|
*
|
||||||
|
* 4. Validate the login request:
|
||||||
|
* POST https://api.primfeed.com/pf/viewer/validate-request
|
||||||
|
* Headers:
|
||||||
|
* Authorization: Bearer <oauth_token>
|
||||||
|
* pf-viewer-api-key: <viewer_api_key>
|
||||||
|
* pf-viewer-request-id: <requestId>
|
||||||
|
* Response: HTTP 204
|
||||||
|
*
|
||||||
|
* 5. Optionally, check user status:
|
||||||
|
* GET https://api.primfeed.com/pf/viewer/user
|
||||||
|
* Headers:
|
||||||
|
* Authorization: Bearer <oauth_token>
|
||||||
|
* pf-viewer-api-key: <viewer_api_key>
|
||||||
|
* Response: { "plan": "free" } (or "pro")
|
||||||
|
*/
|
||||||
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
#include "fsprimfeedauth.h"
|
||||||
|
#include "fsprimfeedconnect.h"
|
||||||
|
#include "llimview.h"
|
||||||
|
#include "llnotificationsutil.h"
|
||||||
|
#include "llfloaterimnearbychathandler.h"
|
||||||
|
#include "llnotificationmanager.h"
|
||||||
|
#include "llagent.h"
|
||||||
|
#include "llevents.h"
|
||||||
|
#include "fscorehttputil.h"
|
||||||
|
#include "llwindow.h"
|
||||||
|
#include "llviewerwindow.h"
|
||||||
|
#include "lluri.h"
|
||||||
|
#include "llsdjson.h"
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
using Callback = FSPrimfeedAuth::authorized_callback_t;
|
||||||
|
|
||||||
|
// private instance variable
|
||||||
|
std::shared_ptr<FSPrimfeedAuth> FSPrimfeedAuth::sPrimfeedAuth;
|
||||||
|
std::unique_ptr<LLEventPump> FSPrimfeedAuth::sPrimfeedAuthPump = std::make_unique<LLEventStream>("PrimfeedAuthResponse");
|
||||||
|
|
||||||
|
// Helper callback that unpacks HTTP POST response data.
|
||||||
|
void FSPrimfeedAuthResponse(LLSD const &aData, Callback callback)
|
||||||
|
{
|
||||||
|
LLSD header = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS][LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
|
||||||
|
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(
|
||||||
|
aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]);
|
||||||
|
|
||||||
|
const LLSD::Binary &rawData = aData[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
|
||||||
|
std::string result;
|
||||||
|
result.assign(rawData.begin(), rawData.end());
|
||||||
|
|
||||||
|
// Assume JSON response.
|
||||||
|
|
||||||
|
LLSD resultLLSD;
|
||||||
|
if(!result.empty())
|
||||||
|
{
|
||||||
|
resultLLSD = LlsdFromJson(boost::json::parse(result));
|
||||||
|
}
|
||||||
|
callback((status.getType() == HTTP_OK ||
|
||||||
|
status.getType() == HTTP_NO_CONTENT), resultLLSD);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::initiateAuthRequest()
|
||||||
|
{
|
||||||
|
// This function is called to initiate the authentication request.
|
||||||
|
// It should be called when the user clicks the "Authenticate" button.
|
||||||
|
// Also triggered on opening the floater.
|
||||||
|
// The actual implementation is in the create() method.
|
||||||
|
|
||||||
|
if (!isAuthorized())
|
||||||
|
{
|
||||||
|
if (sPrimfeedAuth)
|
||||||
|
{
|
||||||
|
LLNotificationsUtil::add("PrimfeedAuthorizationAlreadyInProgress");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If no token stored, begin the login request; otherwise check user status.
|
||||||
|
sPrimfeedAuth = FSPrimfeedAuth::create(
|
||||||
|
[](bool success, const LLSD &response)
|
||||||
|
{
|
||||||
|
LLSD event_data = response;
|
||||||
|
event_data["success"] = success;
|
||||||
|
sPrimfeedAuthPump->post(event_data);
|
||||||
|
// Now that auth is complete, clear the static pointer.
|
||||||
|
sPrimfeedAuth.reset();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTING);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LLNotificationsUtil::add("PrimfeedAlreadyAuthorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::resetAuthStatus()
|
||||||
|
{
|
||||||
|
sPrimfeedAuth.reset();
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedOAuthToken", "");
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedProfileLink", "");
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedPlan", "");
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedUsername", "");
|
||||||
|
LLSD event_data;
|
||||||
|
event_data["status"] = "reset";
|
||||||
|
event_data["success"] = "false";
|
||||||
|
sPrimfeedAuthPump->post(event_data);
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_DISCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FSPrimfeedAuth::FSPrimfeedAuth(authorized_callback_t callback)
|
||||||
|
: mCallback(callback)
|
||||||
|
{
|
||||||
|
mChatMessageConnection = LLNotificationsUI::LLNotificationManager::instance().getChatHandler()->addNewChatCallback(
|
||||||
|
[this](const LLSD &message) {
|
||||||
|
LL_DEBUGS("FSPrimfeedAuth") << "Received chat message: " << message["message"].asString() << LL_ENDL;
|
||||||
|
this->onChatMessage(message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
FSPrimfeedAuth::~FSPrimfeedAuth()
|
||||||
|
{
|
||||||
|
if (mChatMessageConnection.connected())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mChatMessageConnection.disconnect();
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
LL_WARNS("FSPrimfeedAuth") << "Exception during chat connection disconnect: " << e.what() << LL_ENDL;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
LL_WARNS("FSPrimfeedAuth") << "Unknown exception during chat connection disconnect." << LL_ENDL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Factory method to create a shared pointer to FSPrimfeedAuth.
|
||||||
|
std::shared_ptr<FSPrimfeedAuth> FSPrimfeedAuth::create(authorized_callback_t callback)
|
||||||
|
{
|
||||||
|
// Ensure only one authentication attempt is in progress.
|
||||||
|
if (sPrimfeedAuth)
|
||||||
|
{
|
||||||
|
// Already in progress; return the existing instance.
|
||||||
|
return sPrimfeedAuth;
|
||||||
|
}
|
||||||
|
auto auth = std::shared_ptr<FSPrimfeedAuth>(new FSPrimfeedAuth(callback));
|
||||||
|
if(!auth)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTING);
|
||||||
|
|
||||||
|
// If no token stored, begin the login request; otherwise check user status.
|
||||||
|
if (gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken").empty())
|
||||||
|
{
|
||||||
|
auth->beginLoginRequest();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auth->checkUserStatus();
|
||||||
|
}
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::beginLoginRequest()
|
||||||
|
{
|
||||||
|
// Get our API key and user UUID.
|
||||||
|
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||||
|
std::string user_uuid = gAgent.getID().asString();
|
||||||
|
|
||||||
|
std::string url = "https://api.primfeed.com/pf/viewer/create-login-request";
|
||||||
|
std::string post_data = ""; // No body parameters required.
|
||||||
|
|
||||||
|
// Create the headers object.
|
||||||
|
LLCore::HttpHeaders::ptr_t pHeader(new LLCore::HttpHeaders());
|
||||||
|
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions());
|
||||||
|
|
||||||
|
pHeader->append("pf-viewer-api-key", viewer_api_key);
|
||||||
|
pHeader->append("pf-user-uuid", user_uuid);
|
||||||
|
|
||||||
|
// Set up HTTP options
|
||||||
|
options->setWantHeaders(true);
|
||||||
|
options->setRetries(0);
|
||||||
|
options->setTimeout(PRIMFEED_CONNECT_TIMEOUT);
|
||||||
|
|
||||||
|
// Capture shared_ptr to self
|
||||||
|
auto self = shared_from_this();
|
||||||
|
|
||||||
|
const auto end(pHeader->end());
|
||||||
|
for (auto it(pHeader->begin()); end != it; ++it)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Primfeed") << "Header: " << it->first << " = " << it->second << LL_ENDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass both success and failure callbacks
|
||||||
|
FSCoreHttpUtil::callbackHttpPostRaw(
|
||||||
|
url,
|
||||||
|
post_data,
|
||||||
|
[self](LLSD const &aData) {
|
||||||
|
LL_DEBUGS("FSPrimfeedAuth") << "Login request response(OK): " << aData << LL_ENDL;
|
||||||
|
FSPrimfeedAuthResponse(aData,
|
||||||
|
[self](bool success, const LLSD &response) {
|
||||||
|
self->gotRequestId(success, response);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[self](LLSD const &aData) {
|
||||||
|
LL_DEBUGS("FSPrimfeedAuth") << "Login request response(FAIL): " << aData << LL_ENDL;
|
||||||
|
FSPrimfeedAuthResponse(aData,
|
||||||
|
[self](bool success, const LLSD &response) {
|
||||||
|
self->gotRequestId(success, response);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
pHeader,
|
||||||
|
options
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::gotRequestId(bool success, const LLSD &response)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
LLNotificationsUtil::add("PrimfeedLoginRequestFailed");
|
||||||
|
mCallback(false, LLSD());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mRequestId = response["requestId"].asString();
|
||||||
|
if (mRequestId.empty())
|
||||||
|
{
|
||||||
|
LLNotificationsUtil::add("PrimfeedLoginRequestFailed");
|
||||||
|
mCallback(false, LLSD());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Open the browser for user approval.
|
||||||
|
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||||
|
std::string auth_url = "https://www.primfeed.com/oauth/viewer?r=" + mRequestId + "&v=" + viewer_api_key;
|
||||||
|
gViewerWindow->getWindow()->spawnWebBrowser(auth_url, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This function is called by the chat interceptor when the message
|
||||||
|
/// "#PRIMFEED_OAUTH: <oauth_token>" is intercepted.
|
||||||
|
void FSPrimfeedAuth::onOauthTokenReceived(const std::string_view& oauth_token)
|
||||||
|
{
|
||||||
|
if (oauth_token.empty())
|
||||||
|
{
|
||||||
|
mCallback(false, LLSD());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mOauthToken = oauth_token;
|
||||||
|
validateRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::onChatMessage(const LLSD& message)
|
||||||
|
{
|
||||||
|
constexpr std::string_view oauth_msg_prefix = "#PRIMFEED_OAUTH: ";
|
||||||
|
const std::string msg = message["message"].asString();
|
||||||
|
if (msg.find(std::string(oauth_msg_prefix)) == 0)
|
||||||
|
{
|
||||||
|
std::string_view oauth_token(msg.data() + oauth_msg_prefix.size(), msg.size() - oauth_msg_prefix.size());
|
||||||
|
LL_DEBUGS("Primfeed") << "Received OAuth token: " << msg << "extracted:<" << oauth_token << ">" << LL_ENDL;
|
||||||
|
onOauthTokenReceived(oauth_token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::validateRequest()
|
||||||
|
{
|
||||||
|
// No POST body needed.
|
||||||
|
std::string post_data = "";
|
||||||
|
std::string url = "https://api.primfeed.com/pf/viewer/validate-request";
|
||||||
|
|
||||||
|
// Retrieve the viewer API key.
|
||||||
|
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||||
|
|
||||||
|
// Create and populate the headers.
|
||||||
|
LLCore::HttpHeaders::ptr_t pHeader(new LLCore::HttpHeaders());
|
||||||
|
pHeader->append("Authorization", "Bearer " + mOauthToken);
|
||||||
|
pHeader->append("pf-viewer-api-key", viewer_api_key);
|
||||||
|
pHeader->append("pf-viewer-request-id", mRequestId);
|
||||||
|
|
||||||
|
// Set HTTP options
|
||||||
|
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions());
|
||||||
|
options->setWantHeaders(true);
|
||||||
|
options->setRetries(0);
|
||||||
|
options->setTimeout(PRIMFEED_CONNECT_TIMEOUT);
|
||||||
|
|
||||||
|
// print out pHeader for debuging using iterating over pHeader and using LL_DEBUGS
|
||||||
|
const auto end(pHeader->end());
|
||||||
|
for (auto it(pHeader->begin()); end != it; ++it)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("Primfeed") << "Header: " << it->first << " = " << it->second << LL_ENDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto self = shared_from_this();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FSCoreHttpUtil::callbackHttpPostRaw(
|
||||||
|
url,
|
||||||
|
post_data,
|
||||||
|
[self](LLSD const &aData) {
|
||||||
|
LL_DEBUGS("FSPrimfeedAuth") << "Validation-request response(OK): " << aData << LL_ENDL;
|
||||||
|
FSPrimfeedAuthResponse(aData,
|
||||||
|
[self](bool success, const LLSD &response) {
|
||||||
|
self->gotValidateResponse(success, response);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[self](LLSD const &aData) {
|
||||||
|
LL_INFOS("FSPrimfeedAuth") << "Validation-request response(FAIL): " << aData << LL_ENDL;
|
||||||
|
FSPrimfeedAuthResponse(aData,
|
||||||
|
[self](bool success, const LLSD &response) {
|
||||||
|
self->gotValidateResponse(success, response);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
pHeader,
|
||||||
|
options
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
LL_WARNS("Primfeed") << "Primfeed validation failed " << e.what() << LL_ENDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::gotValidateResponse(bool success, const LLSD &response)
|
||||||
|
{
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
LLNotificationsUtil::add("PrimfeedValidateFailed");
|
||||||
|
mCallback(false, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkUserStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::checkUserStatus()
|
||||||
|
{
|
||||||
|
std::string viewer_api_key = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||||
|
|
||||||
|
// Build the base URL without query parameters.
|
||||||
|
std::string url = "https://api.primfeed.com/pf/viewer/user";
|
||||||
|
LL_DEBUGS("Primfeed") << "URL: " << url << LL_ENDL;
|
||||||
|
|
||||||
|
// Create and populate the headers.
|
||||||
|
LLCore::HttpHeaders::ptr_t pHeader(new LLCore::HttpHeaders());
|
||||||
|
pHeader->append("Authorization", "Bearer " + mOauthToken);
|
||||||
|
pHeader->append("pf-viewer-api-key", viewer_api_key);
|
||||||
|
|
||||||
|
// Set HTTP options.
|
||||||
|
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions());
|
||||||
|
options->setWantHeaders(true);
|
||||||
|
options->setRetries(0);
|
||||||
|
options->setTimeout(PRIMFEED_CONNECT_TIMEOUT);
|
||||||
|
|
||||||
|
// Make the HTTP GET request, passing in the headers and options.
|
||||||
|
FSCoreHttpUtil::callbackHttpGetRaw(
|
||||||
|
url,
|
||||||
|
[this](LLSD const &aData) {
|
||||||
|
LL_DEBUGS("FSPrimfeedAuth") << "Check-user-status response: " << aData << LL_ENDL;
|
||||||
|
FSPrimfeedAuthResponse(aData, [this](bool success, const LLSD &response) {
|
||||||
|
this->gotUserStatus(success, response);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[this](LLSD const &aData) {
|
||||||
|
LL_INFOS("FSPrimfeedAuth") << "Check-user-status response (failure): " << aData << LL_ENDL;
|
||||||
|
// Optionally, call the same processing for failure or handle separately.
|
||||||
|
FSPrimfeedAuthResponse(aData, [this](bool success, const LLSD &response){
|
||||||
|
this->gotUserStatus(success, response);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pHeader,
|
||||||
|
options
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FSPrimfeedAuth::gotUserStatus(bool success, const LLSD &response)
|
||||||
|
{
|
||||||
|
LL_INFOS("Primfeed") << "User status: " << response << "(" << success << ")" << LL_ENDL;
|
||||||
|
if (success && response.has("plan"))
|
||||||
|
{
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedOAuthToken", mOauthToken);
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedPlan", response["plan"].asString());
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedProfileLink", response["link"].asString());
|
||||||
|
gSavedPerAccountSettings.setString("FSPrimfeedUsername", response["username"].asString());
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_CONNECTED);
|
||||||
|
mCallback(true, response);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LLNotificationsUtil::add("PrimfeedUserStatusFailed");
|
||||||
|
FSPrimfeedConnect::instance().setConnectionState(FSPrimfeedConnect::PRIMFEED_DISCONNECTED);
|
||||||
|
mCallback(false, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* @file fsprimfeedauth.h
|
||||||
|
* @brief Primfeed Authorisation workflow class
|
||||||
|
* @author beq@firestorm
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||||
|
* Phoenix Firestorm Viewer Source Code
|
||||||
|
* Copyright (C) 2025, Beq Janus
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||||
|
* http://www.firestormviewer.org
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
#ifndef FSPRIMFEEDAUTH_H
|
||||||
|
#define FSPRIMFEEDAUTH_H
|
||||||
|
|
||||||
|
#include "llsd.h"
|
||||||
|
#include "llviewercontrol.h"
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Primfeed authentication workflow class.
|
||||||
|
*
|
||||||
|
* This class handles the Primfeed OAuth login flow and provides methods to
|
||||||
|
* check the user status and receive a callback when the authentication
|
||||||
|
* process is complete.
|
||||||
|
* based on the workflow documented at https://docs.primfeed.com/api/third-party-viewers
|
||||||
|
*/
|
||||||
|
class FSPrimfeedAuth : public std::enable_shared_from_this<FSPrimfeedAuth>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Callback type: first parameter indicates success and the second holds any LLSD response.
|
||||||
|
using authorized_callback_t = std::function<void(bool, const LLSD&)>;
|
||||||
|
static std::shared_ptr<FSPrimfeedAuth> create(authorized_callback_t callback);
|
||||||
|
static std::unique_ptr<LLEventPump> sPrimfeedAuthPump;
|
||||||
|
~FSPrimfeedAuth();
|
||||||
|
|
||||||
|
// Should be called by the chat interceptor when an oauth token is received.
|
||||||
|
void onOauthTokenReceived(const std::string_view& oauth_token);
|
||||||
|
void onInstantMessage(const LLSD& message);
|
||||||
|
void onChatMessage(const LLSD& message);
|
||||||
|
|
||||||
|
// Begin the login request flow.
|
||||||
|
void beginLoginRequest();
|
||||||
|
// Check the user status.
|
||||||
|
void checkUserStatus();
|
||||||
|
static bool isPendingAuth(){ return (sPrimfeedAuth != nullptr); }
|
||||||
|
static bool isAuthorized(){ return (!gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken").empty()); }
|
||||||
|
static void initiateAuthRequest();
|
||||||
|
static void resetAuthStatus();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::shared_ptr<FSPrimfeedAuth> sPrimfeedAuth;
|
||||||
|
|
||||||
|
explicit FSPrimfeedAuth(authorized_callback_t callback);
|
||||||
|
authorized_callback_t mCallback;
|
||||||
|
std::string mOauthToken;
|
||||||
|
std::string mRequestId;
|
||||||
|
|
||||||
|
// Callback when a login request response is received.
|
||||||
|
void gotRequestId(bool success, const LLSD &response);
|
||||||
|
// Validate the login request.
|
||||||
|
void validateRequest();
|
||||||
|
// Callback when the validate response is received.
|
||||||
|
void gotValidateResponse(bool success, const LLSD &response);
|
||||||
|
// Callback when the user status response is received.
|
||||||
|
void gotUserStatus(bool success, const LLSD &response);
|
||||||
|
|
||||||
|
boost::signals2::connection mInstantMessageConnection;
|
||||||
|
boost::signals2::connection mChatMessageConnection;
|
||||||
|
// Static flag to prevent duplicate authentication attempts.
|
||||||
|
static std::atomic<bool> sAuthorisationInProgress;
|
||||||
|
|
||||||
|
static constexpr U32 PRIMFEED_CONNECT_TIMEOUT = 300; // 5 minute timeout should work
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FSPRIMFEEDAUTH_H
|
||||||
|
|
@ -0,0 +1,189 @@
|
||||||
|
/**
|
||||||
|
* @file fsprimfeedconnect.cpp
|
||||||
|
* @brief Primfeed connector class
|
||||||
|
* @author beq@firestorm
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||||
|
* Phoenix Firestorm Viewer Source Code
|
||||||
|
* Copyright (C) 2025, Beq Janus
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||||
|
* http://www.firestormviewer.org
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
#include "fsprimfeedconnect.h"
|
||||||
|
#include "fsprimfeedauth.h"
|
||||||
|
#include "llviewercontrol.h"
|
||||||
|
#include "llcoros.h"
|
||||||
|
#include "llsdjson.h"
|
||||||
|
|
||||||
|
// The connector workflow for Primfeed is realtively simple and mostly just builds on top of the established Auth workflow
|
||||||
|
// and the posting endpoint documented at https://docs.primfeed.com/api/third-party-viewers#creating-a-post
|
||||||
|
|
||||||
|
FSPrimfeedConnect::FSPrimfeedConnect() = default;
|
||||||
|
|
||||||
|
void FSPrimfeedConnect::uploadPhoto(const LLSD& params, LLImageFormatted* image, post_callback_t callback)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("primfeed") << "uploadPhoto() called" << LL_ENDL;
|
||||||
|
if (!FSPrimfeedAuth::isAuthorized())
|
||||||
|
{
|
||||||
|
LL_WARNS("primfeed") << "Authorization failed, aborting.\n" << LL_ENDL;
|
||||||
|
callback(false, "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LL_DEBUGS("primfeed") << "Authorization successful" << LL_ENDL;
|
||||||
|
|
||||||
|
mPostCallback = callback;
|
||||||
|
LL_DEBUGS("primfeed") << "Launching upload coroutine" << LL_ENDL;
|
||||||
|
LLCoros::instance().launch(
|
||||||
|
"FSPrimfeedConnect::uploadPhotoCoro",
|
||||||
|
[this, params, image]() { uploadPhotoCoro(params, image); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedConnect::uploadPhotoCoro(const LLSD& params, LLImageFormatted* image)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("primfeed") << "Entered uploadPhotoCoro" << LL_ENDL;
|
||||||
|
setConnectionState(PRIMFEED_POSTING);
|
||||||
|
LL_DEBUGS("primfeed") << "Connection state set to PRIMFEED_POSTING" << LL_ENDL;
|
||||||
|
|
||||||
|
const std::string fmt = (image->getCodec() == EImageCodec::IMG_CODEC_JPEG) ? "jpg" : "png";
|
||||||
|
LL_DEBUGS("primfeed") << "Image format: " << fmt << LL_ENDL;
|
||||||
|
|
||||||
|
const std::string boundary = "----------------------------0123456789abcdef";
|
||||||
|
const std::string sep = "\n";
|
||||||
|
const std::string dash = "--" + boundary;
|
||||||
|
|
||||||
|
LL_DEBUGS("primfeed") << "Building multipart body" << LL_ENDL;
|
||||||
|
LLCore::BufferArray::ptr_t raw(new LLCore::BufferArray());
|
||||||
|
LLCore::BufferArrayStream body(raw.get());
|
||||||
|
auto addPart = [&](const std::string& name, const std::string& val)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("primfeed") << "Adding part: " << name << "=" << val << LL_ENDL;
|
||||||
|
body << dash << sep
|
||||||
|
<< "Content-Disposition: form-data; name=\"" << name << "\"" << sep << sep
|
||||||
|
<< val << sep;
|
||||||
|
};
|
||||||
|
|
||||||
|
addPart("commercial", params["commercial"].asBoolean() ? "true" : "false");
|
||||||
|
addPart("rating", params["rating"].asString());
|
||||||
|
addPart("content", params["content"].asString());
|
||||||
|
addPart("publicGallery", params["post_to_public_gallery"].asBoolean()? "true" : "false");
|
||||||
|
|
||||||
|
if (params.has("location") && !params["location"].asString().empty())
|
||||||
|
{
|
||||||
|
addPart("location", params["location"].asString());
|
||||||
|
}
|
||||||
|
|
||||||
|
LL_DEBUGS("primfeed") << "Adding image file header" << LL_ENDL;
|
||||||
|
body << dash << sep
|
||||||
|
<< "Content-Disposition: form-data; name=\"image\"; filename=\"snapshot." << fmt << "\"" << sep
|
||||||
|
<< "Content-Type: image/" << fmt << sep << sep;
|
||||||
|
|
||||||
|
U8* data = image->getData();
|
||||||
|
S32 size = image->getDataSize();
|
||||||
|
LL_DEBUGS("primfeed") << "Appending image data, size=" << size << LL_ENDL;
|
||||||
|
// yep this seems inefficient, but all other occurrences in the codebase do it this way.
|
||||||
|
for (S32 i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
body << data[i];
|
||||||
|
}
|
||||||
|
body << sep;
|
||||||
|
|
||||||
|
body << dash << "--" << sep;
|
||||||
|
LL_DEBUGS("primfeed") << "Multipart body ready" << LL_ENDL;
|
||||||
|
|
||||||
|
// Setup HTTP
|
||||||
|
LL_DEBUGS("primfeed") << "Preparing HTTP request" << LL_ENDL;
|
||||||
|
LLCore::HttpRequest::policy_t policy = LLCore::HttpRequest::DEFAULT_POLICY_ID;
|
||||||
|
LLCoreHttpUtil::HttpCoroutineAdapter adapter("PrimfeedUpload", policy);
|
||||||
|
LLCore::HttpRequest::ptr_t request(new LLCore::HttpRequest);
|
||||||
|
LLCore::HttpOptions::ptr_t options(new LLCore::HttpOptions);
|
||||||
|
options->setWantHeaders(true);
|
||||||
|
|
||||||
|
LL_DEBUGS("primfeed") << "Setting HTTP headers" << LL_ENDL;
|
||||||
|
LLCore::HttpHeaders::ptr_t headers(new LLCore::HttpHeaders);
|
||||||
|
std::string token = gSavedPerAccountSettings.getString("FSPrimfeedOAuthToken");
|
||||||
|
std::string apiKey = gSavedSettings.getString("FSPrimfeedViewerApiKey");
|
||||||
|
headers->append("Authorization", "Bearer " + token);
|
||||||
|
headers->append("pf-viewer-api-key", apiKey);
|
||||||
|
headers->append("Content-Type", "multipart/form-data; boundary=" + boundary);
|
||||||
|
LL_DEBUGS("primfeed") << "Dumping HTTP headers for POST:" << LL_ENDL;
|
||||||
|
for (auto it = headers->begin(); it != headers->end(); ++it)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("primfeed") << it->first << ": " << it->second << LL_ENDL;
|
||||||
|
}
|
||||||
|
LL_DEBUGS("primfeed") << "Headers set" << LL_ENDL;
|
||||||
|
|
||||||
|
LL_DEBUGS("primfeed") << "Starting HTTP POST" << LL_ENDL;
|
||||||
|
LLSD result = adapter.postRawAndSuspend(request,
|
||||||
|
"https://api.primfeed.com/pf/viewer/post",
|
||||||
|
raw,
|
||||||
|
options,
|
||||||
|
headers);
|
||||||
|
LL_DEBUGS("primfeed") << "HTTP POST complete" << LL_ENDL;
|
||||||
|
|
||||||
|
const LLSD::Binary &rawData = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
|
||||||
|
std::string response_raw;
|
||||||
|
response_raw.assign(rawData.begin(), rawData.end());
|
||||||
|
LLSD result_LLSD;
|
||||||
|
if(!response_raw.empty())
|
||||||
|
{
|
||||||
|
result_LLSD = LlsdFromJson(boost::json::parse(response_raw));
|
||||||
|
}
|
||||||
|
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]);
|
||||||
|
bool success = (status.getType() == HTTP_OK);
|
||||||
|
LL_DEBUGS("primfeed") << "HTTP status =" << (success?"OK":"FAIL") << " "<< status.getMessage() << LL_ENDL;
|
||||||
|
|
||||||
|
std::string url;
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
url = result_LLSD["url"].asString();
|
||||||
|
LL_DEBUGS("primfeed") << "Received URL=" << url << LL_ENDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LL_DEBUGS("primfeed") << "Invoking callback" << LL_ENDL;
|
||||||
|
mPostCallback(success, url);
|
||||||
|
setConnectionState(success ? PRIMFEED_POSTED : PRIMFEED_POST_FAILED);
|
||||||
|
LL_DEBUGS("primfeed") << "Final state set" << LL_ENDL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle connection state transitions
|
||||||
|
void FSPrimfeedConnect::setConnectionState(EConnectionState state)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("primfeed") << "setConnectionState(" << state << ")" << LL_ENDL;
|
||||||
|
mConnectionState = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSPrimfeedConnect::EConnectionState FSPrimfeedConnect::getConnectionState() const
|
||||||
|
{
|
||||||
|
return mConnectionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FSPrimfeedConnect::isTransactionOngoing() const
|
||||||
|
{
|
||||||
|
return (mConnectionState == PRIMFEED_CONNECTING ||
|
||||||
|
mConnectionState == PRIMFEED_POSTING ||
|
||||||
|
mConnectionState == PRIMFEED_DISCONNECTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSPrimfeedConnect::loadPrimfeedInfo()
|
||||||
|
{
|
||||||
|
LL_DEBUGS("primfeed") << "loadPrimfeedInfo() called" << LL_ENDL;
|
||||||
|
// Nothing to do here for Primfeed
|
||||||
|
setConnectionState(PRIMFEED_CONNECTED);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* @file fsprimfeedconect.h
|
||||||
|
* @brief Primfeed connector class
|
||||||
|
* @author beq@firestorm
|
||||||
|
*
|
||||||
|
* $LicenseInfo:firstyear=2025&license=fsviewerlgpl$
|
||||||
|
* Phoenix Firestorm Viewer Source Code
|
||||||
|
* Copyright (C) 2025, Beq Janus
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA
|
||||||
|
* http://www.firestormviewer.org
|
||||||
|
* $/LicenseInfo$
|
||||||
|
*/
|
||||||
|
#ifndef FS_PRIMFEEDCONNECT_H
|
||||||
|
#define FS_PRIMFEEDCONNECT_H
|
||||||
|
|
||||||
|
#include "llsingleton.h"
|
||||||
|
#include "llsd.h"
|
||||||
|
#include "llimage.h"
|
||||||
|
#include "fsprimfeedauth.h"
|
||||||
|
#include "llcorehttputil.h"
|
||||||
|
#include "bufferarray.h"
|
||||||
|
#include "llcoros.h"
|
||||||
|
#include "llviewercontrol.h" // for gSavedSettings/gSavedPerAccountSettings
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
// Coro based connector designed to interface with floater designed along the same principles as LLFloaterFlickr.cpp
|
||||||
|
|
||||||
|
class FSPrimfeedConnect : public LLSingleton<FSPrimfeedConnect>
|
||||||
|
{
|
||||||
|
LLSINGLETON(FSPrimfeedConnect);
|
||||||
|
public:
|
||||||
|
// Connection states for Primfeed operations
|
||||||
|
enum EConnectionState
|
||||||
|
{
|
||||||
|
PRIMFEED_DISCONNECTED = 0,
|
||||||
|
PRIMFEED_CONNECTING,
|
||||||
|
PRIMFEED_CONNECTED,
|
||||||
|
PRIMFEED_POSTING,
|
||||||
|
PRIMFEED_POSTED,
|
||||||
|
PRIMFEED_POST_FAILED,
|
||||||
|
PRIMFEED_DISCONNECTING
|
||||||
|
};
|
||||||
|
|
||||||
|
// Callback invoked on post completion: success flag and URL (empty on failure)
|
||||||
|
using post_callback_t = std::function<void(bool success, const std::string& url)>;
|
||||||
|
|
||||||
|
// Posts a snapshot to Primfeed; requires FSPrimfeedAuth::isAuthorized()
|
||||||
|
void uploadPhoto(const LLSD& params, LLImageFormatted* image, post_callback_t callback);
|
||||||
|
|
||||||
|
// Retrieve and update account info from Primfeed (not used kept for compatibility)
|
||||||
|
void loadPrimfeedInfo();
|
||||||
|
|
||||||
|
void setConnectionState(EConnectionState state);
|
||||||
|
EConnectionState getConnectionState() const;
|
||||||
|
bool isTransactionOngoing() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Internal coroutine entry-point for uploads
|
||||||
|
void uploadPhotoCoro(const LLSD& params, LLImageFormatted* image);
|
||||||
|
|
||||||
|
// Cached callback until coroutine completes
|
||||||
|
post_callback_t mPostCallback;
|
||||||
|
|
||||||
|
// Current connection/post state
|
||||||
|
EConnectionState mConnectionState = PRIMFEED_DISCONNECTED;
|
||||||
|
};
|
||||||
|
#endif // FS_PRIMFEEDCONNECT_H
|
||||||
|
|
@ -646,6 +646,12 @@ void GLTFSceneManager::render(Asset& asset, U8 variant)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gGLTFPBRMetallicRoughnessProgram.mGLTFVariants.size() <= variant)
|
||||||
|
{
|
||||||
|
llassert(false); // mGLTFVariants should have been initialized
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (U32 ds = 0; ds < 2; ++ds)
|
for (U32 ds = 0; ds < 2; ++ds)
|
||||||
{
|
{
|
||||||
RenderData& rd = asset.mRenderData[ds];
|
RenderData& rd = asset.mRenderData[ds];
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -234,6 +234,8 @@
|
||||||
#include "llfloaterreg.h"
|
#include "llfloaterreg.h"
|
||||||
#include "llfloatersimplesnapshot.h"
|
#include "llfloatersimplesnapshot.h"
|
||||||
#include "llfloatersnapshot.h"
|
#include "llfloatersnapshot.h"
|
||||||
|
#include "llfloaterflickr.h"
|
||||||
|
#include "fsfloaterprimfeed.h" // <FS:Beq/> Primfeed Floater
|
||||||
#include "llsidepanelinventory.h"
|
#include "llsidepanelinventory.h"
|
||||||
#include "llatmosphere.h"
|
#include "llatmosphere.h"
|
||||||
|
|
||||||
|
|
@ -1764,6 +1766,8 @@ bool LLAppViewer::doFrame()
|
||||||
gPipeline.mReflectionMapManager.update();
|
gPipeline.mReflectionMapManager.update();
|
||||||
LLFloaterSnapshot::update(); // take snapshots
|
LLFloaterSnapshot::update(); // take snapshots
|
||||||
LLFloaterSimpleSnapshot::update();
|
LLFloaterSimpleSnapshot::update();
|
||||||
|
LLFloaterFlickr::update(); // <FS:Beq/> FIRE-35002 - Flickr preview not updating whne opened directly from tool tray icon
|
||||||
|
FSFloaterPrimfeed::update(); // <FS:Beq/> Primfeed support
|
||||||
gGLActive = false;
|
gGLActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3808,6 +3812,7 @@ bool LLAppViewer::waitForUpdater()
|
||||||
|
|
||||||
void LLAppViewer::writeDebugInfo(bool isStatic)
|
void LLAppViewer::writeDebugInfo(bool isStatic)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING; // <FS:Beq/> improve instrumentation
|
||||||
#if LL_WINDOWS && LL_BUGSPLAT
|
#if LL_WINDOWS && LL_BUGSPLAT
|
||||||
// <FS:Beq> Improve Bugsplat tracking by using attributes for certain static data items.
|
// <FS:Beq> Improve Bugsplat tracking by using attributes for certain static data items.
|
||||||
const LLSD& info = getViewerInfo();
|
const LLSD& info = getViewerInfo();
|
||||||
|
|
@ -3836,6 +3841,7 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
|
||||||
|
|
||||||
LLSD LLAppViewer::getViewerInfo() const
|
LLSD LLAppViewer::getViewerInfo() const
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING; // <FS:Beq/> improve instrumentation
|
||||||
// The point of having one method build an LLSD info block and the other
|
// The point of having one method build an LLSD info block and the other
|
||||||
// construct the user-visible About string is to ensure that the same info
|
// construct the user-visible About string is to ensure that the same info
|
||||||
// is available to a getInfo() caller as to the user opening
|
// is available to a getInfo() caller as to the user opening
|
||||||
|
|
@ -4148,6 +4154,7 @@ LLSD LLAppViewer::getViewerInfo() const
|
||||||
// info["DISK_CACHE_INFO"] = LLDiskCache::getInstance()->getCacheInfo();
|
// info["DISK_CACHE_INFO"] = LLDiskCache::getInstance()->getCacheInfo();
|
||||||
if (auto cache = LLDiskCache::getInstance(); cache)
|
if (auto cache = LLDiskCache::getInstance(); cache)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_NAMED("gvi-getCacheInfo"); // <FS:Beq/> improve instrumentation
|
||||||
info["DISK_CACHE_INFO"] = cache->getCacheInfo();
|
info["DISK_CACHE_INFO"] = cache->getCacheInfo();
|
||||||
}
|
}
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
|
|
@ -6003,7 +6010,7 @@ void LLAppViewer::idle()
|
||||||
// objects and camera should be in sync, do LOD calculations now
|
// objects and camera should be in sync, do LOD calculations now
|
||||||
{
|
{
|
||||||
LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE);
|
LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE);
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Added a max time limit to the object list updates as these updates do affect the texture system
|
// Added a max time limit to the object list updates as these updates do affect the texture system
|
||||||
//gObjectList.updateApparentAngles(gAgent);
|
//gObjectList.updateApparentAngles(gAgent);
|
||||||
F32 max_update_apparent_angles = 0.025f * gFrameIntervalSeconds.value(); // 20 ms/second decode time
|
F32 max_update_apparent_angles = 0.025f * gFrameIntervalSeconds.value(); // 20 ms/second decode time
|
||||||
|
|
|
||||||
|
|
@ -644,11 +644,13 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
|
||||||
// <FS:Beq> Use the Attributes API on Windows to enhance crash metadata
|
// <FS:Beq> Use the Attributes API on Windows to enhance crash metadata
|
||||||
void LLAppViewerWin32::bugsplatAddStaticAttributes(const LLSD& info)
|
void LLAppViewerWin32::bugsplatAddStaticAttributes(const LLSD& info)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING;
|
||||||
#ifdef LL_BUGSPLAT
|
#ifdef LL_BUGSPLAT
|
||||||
auto& bugSplatMap = BugSplatAttributes::instance();
|
auto& bugSplatMap = BugSplatAttributes::instance();
|
||||||
static bool write_once_after_startup = false;
|
static bool write_once_after_startup = false;
|
||||||
if (!write_once_after_startup )
|
if (!write_once_after_startup )
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_NAMED("bs-st-att-once")
|
||||||
// Only write the attributes that are fixed once after we've started.
|
// Only write the attributes that are fixed once after we've started.
|
||||||
// note we might update them more than once and some/many may be empty during startup as we want to catch early crashes
|
// note we might update them more than once and some/many may be empty during startup as we want to catch early crashes
|
||||||
// once we're started we can assume they don't change for this run.
|
// once we're started we can assume they don't change for this run.
|
||||||
|
|
@ -689,7 +691,7 @@ void LLAppViewerWin32::bugsplatAddStaticAttributes(const LLSD& info)
|
||||||
#if LL_DARWIN
|
#if LL_DARWIN
|
||||||
bugSplatMap.setAttribute("HiDPI", info["HIDPI"].asBoolean() ? "Enabled" : "Disabled");
|
bugSplatMap.setAttribute("HiDPI", info["HIDPI"].asBoolean() ? "Enabled" : "Disabled");
|
||||||
#endif
|
#endif
|
||||||
bugSplatMap.setAttribute("Max Texture Size", gSavedSettings.getString("RenderMaxTextureResolution"));
|
bugSplatMap.setAttribute("Max Texture Size", gSavedSettings.getU32("RenderMaxTextureResolution"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// These attributes are potentially dynamic
|
// These attributes are potentially dynamic
|
||||||
|
|
@ -1034,6 +1036,29 @@ bool LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LLAppViewerWin32::initWindow()
|
||||||
|
{
|
||||||
|
// This is a workaround/hotfix for a change in Windows 11 24H2 (and possibly later)
|
||||||
|
// Where the window width and height need to correctly reflect an available FullScreen size
|
||||||
|
if (gSavedSettings.getBOOL("FullScreen"))
|
||||||
|
{
|
||||||
|
DEVMODE dev_mode;
|
||||||
|
::ZeroMemory(&dev_mode, sizeof(DEVMODE));
|
||||||
|
dev_mode.dmSize = sizeof(DEVMODE);
|
||||||
|
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode))
|
||||||
|
{
|
||||||
|
gSavedSettings.setU32("WindowWidth", dev_mode.dmPelsWidth);
|
||||||
|
gSavedSettings.setU32("WindowHeight", dev_mode.dmPelsHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LL_WARNS("AppInit") << "Unable to set WindowWidth and WindowHeight for FullScreen mode" << LL_ENDL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return LLAppViewer::initWindow();
|
||||||
|
}
|
||||||
|
|
||||||
void LLAppViewerWin32::initLoggingAndGetLastDuration()
|
void LLAppViewerWin32::initLoggingAndGetLastDuration()
|
||||||
{
|
{
|
||||||
LLAppViewer::initLoggingAndGetLastDuration();
|
LLAppViewer::initLoggingAndGetLastDuration();
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ public:
|
||||||
bool reportCrashToBugsplat(void* pExcepInfo) override;
|
bool reportCrashToBugsplat(void* pExcepInfo) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool initWindow() override; // Override to initialize the viewer's window.
|
||||||
void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info.
|
void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info.
|
||||||
void initConsole() override; // Initialize OS level debugging console.
|
void initConsole() override; // Initialize OS level debugging console.
|
||||||
bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
|
bool initHardwareTest() override; // Win32 uses DX9 to test hardware.
|
||||||
|
|
|
||||||
|
|
@ -516,7 +516,7 @@ void LLAvatarTracker::idleNotifyObservers()
|
||||||
|
|
||||||
void LLAvatarTracker::notifyObservers()
|
void LLAvatarTracker::notifyObservers()
|
||||||
{
|
{
|
||||||
if (mIsNotifyObservers || (LLStartUp::getStartupState() <= STATE_INVENTORY_CALLBACKS))
|
if (mIsNotifyObservers || (LLStartUp::getStartupState() <= STATE_INVENTORY_SEND2))
|
||||||
{
|
{
|
||||||
// Don't allow multiple calls.
|
// Don't allow multiple calls.
|
||||||
// new masks and ids will be processed later from idle.
|
// new masks and ids will be processed later from idle.
|
||||||
|
|
@ -835,7 +835,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
|
||||||
mModifyMask |= LLFriendObserver::ONLINE;
|
mModifyMask |= LLFriendObserver::ONLINE;
|
||||||
instance().notifyObservers();
|
instance().notifyObservers();
|
||||||
// Skip if we had received the friends list before the inventory callbacks were properly initialized
|
// Skip if we had received the friends list before the inventory callbacks were properly initialized
|
||||||
if (LLStartUp::getStartupState() > STATE_INVENTORY_CALLBACKS)
|
if (LLStartUp::getStartupState() > STATE_INVENTORY_SEND2)
|
||||||
{
|
{
|
||||||
gInventory.notifyObservers();
|
gInventory.notifyObservers();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ static LLStaticHashedString sColorIn("color_in");
|
||||||
|
|
||||||
bool LLFace::sSafeRenderSelect = true; // false
|
bool LLFace::sSafeRenderSelect = true; // false
|
||||||
|
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Moved to allow more code to access these values
|
// Moved to allow more code to access these values
|
||||||
const S8 FACE_IMPORTANCE_LEVEL = 4 ;
|
const S8 FACE_IMPORTANCE_LEVEL = 4 ;
|
||||||
const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight}
|
const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight}
|
||||||
|
|
@ -180,7 +180,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
|
||||||
mFaceColor = LLColor4(1,0,0,1);
|
mFaceColor = LLColor4(1,0,0,1);
|
||||||
|
|
||||||
mImportanceToCamera = 1.f ;
|
mImportanceToCamera = 1.f ;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
mCloseToCamera = 1.0f;
|
mCloseToCamera = 1.0f;
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
mBoundingSphereRadius = 0.0f ;
|
mBoundingSphereRadius = 0.0f ;
|
||||||
|
|
@ -1683,7 +1683,7 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
|
||||||
xforms = XFORM_NONE;
|
xforms = XFORM_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Removed check for turning off animations
|
// Removed check for turning off animations
|
||||||
//if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))
|
//if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
@ -2287,7 +2287,7 @@ F32 LLFace::getTextureVirtualSize()
|
||||||
|
|
||||||
F32 radius;
|
F32 radius;
|
||||||
F32 cos_angle_to_view_dir;
|
F32 cos_angle_to_view_dir;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
//bool in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
|
//bool in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
|
||||||
// The mInFrustum value is now updated in calcPixelArea, so no longer need to accss the value
|
// The mInFrustum value is now updated in calcPixelArea, so no longer need to accss the value
|
||||||
calcPixelArea(cos_angle_to_view_dir, radius);
|
calcPixelArea(cos_angle_to_view_dir, radius);
|
||||||
|
|
@ -2325,7 +2325,7 @@ F32 LLFace::getTextureVirtualSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
|
face_area = LLFace::adjustPixelArea(mImportanceToCamera, face_area);
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Remove the face area being affected by being partial off screen as close to screen textures can then become scaled down along with
|
// Remove the face area being affected by being partial off screen as close to screen textures can then become scaled down along with
|
||||||
// animated textures.
|
// animated textures.
|
||||||
/*
|
/*
|
||||||
|
|
@ -2423,7 +2423,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
||||||
// no rigged extents, zero out bounding box and skip update
|
// no rigged extents, zero out bounding box and skip update
|
||||||
mRiggedExtents[0] = mRiggedExtents[1] = LLVector4a(0.f, 0.f, 0.f);
|
mRiggedExtents[0] = mRiggedExtents[1] = LLVector4a(0.f, 0.f, 0.f);
|
||||||
|
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Set the face to be out of the frustum as the object is invalid
|
// Set the face to be out of the frustum as the object is invalid
|
||||||
mInFrustum = false;
|
mInFrustum = false;
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
@ -2473,7 +2473,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
||||||
LLVector4a x_axis;
|
LLVector4a x_axis;
|
||||||
x_axis.load3(camera->getXAxis().mV);
|
x_axis.load3(camera->getXAxis().mV);
|
||||||
cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32();
|
cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32();
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Added close to camera (based upon the mImportanceToCamera) where any object that is within the FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE (16.1f)
|
// Added close to camera (based upon the mImportanceToCamera) where any object that is within the FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE (16.1f)
|
||||||
// gets an extra texture scaling up.
|
// gets an extra texture scaling up.
|
||||||
// Use positive distance to the camera and apply the multiplier based upon the texture scaled for increase in the default draw distance
|
// Use positive distance to the camera and apply the multiplier based upon the texture scaled for increase in the default draw distance
|
||||||
|
|
@ -2488,7 +2488,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
||||||
if(!camera->AABBInFrustum(center, size))
|
if(!camera->AABBInFrustum(center, size))
|
||||||
{
|
{
|
||||||
mImportanceToCamera = 0.f ;
|
mImportanceToCamera = 0.f ;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Added real in frustum check value. Previous was only false for media textures off screen and invalid rig objects
|
// Added real in frustum check value. Previous was only false for media textures off screen and invalid rig objects
|
||||||
mInFrustum = false;
|
mInFrustum = false;
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
@ -2514,7 +2514,7 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius)
|
||||||
{
|
{
|
||||||
cos_angle_to_view_dir = 1.0f ;
|
cos_angle_to_view_dir = 1.0f ;
|
||||||
mImportanceToCamera = 1.0f ;
|
mImportanceToCamera = 1.0f ;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
mInFrustum = true; // If the face is important to the camera, it is in the frustum
|
mInFrustum = true; // If the face is important to the camera, it is in the frustum
|
||||||
mCloseToCamera = 1.0f;
|
mCloseToCamera = 1.0f;
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
@ -2561,7 +2561,7 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
|
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
|
||||||
F32 importance = 0.f ;
|
F32 importance = 0.f ;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Move camera out to use for the inital check for the distance to the face importance with the multiplier
|
// Move camera out to use for the inital check for the distance to the face importance with the multiplier
|
||||||
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
LLViewerCamera* camera = LLViewerCamera::getInstance();
|
||||||
|
|
||||||
|
|
@ -2581,7 +2581,7 @@ F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist)
|
||||||
}
|
}
|
||||||
|
|
||||||
S32 i = 0 ;
|
S32 i = 0 ;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Added draw distance multiplier to the distance
|
// Added draw distance multiplier to the distance
|
||||||
for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0] * camera->getDrawDistanceMultiplier(); ++i);
|
for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0] * camera->getDrawDistanceMultiplier(); ++i);
|
||||||
// </FS:minerjr> [FIRE-35081]
|
// </FS:minerjr> [FIRE-35081]
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class LLDrawInfo;
|
||||||
class LLMeshSkinInfo;
|
class LLMeshSkinInfo;
|
||||||
|
|
||||||
const F32 MIN_ALPHA_SIZE = 1024.f;
|
const F32 MIN_ALPHA_SIZE = 1024.f;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
//const F32 MIN_TEX_ANIM_SIZE = 512.f;
|
//const F32 MIN_TEX_ANIM_SIZE = 512.f;
|
||||||
// Change the min size to
|
// Change the min size to
|
||||||
const F32 MIN_TEX_ANIM_SIZE = 10.f;
|
const F32 MIN_TEX_ANIM_SIZE = 10.f;
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ void LLFloaterBvhPreview::setAnimCallbacks()
|
||||||
getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1));
|
getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map <std::string, std::string> LLFloaterBvhPreview::getJointAliases()
|
std::map <std::string, std::string, std::less<>> LLFloaterBvhPreview::getJointAliases()
|
||||||
{
|
{
|
||||||
LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar();
|
LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar();
|
||||||
return av->getJointAliases();
|
return av->getJointAliases();
|
||||||
|
|
@ -337,7 +337,7 @@ bool LLFloaterBvhPreview::loadBVH()
|
||||||
ELoadStatus load_status = E_ST_OK;
|
ELoadStatus load_status = E_ST_OK;
|
||||||
S32 line_number = 0;
|
S32 line_number = 0;
|
||||||
|
|
||||||
std::map<std::string, std::string> joint_alias_map = getJointAliases();
|
auto joint_alias_map = getJointAliases();
|
||||||
|
|
||||||
loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map);
|
loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map);
|
||||||
std::string status = getString(STATUS[load_status]);
|
std::string status = getString(STATUS[load_status]);
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ public:
|
||||||
// </FS:Sei>
|
// </FS:Sei>
|
||||||
private:
|
private:
|
||||||
void setAnimCallbacks() ;
|
void setAnimCallbacks() ;
|
||||||
std::map <std::string, std::string> getJointAliases();
|
std::map <std::string, std::string, std::less<>> getJointAliases();
|
||||||
|
|
||||||
// <FS> Reload animation from disk
|
// <FS> Reload animation from disk
|
||||||
bool loadBVH();
|
bool loadBVH();
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "llviewerprecompiledheaders.h"
|
#include "llviewerprecompiledheaders.h"
|
||||||
|
|
||||||
|
#include "llfloatersnapshot.h" // <FS:Beq/> Fix share to flickr preview again
|
||||||
#include "llfloaterflickr.h"
|
#include "llfloaterflickr.h"
|
||||||
|
|
||||||
#include "llagent.h"
|
#include "llagent.h"
|
||||||
|
|
@ -243,7 +244,16 @@ void LLFlickrPhotoPanel::draw()
|
||||||
// Draw the rest of the panel on top of it
|
// Draw the rest of the panel on top of it
|
||||||
LLPanel::draw();
|
LLPanel::draw();
|
||||||
}
|
}
|
||||||
|
// <FS:Beq> FIRE-35002 - Flickr preview not updating whne opened directly from tool tray icon
|
||||||
|
//static
|
||||||
|
void LLFloaterFlickr::update()
|
||||||
|
{
|
||||||
|
if (LLFloaterReg::instanceVisible("flickr"))
|
||||||
|
{
|
||||||
|
LLFloaterSnapshotBase::ImplBase::updatePreviewList( true, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// </FS:Beq>
|
||||||
LLSnapshotLivePreview* LLFlickrPhotoPanel::getPreviewView()
|
LLSnapshotLivePreview* LLFlickrPhotoPanel::getPreviewView()
|
||||||
{
|
{
|
||||||
LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
|
LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get();
|
||||||
|
|
|
||||||
|
|
@ -136,6 +136,7 @@ public:
|
||||||
void onOpen(const LLSD& key);
|
void onOpen(const LLSD& key);
|
||||||
LLSnapshotLivePreview* getPreviewView(); // <FS:Beq/> Required for snapshot frame rendering
|
LLSnapshotLivePreview* getPreviewView(); // <FS:Beq/> Required for snapshot frame rendering
|
||||||
|
|
||||||
|
static void update(); // <FS:Beq/> FIRE-35002 - Flickr preview not updating whne opened directly from tool tray icon
|
||||||
private:
|
private:
|
||||||
LLFlickrPhotoPanel* mFlickrPhotoPanel;
|
LLFlickrPhotoPanel* mFlickrPhotoPanel;
|
||||||
LLTextBox* mStatusErrorText;
|
LLTextBox* mStatusErrorText;
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,13 @@ public:
|
||||||
{
|
{
|
||||||
ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime, this));
|
ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime, this));
|
||||||
}
|
}
|
||||||
|
// <FS:darl> [FIRE-35039 > FIRE-35294] Add flag to show/hide the on-screen console
|
||||||
|
ctrl = gSavedSettings.getControl("FSShowOnscreenConsole").get();
|
||||||
|
if (ctrl)
|
||||||
|
{
|
||||||
|
ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::removeToastsFromChannel, this));
|
||||||
|
}
|
||||||
|
// </FS:darl> [FIRE-35039 > FIRE-35294] Add flag to show/hide the on-screen console
|
||||||
}
|
}
|
||||||
|
|
||||||
void addChat (LLSD& chat);
|
void addChat (LLSD& chat);
|
||||||
|
|
@ -663,7 +670,14 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// <FS:Beq> Hide Primfeed OAuth message from chat to prevent accidental leak of secret.
|
||||||
|
const std::string primfeed_oauth = "#PRIMFEED_OAUTH: ";
|
||||||
|
if( chat_msg.mText.compare(0, primfeed_oauth.length(), primfeed_oauth) == 0 && chat_msg.mChatType == CHAT_TYPE_IM && chat_msg.mSourceType == CHAT_SOURCE_OBJECT )
|
||||||
|
{
|
||||||
|
// Don't show the message in chat.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// </FS:Beq>
|
||||||
nearby_chat->addMessage(chat_msg, true, args);
|
nearby_chat->addMessage(chat_msg, true, args);
|
||||||
|
|
||||||
if (chat_msg.mSourceType == CHAT_SOURCE_AGENT
|
if (chat_msg.mSourceType == CHAT_SOURCE_AGENT
|
||||||
|
|
@ -694,6 +708,14 @@ void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
|
||||||
}
|
}
|
||||||
// </FS:Ansariel>
|
// </FS:Ansariel>
|
||||||
|
|
||||||
|
// <FS:darl> [FIRE-35039 > FIRE-35294] Add flag to show/hide the on-screen console
|
||||||
|
static LLUICachedControl<bool> showOnscreenConsole("FSShowOnscreenConsole");
|
||||||
|
if (!showOnscreenConsole)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// </FS:darl> [FIRE-35039 > FIRE-35294]
|
||||||
|
|
||||||
static LLCachedControl<bool> useChatBubbles(gSavedSettings, "UseChatBubbles");
|
static LLCachedControl<bool> useChatBubbles(gSavedSettings, "UseChatBubbles");
|
||||||
static LLCachedControl<bool> fsBubblesHideConsoleAndToasts(gSavedSettings, "FSBubblesHideConsoleAndToasts");
|
static LLCachedControl<bool> fsBubblesHideConsoleAndToasts(gSavedSettings, "FSBubblesHideConsoleAndToasts");
|
||||||
// <FS:Ansariel> [FS communication UI]
|
// <FS:Ansariel> [FS communication UI]
|
||||||
|
|
|
||||||
|
|
@ -1625,14 +1625,9 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
|
||||||
for (U32 j = 0; j < joint_count; ++j)
|
for (U32 j = 0; j < joint_count; ++j)
|
||||||
{
|
{
|
||||||
const LLVector3& joint_pos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation());
|
const LLVector3& joint_pos = LLVector3(skin->mAlternateBindMatrix[j].getTranslation());
|
||||||
// <FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
|
||||||
//LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
|
|
||||||
|
|
||||||
//LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview);
|
LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview);
|
||||||
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j].mName];
|
|
||||||
|
|
||||||
LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j].mName, mModelPreview);
|
|
||||||
// <FS:ND>
|
|
||||||
if (pJoint)
|
if (pJoint)
|
||||||
{
|
{
|
||||||
// see how voavatar uses aboveJointPosThreshold
|
// see how voavatar uses aboveJointPosThreshold
|
||||||
|
|
@ -1661,9 +1656,7 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
|
||||||
{
|
{
|
||||||
for (U32 j = 0; j < joint_count; ++j)
|
for (U32 j = 0; j < joint_count; ++j)
|
||||||
{
|
{
|
||||||
// <FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
|
||||||
//LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
|
|
||||||
LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j].mName];
|
|
||||||
data.mModelsNoOverrides.insert(model->getName());
|
data.mModelsNoOverrides.insert(model->getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1678,7 +1671,7 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
|
||||||
{
|
{
|
||||||
// Populate table
|
// Populate table
|
||||||
|
|
||||||
std::map<std::string, std::string> joint_alias_map;
|
std::map<std::string, std::string, std::less<>> joint_alias_map;
|
||||||
mModelPreview->getJointAliases(joint_alias_map);
|
mModelPreview->getJointAliases(joint_alias_map);
|
||||||
|
|
||||||
S32 conflicts = 0;
|
S32 conflicts = 0;
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,27 @@ bool LLFloaterNewFeatureNotification::postBuild()
|
||||||
|
|
||||||
const std::string title_txt = "title_txt";
|
const std::string title_txt = "title_txt";
|
||||||
const std::string dsc_txt = "description_txt";
|
const std::string dsc_txt = "description_txt";
|
||||||
std::string feature = "_" + getKey().asString();
|
// <FS:Beq> FIRE-35393 stop crashing just cos whirly does something daft and blames Atlas for it
|
||||||
|
std::string feature = getKey().asString();
|
||||||
|
if(feature.empty() )
|
||||||
|
{
|
||||||
|
LL_WARNS("FloaterNewFeature") << "Unexpected failure - No feature name NewFeatureNotification." << LL_ENDL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!hasString( title_txt + "_" + feature ) )
|
||||||
|
{
|
||||||
|
LL_WARNS("FloaterNewFeature") << "No string for " << title_txt + "_" + feature << LL_ENDL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!hasString( dsc_txt + "_" + feature ) )
|
||||||
|
{
|
||||||
|
LL_WARNS("FloaterNewFeature") << "No string for " << dsc_txt + "_" + feature << LL_ENDL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// </FS:Beq>
|
||||||
|
|
||||||
getChild<LLUICtrl>(title_txt)->setValue(getString(title_txt + feature));
|
getChild<LLUICtrl>(title_txt)->setValue(getString(title_txt + "_" + feature));
|
||||||
getChild<LLUICtrl>(dsc_txt)->setValue(getString(dsc_txt + feature));
|
getChild<LLUICtrl>(dsc_txt)->setValue(getString(dsc_txt + "_" + feature));
|
||||||
|
|
||||||
if (getKey().asString() == "gltf")
|
if (getKey().asString() == "gltf")
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "llfloaterreg.h"
|
#include "llfloaterreg.h"
|
||||||
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
||||||
|
#include "fsfloaterprimfeed.h" // <FS:Beq> Share to Primfeed
|
||||||
#include "llimagefiltersmanager.h"
|
#include "llimagefiltersmanager.h"
|
||||||
#include "llcheckboxctrl.h"
|
#include "llcheckboxctrl.h"
|
||||||
#include "llcombobox.h"
|
#include "llcombobox.h"
|
||||||
|
|
@ -1485,12 +1486,12 @@ bool LLFloaterSnapshot::isWaitingState()
|
||||||
|
|
||||||
// <FS:Beq> FIRE-35002 - Post to flickr broken, improved solution
|
// <FS:Beq> FIRE-35002 - Post to flickr broken, improved solution
|
||||||
// bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
|
// bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized)
|
||||||
bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized, bool have_flickr)
|
bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized, bool have_socials)
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
{
|
{
|
||||||
// <FS:Ansariel> Share to Flickr
|
// <FS:Ansariel> Share to Flickr
|
||||||
//if (!initialized)
|
//if (!initialized)
|
||||||
if (!initialized && !have_flickr)
|
if (!initialized && !have_socials)
|
||||||
// </FS:Ansariel>
|
// </FS:Ansariel>
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -1509,11 +1510,13 @@ void LLFloaterSnapshotBase::ImplBase::updateLivePreview()
|
||||||
{
|
{
|
||||||
// don't update preview for hidden floater
|
// don't update preview for hidden floater
|
||||||
// <FS:Beq> FIRE-35002 - Post to flickr broken
|
// <FS:Beq> FIRE-35002 - Post to flickr broken
|
||||||
LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr");
|
bool have_socials = (
|
||||||
auto have_flickr = floater_flickr != nullptr;
|
LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr") != nullptr ||
|
||||||
|
LLFloaterReg::findTypedInstance<FSFloaterPrimfeed>("primfeed") != nullptr
|
||||||
|
);
|
||||||
if ( ((mFloater && mFloater->isInVisibleChain()) ||
|
if ( ((mFloater && mFloater->isInVisibleChain()) ||
|
||||||
have_flickr) &&
|
have_socials) &&
|
||||||
ImplBase::updatePreviewList(true, have_flickr))
|
ImplBase::updatePreviewList(true, have_socials))
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
{
|
{
|
||||||
LL_DEBUGS() << "changed" << LL_ENDL;
|
LL_DEBUGS() << "changed" << LL_ENDL;
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ public:
|
||||||
virtual EStatus getStatus() const { return mStatus; }
|
virtual EStatus getStatus() const { return mStatus; }
|
||||||
virtual void setNeedRefresh(bool need);
|
virtual void setNeedRefresh(bool need);
|
||||||
|
|
||||||
static bool updatePreviewList(bool initialized, bool have_flickr = false); // <FS:Beq/> FIRE-35002 - Post to flickr broken, improved solution
|
static bool updatePreviewList(bool initialized, bool have_socials = false); // <FS:Beq/> FIRE-35002 - Post to flickr broken, improved solution
|
||||||
|
|
||||||
void setAdvanced(bool advanced) { mAdvanced = advanced; }
|
void setAdvanced(bool advanced) { mAdvanced = advanced; }
|
||||||
void setSkipReshaping(bool skip) { mSkipReshaping = skip; }
|
void setSkipReshaping(bool skip) { mSkipReshaping = skip; }
|
||||||
|
|
|
||||||
|
|
@ -433,10 +433,13 @@ bool LLFloaterWorldMap::postBuild()
|
||||||
F32 slider_zoom = mMapView->getZoom();
|
F32 slider_zoom = mMapView->getZoom();
|
||||||
mZoomSlider->setValue(slider_zoom);
|
mZoomSlider->setValue(slider_zoom);
|
||||||
|
|
||||||
|
mTrackCtrlsPanel = getChild<LLPanel>("layout_panel_4");
|
||||||
|
mSearchButton = getChild<LLButton>("DoSearch");
|
||||||
|
|
||||||
// <FS:Ansariel> Use own expand/collapse function
|
// <FS:Ansariel> Use own expand/collapse function
|
||||||
//getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this));
|
//getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this));
|
||||||
|
|
||||||
setDefaultBtn(NULL);
|
mTrackCtrlsPanel->setDefaultBtn(nullptr);
|
||||||
|
|
||||||
onChangeMaturity();
|
onChangeMaturity();
|
||||||
|
|
||||||
|
|
@ -784,7 +787,7 @@ void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string&
|
||||||
{
|
{
|
||||||
LLTracker::stopTracking(false);
|
LLTracker::stopTracking(false);
|
||||||
}
|
}
|
||||||
setDefaultBtn("Teleport");
|
mTrackCtrlsPanel->setDefaultBtn(mTeleportButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
|
void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
|
||||||
|
|
@ -829,7 +832,7 @@ void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
|
||||||
{
|
{
|
||||||
LLTracker::stopTracking(false);
|
LLTracker::stopTracking(false);
|
||||||
}
|
}
|
||||||
setDefaultBtn("Teleport");
|
mTrackCtrlsPanel->setDefaultBtn(mTeleportButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -838,7 +841,7 @@ void LLFloaterWorldMap::trackEvent(const LLItemInfo &event_info)
|
||||||
mShowParcelInfo = false;
|
mShowParcelInfo = false;
|
||||||
mTrackedStatus = LLTracker::TRACKING_LOCATION;
|
mTrackedStatus = LLTracker::TRACKING_LOCATION;
|
||||||
LLTracker::trackLocation(event_info.getGlobalPosition(), event_info.getName(), event_info.getToolTip(), LLTracker::LOCATION_EVENT);
|
LLTracker::trackLocation(event_info.getGlobalPosition(), event_info.getName(), event_info.getToolTip(), LLTracker::LOCATION_EVENT);
|
||||||
setDefaultBtn("Teleport");
|
mTrackCtrlsPanel->setDefaultBtn(mTeleportButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item)
|
void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item)
|
||||||
|
|
@ -846,7 +849,7 @@ void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item)
|
||||||
mShowParcelInfo = false;
|
mShowParcelInfo = false;
|
||||||
mTrackedStatus = LLTracker::TRACKING_LOCATION;
|
mTrackedStatus = LLTracker::TRACKING_LOCATION;
|
||||||
LLTracker::trackLocation(item.getGlobalPosition(), item.getName(), item.getToolTip(), LLTracker::LOCATION_ITEM);
|
LLTracker::trackLocation(item.getGlobalPosition(), item.getName(), item.getToolTip(), LLTracker::LOCATION_ITEM);
|
||||||
setDefaultBtn("Teleport");
|
mTrackCtrlsPanel->setDefaultBtn(mTeleportButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
|
void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
|
||||||
|
|
@ -860,7 +863,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
|
||||||
S32 world_x = S32(pos_global.mdV[0] / 256);
|
S32 world_x = S32(pos_global.mdV[0] / 256);
|
||||||
S32 world_y = S32(pos_global.mdV[1] / 256);
|
S32 world_y = S32(pos_global.mdV[1] / 256);
|
||||||
LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
|
LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
|
||||||
setDefaultBtn("");
|
mTrackCtrlsPanel->setDefaultBtn(nullptr);
|
||||||
|
|
||||||
// clicked on a non-region - turn off coord display
|
// clicked on a non-region - turn off coord display
|
||||||
enableTeleportCoordsDisplay( false );
|
enableTeleportCoordsDisplay( false );
|
||||||
|
|
@ -874,7 +877,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
|
||||||
LLTracker::stopTracking(false);
|
LLTracker::stopTracking(false);
|
||||||
LLWorldMap::getInstance()->setTracking(pos_global);
|
LLWorldMap::getInstance()->setTracking(pos_global);
|
||||||
LLWorldMap::getInstance()->setTrackingInvalid();
|
LLWorldMap::getInstance()->setTrackingInvalid();
|
||||||
setDefaultBtn("");
|
mTrackCtrlsPanel->setDefaultBtn(nullptr);
|
||||||
|
|
||||||
// clicked on a down region - turn off coord display
|
// clicked on a down region - turn off coord display
|
||||||
enableTeleportCoordsDisplay( false );
|
enableTeleportCoordsDisplay( false );
|
||||||
|
|
@ -925,7 +928,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
|
||||||
// we have a valid region - turn on coord display
|
// we have a valid region - turn on coord display
|
||||||
enableTeleportCoordsDisplay( true );
|
enableTeleportCoordsDisplay( true );
|
||||||
|
|
||||||
setDefaultBtn("Teleport");
|
mTrackCtrlsPanel->setDefaultBtn(mTeleportButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable/disable teleport destination coordinates
|
// enable/disable teleport destination coordinates
|
||||||
|
|
@ -1085,9 +1088,9 @@ void LLFloaterWorldMap::updateLocation()
|
||||||
// mSLURL = LLSLURL(sim_name, pos_global);
|
// mSLURL = LLSLURL(sim_name, pos_global);
|
||||||
// <FS> [FIRE-35268] OpenSim support for when on other grids
|
// <FS> [FIRE-35268] OpenSim support for when on other grids
|
||||||
if (LLGridManager::getInstance()->isInSecondLife())
|
if (LLGridManager::getInstance()->isInSecondLife())
|
||||||
mSLURL = LLSLURL(sim_info->getName(), gAgent.getPositionAgent());
|
mSLURL = LLSLURL(sim_info->getName(), sim_info->getGlobalOrigin(), pos_global);
|
||||||
else
|
else
|
||||||
mSLURL = LLSLURL(LFSimFeatureHandler::instance().hyperGridURL(), sim_info->getName(), gAgent.getPositionAgent());
|
mSLURL = LLSLURL(LFSimFeatureHandler::instance().hyperGridURL(), sim_info->getName(), sim_info->getGlobalOrigin(), pos_global);
|
||||||
// </FS>
|
// </FS>
|
||||||
}
|
}
|
||||||
// </FS:Beq pp Oren>
|
// </FS:Beq pp Oren>
|
||||||
|
|
@ -1131,7 +1134,7 @@ void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S3
|
||||||
local_pos.mV[VZ] = (F32)z_coord;
|
local_pos.mV[VZ] = (F32)z_coord;
|
||||||
LLVector3d global_pos = sim_info->getGlobalPos(local_pos);
|
LLVector3d global_pos = sim_info->getGlobalPos(local_pos);
|
||||||
trackLocation(global_pos);
|
trackLocation(global_pos);
|
||||||
setDefaultBtn("Teleport");
|
mTrackCtrlsPanel->setDefaultBtn(mTeleportButton);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1569,11 +1572,11 @@ void LLFloaterWorldMap::updateSearchEnabled()
|
||||||
if (childHasKeyboardFocus("location") &&
|
if (childHasKeyboardFocus("location") &&
|
||||||
mLocationEditor->getValue().asString().length() > 0)
|
mLocationEditor->getValue().asString().length() > 0)
|
||||||
{
|
{
|
||||||
setDefaultBtn("DoSearch");
|
mTrackCtrlsPanel->setDefaultBtn(mSearchButton);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setDefaultBtn(NULL);
|
mTrackCtrlsPanel->setDefaultBtn(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2033,7 +2036,7 @@ void LLFloaterWorldMap::onCommitSearchResult()
|
||||||
|
|
||||||
mLocationEditor->setValue(sim_name);
|
mLocationEditor->setValue(sim_name);
|
||||||
trackLocation(pos_global);
|
trackLocation(pos_global);
|
||||||
setDefaultBtn("Teleport");
|
mTrackCtrlsPanel->setDefaultBtn(mTeleportButton);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,7 @@ private:
|
||||||
LLButton* mShowDestinationButton = nullptr;
|
LLButton* mShowDestinationButton = nullptr;
|
||||||
LLButton* mCopySlurlButton = nullptr;
|
LLButton* mCopySlurlButton = nullptr;
|
||||||
LLButton* mGoHomeButton = nullptr;
|
LLButton* mGoHomeButton = nullptr;
|
||||||
|
LLButton* mSearchButton = nullptr;
|
||||||
|
|
||||||
LLCheckBoxCtrl* mPeopleCheck = nullptr;
|
LLCheckBoxCtrl* mPeopleCheck = nullptr;
|
||||||
LLCheckBoxCtrl* mInfohubCheck = nullptr;
|
LLCheckBoxCtrl* mInfohubCheck = nullptr;
|
||||||
|
|
@ -258,6 +259,8 @@ private:
|
||||||
|
|
||||||
LLSliderCtrl* mZoomSlider = nullptr;
|
LLSliderCtrl* mZoomSlider = nullptr;
|
||||||
|
|
||||||
|
LLPanel* mTrackCtrlsPanel = nullptr;
|
||||||
|
|
||||||
boost::signals2::connection mTeleportFinishConnection;
|
boost::signals2::connection mTeleportFinishConnection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3914,16 +3914,55 @@ LLUUID LLIMMgr::addSession(
|
||||||
//works only for outgoing ad-hoc sessions
|
//works only for outgoing ad-hoc sessions
|
||||||
if (new_session &&
|
if (new_session &&
|
||||||
((IM_NOTHING_SPECIAL == dialog) || (IM_SESSION_P2P_INVITE == dialog) || (IM_SESSION_CONFERENCE_START == dialog)) &&
|
((IM_NOTHING_SPECIAL == dialog) || (IM_SESSION_P2P_INVITE == dialog) || (IM_SESSION_CONFERENCE_START == dialog)) &&
|
||||||
ids.size())
|
// <AS:chanayane> [FIRE-34494] fix unable to open an IM with someone who started a group chat
|
||||||
|
//ids.size())
|
||||||
|
!ids.empty())
|
||||||
|
// </AS:chanayane>
|
||||||
{
|
{
|
||||||
session = LLIMModel::getInstance()->findAdHocIMSession(ids);
|
session = LLIMModel::getInstance()->findAdHocIMSession(ids);
|
||||||
if (session)
|
if (session)
|
||||||
{
|
{
|
||||||
new_session = false;
|
// <AS:chanayane> [FIRE-34494] fix unable to open an IM with someone who started a group chat
|
||||||
session_id = session->mSessionID;
|
// new_session = false;
|
||||||
|
// session_id = session->mSessionID;
|
||||||
|
|
||||||
|
// Protect against wrong session type reuse (e.g., conference reused for IM)
|
||||||
|
if (session->mType != dialog)
|
||||||
|
{
|
||||||
|
LL_WARNS("IMVIEW") << "Discarding mismatched session type reuse: expected "
|
||||||
|
<< dialog << " but found " << session->mType
|
||||||
|
<< " for session " << session->mSessionID
|
||||||
|
<< ". This may indicate improper reuse of a session object." << LL_ENDL;
|
||||||
|
session = nullptr;
|
||||||
|
new_session = true;
|
||||||
|
session_id = computeSessionID(dialog, other_participant_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_session = false;
|
||||||
|
session_id = session->mSessionID;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session && session->mType != dialog)
|
||||||
|
{
|
||||||
|
// Prevent reusing a session of the wrong type
|
||||||
|
session = nullptr;
|
||||||
|
new_session = true;
|
||||||
|
|
||||||
|
// Recompute session ID depending on dialog type
|
||||||
|
if (dialog == IM_SESSION_CONFERENCE_START)
|
||||||
|
{
|
||||||
|
session_id.generate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
session_id = computeSessionID(dialog, other_participant_id);
|
||||||
|
}
|
||||||
|
// </AS:chanayane>
|
||||||
|
}
|
||||||
|
|
||||||
//Notify observers that a session was added
|
//Notify observers that a session was added
|
||||||
if (new_session)
|
if (new_session)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -346,6 +346,15 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
||||||
LL_DEBUGS("LLLogin") << "reason " << reason_response
|
LL_DEBUGS("LLLogin") << "reason " << reason_response
|
||||||
<< " message " << message_response
|
<< " message " << message_response
|
||||||
<< LL_ENDL;
|
<< LL_ENDL;
|
||||||
|
|
||||||
|
if (response.has("mfa_hash"))
|
||||||
|
{
|
||||||
|
mRequestData["params"]["mfa_hash"] = response["mfa_hash"];
|
||||||
|
mRequestData["params"]["token"] = "";
|
||||||
|
|
||||||
|
saveMFAHash(response);
|
||||||
|
}
|
||||||
|
|
||||||
// For the cases of critical message or TOS agreement,
|
// For the cases of critical message or TOS agreement,
|
||||||
// start the TOS dialog. The dialog response will be handled
|
// start the TOS dialog. The dialog response will be handled
|
||||||
// by the LLLoginInstance::handleTOSResponse() callback.
|
// by the LLLoginInstance::handleTOSResponse() callback.
|
||||||
|
|
@ -609,6 +618,24 @@ bool LLLoginInstance::handleMFAChallenge(LLSD const & notif, LLSD const & respon
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLLoginInstance::saveMFAHash(LLSD const& response)
|
||||||
|
{
|
||||||
|
std::string grid(LLGridManager::getInstance()->getGridId());
|
||||||
|
std::string user_id(LLStartUp::getUserId());
|
||||||
|
|
||||||
|
// Only save mfa_hash for future logins if the user wants their info remembered.
|
||||||
|
if (response.has("mfa_hash") && gSavedSettings.getBOOL("RememberUser") && LLLoginInstance::getInstance()->saveMFA())
|
||||||
|
{
|
||||||
|
gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]);
|
||||||
|
}
|
||||||
|
else if (!LLLoginInstance::getInstance()->saveMFA())
|
||||||
|
{
|
||||||
|
gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id);
|
||||||
|
}
|
||||||
|
// TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically
|
||||||
|
gSecAPIHandler->syncProtectedMap();
|
||||||
|
}
|
||||||
|
|
||||||
std::string construct_start_string()
|
std::string construct_start_string()
|
||||||
{
|
{
|
||||||
std::string start;
|
std::string start;
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,8 @@ public:
|
||||||
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
|
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
|
||||||
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
|
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
|
||||||
|
|
||||||
|
void saveMFAHash(LLSD const& response);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::shared_ptr<LLEventAPI::Response> ResponsePtr;
|
typedef std::shared_ptr<LLEventAPI::Response> ResponsePtr;
|
||||||
void constructAuthParams(LLPointer<LLCredential> user_credentials);
|
void constructAuthParams(LLPointer<LLCredential> user_credentials);
|
||||||
|
|
|
||||||
|
|
@ -1909,42 +1909,36 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
|
||||||
//static
|
//static
|
||||||
void LLMeshRepoThread::incActiveLODRequests()
|
void LLMeshRepoThread::incActiveLODRequests()
|
||||||
{
|
{
|
||||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
|
||||||
++LLMeshRepoThread::sActiveLODRequests;
|
++LLMeshRepoThread::sActiveLODRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void LLMeshRepoThread::decActiveLODRequests()
|
void LLMeshRepoThread::decActiveLODRequests()
|
||||||
{
|
{
|
||||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
|
||||||
--LLMeshRepoThread::sActiveLODRequests;
|
--LLMeshRepoThread::sActiveLODRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void LLMeshRepoThread::incActiveHeaderRequests()
|
void LLMeshRepoThread::incActiveHeaderRequests()
|
||||||
{
|
{
|
||||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
|
||||||
++LLMeshRepoThread::sActiveHeaderRequests;
|
++LLMeshRepoThread::sActiveHeaderRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void LLMeshRepoThread::decActiveHeaderRequests()
|
void LLMeshRepoThread::decActiveHeaderRequests()
|
||||||
{
|
{
|
||||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
|
||||||
--LLMeshRepoThread::sActiveHeaderRequests;
|
--LLMeshRepoThread::sActiveHeaderRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void LLMeshRepoThread::incActiveSkinRequests()
|
void LLMeshRepoThread::incActiveSkinRequests()
|
||||||
{
|
{
|
||||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
|
||||||
++LLMeshRepoThread::sActiveSkinRequests;
|
++LLMeshRepoThread::sActiveSkinRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void LLMeshRepoThread::decActiveSkinRequests()
|
void LLMeshRepoThread::decActiveSkinRequests()
|
||||||
{
|
{
|
||||||
LLMutexLock lock(gMeshRepo.mThread->mMutex);
|
|
||||||
--LLMeshRepoThread::sActiveSkinRequests;
|
--LLMeshRepoThread::sActiveSkinRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4665,13 +4659,20 @@ void LLMeshRepository::notifyLoadedMeshes()
|
||||||
{
|
{
|
||||||
LLMutexTrylock lock1(mMeshMutex);
|
LLMutexTrylock lock1(mMeshMutex);
|
||||||
LLMutexTrylock lock2(mThread->mMutex);
|
LLMutexTrylock lock2(mThread->mMutex);
|
||||||
|
LLMutexTrylock lock3(mThread->mHeaderMutex);
|
||||||
|
LLMutexTrylock lock4(mThread->mPendingMutex);
|
||||||
|
|
||||||
static U32 hold_offs(0);
|
static U32 hold_offs(0);
|
||||||
if (! lock1.isLocked() || ! lock2.isLocked())
|
if (! lock1.isLocked() || ! lock2.isLocked() || ! lock3.isLocked() || ! lock4.isLocked())
|
||||||
{
|
{
|
||||||
// If we can't get the locks, skip and pick this up later.
|
// If we can't get the locks, skip and pick this up later.
|
||||||
|
// Eventually thread queue will be free enough
|
||||||
++hold_offs;
|
++hold_offs;
|
||||||
sMaxLockHoldoffs = llmax(sMaxLockHoldoffs, hold_offs);
|
sMaxLockHoldoffs = llmax(sMaxLockHoldoffs, hold_offs);
|
||||||
|
if (hold_offs > 4)
|
||||||
|
{
|
||||||
|
LL_WARNS_ONCE() << "High mesh thread holdoff" << LL_ENDL;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hold_offs = 0;
|
hold_offs = 0;
|
||||||
|
|
@ -4732,6 +4733,7 @@ void LLMeshRepository::notifyLoadedMeshes()
|
||||||
|
|
||||||
if (mPendingRequests.size() > push_count)
|
if (mPendingRequests.size() > push_count)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_NAMED("Mesh score_map");
|
||||||
// More requests than the high-water limit allows so
|
// More requests than the high-water limit allows so
|
||||||
// sort and forward the most important.
|
// sort and forward the most important.
|
||||||
|
|
||||||
|
|
@ -4782,8 +4784,6 @@ void LLMeshRepository::notifyLoadedMeshes()
|
||||||
std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count,
|
std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count,
|
||||||
mPendingRequests.end(), PendingRequestBase::CompareScoreGreater());
|
mPendingRequests.end(), PendingRequestBase::CompareScoreGreater());
|
||||||
}
|
}
|
||||||
LLMutexTrylock lock3(mThread->mHeaderMutex);
|
|
||||||
LLMutexTrylock lock4(mThread->mPendingMutex);
|
|
||||||
while (!mPendingRequests.empty() && push_count > 0)
|
while (!mPendingRequests.empty() && push_count > 0)
|
||||||
{
|
{
|
||||||
std::unique_ptr<PendingRequestBase>& req_p = mPendingRequests.front();
|
std::unique_ptr<PendingRequestBase>& req_p = mPendingRequests.front();
|
||||||
|
|
@ -6238,13 +6238,20 @@ bool LLMeshRepository::meshUploadEnabled()
|
||||||
bool LLMeshRepository::meshRezEnabled()
|
bool LLMeshRepository::meshRezEnabled()
|
||||||
{
|
{
|
||||||
static LLCachedControl<bool> mesh_enabled(gSavedSettings, "MeshEnabled");
|
static LLCachedControl<bool> mesh_enabled(gSavedSettings, "MeshEnabled");
|
||||||
LLViewerRegion *region = gAgent.getRegion();
|
// <FS:Beq> FIRE-35602 etc - Mesh not appearing after TP/login (opensim only)
|
||||||
if(mesh_enabled &&
|
// For OpenSim there is still an outside chance that mesh rezzing is disabled on the sim/region
|
||||||
region)
|
// restore the old behaviour but keep the bias to mesh_enabled == true in the underlying checks.
|
||||||
|
#ifdef OPENSIM
|
||||||
|
if (LLGridManager::instance().isInOpenSim())
|
||||||
{
|
{
|
||||||
return region->meshRezEnabled();
|
if (LLViewerRegion* region = gAgent.getRegion(); mesh_enabled && region)
|
||||||
|
{
|
||||||
|
return region->meshRezEnabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
#endif // OPENSIM
|
||||||
|
// </FS:Beq>
|
||||||
|
return mesh_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Threading: main thread only
|
// Threading: main thread only
|
||||||
|
|
|
||||||
|
|
@ -1020,7 +1020,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
|
||||||
clearGLODGroup();
|
clearGLODGroup();
|
||||||
}
|
}
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
std::map<std::string, std::string> joint_alias_map;
|
std::map<std::string, std::string, std::less<>> joint_alias_map;
|
||||||
getJointAliases(joint_alias_map);
|
getJointAliases(joint_alias_map);
|
||||||
|
|
||||||
LLHandle<LLModelPreview> preview_handle = getHandle();
|
LLHandle<LLModelPreview> preview_handle = getHandle();
|
||||||
|
|
@ -4185,10 +4185,7 @@ LLJoint* LLModelPreview::lookupJointByName(const std::string& str, void* opaque)
|
||||||
LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
|
LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque);
|
||||||
if (pPreview)
|
if (pPreview)
|
||||||
{
|
{
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
return pPreview->getPreviewAvatar()->getJoint(str);
|
||||||
// return pPreview->getPreviewAvatar()->getJoint(str);
|
|
||||||
return pPreview->getPreviewAvatar()->getJoint( JointKey::construct( str ) );
|
|
||||||
// <FS:ND>
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,10 +131,7 @@ void LLMorphView::updateCamera()
|
||||||
{
|
{
|
||||||
if (!mCameraTargetJoint)
|
if (!mCameraTargetJoint)
|
||||||
{
|
{
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
setCameraTargetJoint( gAgentAvatarp->getJoint( "mHead" ) );
|
||||||
// setCameraTargetJoint( gAgentAvatarp->getJoint( "mHead" ) );
|
|
||||||
setCameraTargetJoint( gAgentAvatarp->getJoint( JointKey::construct( "mHead" ) ) );
|
|
||||||
// </FS:ND>
|
|
||||||
}
|
}
|
||||||
if (!isAgentAvatarValid()) return;
|
if (!isAgentAvatarValid()) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1316,15 +1316,11 @@ void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, bool show, bo
|
||||||
value_map_t sorted_params;
|
value_map_t sorted_params;
|
||||||
getSortedParams(sorted_params, edit_group);
|
getSortedParams(sorted_params, edit_group);
|
||||||
|
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
LLJoint* jointp = gAgentAvatarp->getJoint( subpart_entry->mTargetJoint );
|
||||||
//LLJoint* jointp = gAgentAvatarp->getJoint( subpart_entry->mTargetJoint );
|
|
||||||
LLJoint* jointp = gAgentAvatarp->getJoint( JointKey::construct( subpart_entry->mTargetJoint ) );
|
|
||||||
if (!jointp)
|
if (!jointp)
|
||||||
{
|
{
|
||||||
//jointp = gAgentAvatarp->getJoint( "mHead" );
|
jointp = gAgentAvatarp->getJoint( "mHead" );
|
||||||
jointp = gAgentAvatarp->getJoint( JointKey::construct( "mHead" ) );
|
|
||||||
}
|
}
|
||||||
// </FS:ND>
|
|
||||||
|
|
||||||
buildParamList(panel_list, sorted_params, tab, jointp);
|
buildParamList(panel_list, sorted_params, tab, jointp);
|
||||||
|
|
||||||
|
|
@ -1440,11 +1436,7 @@ void LLPanelEditWearable::changeCamera(U8 subpart)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the camera
|
// Update the camera
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) );
|
||||||
//gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( subpart_entry->mTargetJoint ) );
|
|
||||||
gMorphView->setCameraTargetJoint( gAgentAvatarp->getJoint( JointKey::construct( subpart_entry->mTargetJoint ) ) );
|
|
||||||
// </FS>ND>
|
|
||||||
|
|
||||||
gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset );
|
gMorphView->setCameraTargetOffset( subpart_entry->mTargetOffset );
|
||||||
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
|
gMorphView->setCameraOffset( subpart_entry->mCameraOffset );
|
||||||
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
|
if (gSavedSettings.getBOOL("AppearanceCameraMovement"))
|
||||||
|
|
|
||||||
|
|
@ -5540,6 +5540,11 @@ void LLPanelFace::changePrecision(S32 decimal_precision)
|
||||||
mBumpyRotate->setPrecision(decimal_precision);
|
mBumpyRotate->setPrecision(decimal_precision);
|
||||||
mShinyRotate->setPrecision(decimal_precision);
|
mShinyRotate->setPrecision(decimal_precision);
|
||||||
mTexRepeat->setPrecision(decimal_precision);
|
mTexRepeat->setPrecision(decimal_precision);
|
||||||
|
mPBRScaleU->setPrecision(decimal_precision);
|
||||||
|
mPBRScaleV->setPrecision(decimal_precision);
|
||||||
|
mPBRRotate->setPrecision(decimal_precision);
|
||||||
|
mPBROffsetU->setPrecision(decimal_precision);
|
||||||
|
mPBROffsetV->setPrecision(decimal_precision);
|
||||||
}
|
}
|
||||||
// </FS:CR>
|
// </FS:CR>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,9 @@ bool LLPanelOutfitsInventory::postBuild()
|
||||||
getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, false));
|
getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, false));
|
||||||
getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, true));
|
getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, true));
|
||||||
|
|
||||||
|
// <FS:Ansariel> FIRE-17626: Attachment count in appearance floater
|
||||||
|
mTempAttachmentUpdateTimer.start();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,6 +264,20 @@ void LLPanelOutfitsInventory::onSave()
|
||||||
}
|
}
|
||||||
|
|
||||||
// <FS:Ansariel> FIRE-17626: Attachment count in appearance floater
|
// <FS:Ansariel> FIRE-17626: Attachment count in appearance floater
|
||||||
|
void LLPanelOutfitsInventory::draw()
|
||||||
|
{
|
||||||
|
if (mTempAttachmentUpdateTimer.checkExpirationAndReset(1.f))
|
||||||
|
{
|
||||||
|
if (U32 tempAttachmentCount = (U32)LLAgentWearables::getTempAttachments().size(); tempAttachmentCount != mCurrentTempAttachmentCount)
|
||||||
|
{
|
||||||
|
mCurrentTempAttachmentCount = tempAttachmentCount;
|
||||||
|
onCOFChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LLPanel::draw();
|
||||||
|
}
|
||||||
|
|
||||||
void LLPanelOutfitsInventory::onCOFChanged()
|
void LLPanelOutfitsInventory::onCOFChanged()
|
||||||
{
|
{
|
||||||
if (!isAgentAvatarValid())
|
if (!isAgentAvatarValid())
|
||||||
|
|
@ -273,7 +290,7 @@ void LLPanelOutfitsInventory::onCOFChanged()
|
||||||
LLInventoryModel::cat_array_t cats;
|
LLInventoryModel::cat_array_t cats;
|
||||||
LLIsType is_of_type(LLAssetType::AT_OBJECT);
|
LLIsType is_of_type(LLAssetType::AT_OBJECT);
|
||||||
gInventory.collectDescendentsIf(cof, cats, obj_items, LLInventoryModel::EXCLUDE_TRASH, is_of_type);
|
gInventory.collectDescendentsIf(cof, cats, obj_items, LLInventoryModel::EXCLUDE_TRASH, is_of_type);
|
||||||
U32 attachments = static_cast<U32>(obj_items.size());
|
U32 attachments = static_cast<U32>(obj_items.size()) + mCurrentTempAttachmentCount;
|
||||||
|
|
||||||
LLStringUtil::format_map_t args;
|
LLStringUtil::format_map_t args;
|
||||||
args["COUNT"] = llformat("%d", attachments);
|
args["COUNT"] = llformat("%d", attachments);
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ public:
|
||||||
/*virtual*/ bool postBuild();
|
/*virtual*/ bool postBuild();
|
||||||
/*virtual*/ void onOpen(const LLSD& key);
|
/*virtual*/ void onOpen(const LLSD& key);
|
||||||
|
|
||||||
|
void draw(); // <FS:Ansariel> FIRE-17626: Attachment count in appearance floater
|
||||||
|
|
||||||
void onSearchEdit(const std::string& string);
|
void onSearchEdit(const std::string& string);
|
||||||
void onSave();
|
void onSave();
|
||||||
void saveOutfit(bool as_new = false);
|
void saveOutfit(bool as_new = false);
|
||||||
|
|
@ -91,6 +93,10 @@ private:
|
||||||
// <FS:Ansariel> FIRE-17626: Attachment count in appearance floater
|
// <FS:Ansariel> FIRE-17626: Attachment count in appearance floater
|
||||||
LLInventoryCategoriesObserver* mCategoriesObserver;
|
LLInventoryCategoriesObserver* mCategoriesObserver;
|
||||||
void onCOFChanged();
|
void onCOFChanged();
|
||||||
|
|
||||||
|
U32 mCurrentTempAttachmentCount{ 0 };
|
||||||
|
|
||||||
|
LLFrameTimer mTempAttachmentUpdateTimer;
|
||||||
// </FS:Ansariel>
|
// </FS:Ansariel>
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
|
#include "llfloatersnapshot.h" // FIXME: create a snapshot model
|
||||||
#include "llfloaterreg.h"
|
#include "llfloaterreg.h"
|
||||||
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
||||||
|
#include "fsfloaterprimfeed.h" // <FS:Beq> Share to Primfeed
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides several ways to save a snapshot.
|
* Provides several ways to save a snapshot.
|
||||||
|
|
@ -52,6 +53,7 @@ private:
|
||||||
void onSaveToInventory();
|
void onSaveToInventory();
|
||||||
void onSaveToComputer();
|
void onSaveToComputer();
|
||||||
void onSendToFlickr(); // <FS:Ansariel> Share to Flickr
|
void onSendToFlickr(); // <FS:Ansariel> Share to Flickr
|
||||||
|
void onSendToPrimfeed(); // <FS:Beq/> Share to Primfeed
|
||||||
|
|
||||||
LLFloaterSnapshotBase* mSnapshotFloater;
|
LLFloaterSnapshotBase* mSnapshotFloater;
|
||||||
};
|
};
|
||||||
|
|
@ -65,6 +67,7 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
|
||||||
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
|
mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this));
|
||||||
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
|
mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this));
|
||||||
mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this)); // <FS:Ansariel> Share to Flickr
|
mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this)); // <FS:Ansariel> Share to Flickr
|
||||||
|
mCommitCallbackRegistrar.add("Snapshot.SendToPrimfeed", boost::bind(&LLPanelSnapshotOptions::onSendToPrimfeed, this)); // <FS:Beq/> Share to Primfeed
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
|
|
@ -113,11 +116,23 @@ void LLPanelSnapshotOptions::onSendToFlickr()
|
||||||
{
|
{
|
||||||
LLFloaterReg::hideInstance("snapshot");
|
LLFloaterReg::hideInstance("snapshot");
|
||||||
|
|
||||||
LLFloaterFlickr* flickr_floater = dynamic_cast<LLFloaterFlickr*>(LLFloaterReg::getInstance("flickr"));
|
if (auto flickr_floater = LLFloaterReg::getTypedInstance<LLFloaterFlickr>("flickr"))
|
||||||
if (flickr_floater)
|
|
||||||
{
|
{
|
||||||
flickr_floater->showPhotoPanel();
|
flickr_floater->showPhotoPanel();
|
||||||
}
|
}
|
||||||
LLFloaterReg::showInstance("flickr");
|
LLFloaterReg::showInstance("flickr");
|
||||||
}
|
}
|
||||||
// </FS:Ansariel>
|
// </FS:Ansariel>
|
||||||
|
|
||||||
|
// <FS:Beq> Share to Primfeed
|
||||||
|
void LLPanelSnapshotOptions::onSendToPrimfeed()
|
||||||
|
{
|
||||||
|
LLFloaterReg::hideInstance("snapshot");
|
||||||
|
|
||||||
|
if (auto primfeed_floater = LLFloaterReg::getTypedInstance<FSFloaterPrimfeed>("primfeed"))
|
||||||
|
{
|
||||||
|
primfeed_floater->showPhotoPanel();
|
||||||
|
}
|
||||||
|
LLFloaterReg::showInstance("primfeed");
|
||||||
|
}
|
||||||
|
// </FS:Beq>
|
||||||
|
|
|
||||||
|
|
@ -538,17 +538,22 @@ void LLPresetsManager::loadPreset(const std::string& subdirectory, std::string n
|
||||||
{
|
{
|
||||||
gSavedSettings.setString("PresetGraphicActive", name);
|
gSavedSettings.setString("PresetGraphicActive", name);
|
||||||
|
|
||||||
|
// <FS> [FIRE-35390] Old viewer presets have these as true and 0.7, whereas the equivalent on modern viewers is false and 1.0
|
||||||
|
if (auto control = gSavedSettings.getControl("RenderSkyAutoAdjustLegacy"))
|
||||||
|
control->resetToDefault(true);
|
||||||
|
if (auto control = gSavedSettings.getControl("RenderSkyAmbientScale"))
|
||||||
|
control->resetToDefault(true);
|
||||||
|
// </FS>
|
||||||
|
|
||||||
// <FS:Ansariel> Update indirect controls
|
// <FS:Ansariel> Update indirect controls
|
||||||
LLAvatarComplexityControls::setIndirectControls();
|
LLAvatarComplexityControls::setIndirectControls();
|
||||||
|
|
||||||
LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
|
if (LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"))
|
||||||
if (instance)
|
|
||||||
{
|
{
|
||||||
instance->refreshEnabledGraphics();
|
instance->refreshEnabledGraphics();
|
||||||
}
|
}
|
||||||
// <FS:Ansariel> Graphic preset controls independent from XUI
|
// <FS:Ansariel> Graphic preset controls independent from XUI
|
||||||
FloaterQuickPrefs* phototools = LLFloaterReg::findTypedInstance<FloaterQuickPrefs>(PHOTOTOOLS_FLOATER);
|
if (FloaterQuickPrefs* phototools = LLFloaterReg::findTypedInstance<FloaterQuickPrefs>(PHOTOTOOLS_FLOATER))
|
||||||
if (phototools)
|
|
||||||
{
|
{
|
||||||
phototools->refreshSettings();
|
phototools->refreshSettings();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7970,19 +7970,20 @@ bool LLSelectMgr::canSelectObject(LLViewerObject* object, bool ignore_select_own
|
||||||
// only select my own objects
|
// only select my own objects
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <FS:Ansariel> FIRE-14593: Option to select only copyable objects
|
||||||
|
if (!object->permCopy() && gSavedSettings.getBOOL("FSSelectCopyableOnly"))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// </FS:Ansariel>
|
||||||
|
// <FS:Ansariel> FIRE-17696: Option to select only locked objects
|
||||||
|
if (gSavedSettings.getBOOL("FSSelectLockedOnly") && object->permMove() && !object->isPermanentEnforced())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// </FS:Ansariel>// Can't select objects that are not owned by you or group
|
||||||
}
|
}
|
||||||
// <FS:Ansariel> FIRE-14593: Option to select only copyable objects
|
|
||||||
if (!object->permCopy() && gSavedSettings.getBOOL("FSSelectCopyableOnly"))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// </FS:Ansariel>
|
|
||||||
// <FS:Ansariel> FIRE-17696: Option to select only locked objects
|
|
||||||
if (gSavedSettings.getBOOL("FSSelectLockedOnly") && object->permMove() && !object->isPermanentEnforced())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// </FS:Ansariel>
|
|
||||||
|
|
||||||
// Can't select orphans
|
// Can't select orphans
|
||||||
if (object->isOrphaned()) return false;
|
if (object->isOrphaned()) return false;
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,7 @@ void dump_avatar_and_skin_state(const std::string& reason, LLVOAvatar *avatar, c
|
||||||
{
|
{
|
||||||
LL_WARNS("Avatar") << "skin joint idx " << j << " name [" << skin->mJointNames[j]
|
LL_WARNS("Avatar") << "skin joint idx " << j << " name [" << skin->mJointNames[j]
|
||||||
<< "] num " << skin->mJointNums[j] << LL_ENDL;
|
<< "] num " << skin->mJointNums[j] << LL_ENDL;
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
const std::string& name = skin->mJointNames[j];
|
||||||
//const std::string& name = skin->mJointNames[j];
|
|
||||||
const std::string& name = skin->mJointNames[j].mName;
|
|
||||||
// </FS:ND>
|
|
||||||
S32 joint_num = skin->mJointNums[j];
|
S32 joint_num = skin->mJointNums[j];
|
||||||
|
|
||||||
LLJoint *name_joint = avatar->getJoint(name);
|
LLJoint *name_joint = avatar->getJoint(name);
|
||||||
|
|
@ -119,14 +116,9 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin
|
||||||
// needed for handling of any legacy bad data.
|
// needed for handling of any legacy bad data.
|
||||||
if (!avatar->getJoint(skin->mJointNames[j]))
|
if (!avatar->getJoint(skin->mJointNames[j]))
|
||||||
{
|
{
|
||||||
//<FS:ND> Query by JointKey rather than just a string, the key can be a U32 index for faster lookup
|
LL_DEBUGS("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint " << skin->mJointNames[j] << LL_ENDL;
|
||||||
//LL_DEBUGS("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint " << skin->mJointNames[j] << LL_ENDL;
|
LL_WARNS_ONCE("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL;
|
||||||
//LL_WARNS_ONCE("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL;
|
skin->mJointNames[j] = "mPelvis";
|
||||||
//skin->mJointNames[j] = "mPelvis";
|
|
||||||
LL_DEBUGS("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint " << skin->mJointNames[j].mName << LL_ENDL;
|
|
||||||
LL_WARNS_ONCE("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint" << skin->mJointNames[j].mName << LL_ENDL;
|
|
||||||
skin->mJointNames[j] = JointKey::construct("mPelvis");
|
|
||||||
//</FS:ND>
|
|
||||||
skin->mJointNumsInitialized = false; // force update after names change.
|
skin->mJointNumsInitialized = false; // force update after names change.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
#include "llfloaterperms.h"
|
#include "llfloaterperms.h"
|
||||||
#include "llfloaterreg.h"
|
#include "llfloaterreg.h"
|
||||||
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
#include "llfloaterflickr.h" // <FS:Ansariel> Share to Flickr
|
||||||
|
#include "fsfloaterprimfeed.h" // <FS:Beq> Share to Primfeed
|
||||||
#include "llimagefilter.h"
|
#include "llimagefilter.h"
|
||||||
#include "llimagefiltersmanager.h"
|
#include "llimagefiltersmanager.h"
|
||||||
#include "llimagebmp.h"
|
#include "llimagebmp.h"
|
||||||
|
|
|
||||||
|
|
@ -1950,9 +1950,9 @@ bool idle_startup()
|
||||||
// <FS:Ansariel> Wait for notification confirmation
|
// <FS:Ansariel> Wait for notification confirmation
|
||||||
if (STATE_LOGIN_CONFIRM_NOTIFICATON == LLStartUp::getStartupState())
|
if (STATE_LOGIN_CONFIRM_NOTIFICATON == LLStartUp::getStartupState())
|
||||||
{
|
{
|
||||||
display_startup();
|
do_startup_frame();
|
||||||
gViewerWindow->getProgressView()->setVisible(false);
|
gViewerWindow->getProgressView()->setVisible(false);
|
||||||
display_startup();
|
do_startup_frame();
|
||||||
ms_sleep(1);
|
ms_sleep(1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -2298,10 +2298,10 @@ bool idle_startup()
|
||||||
//so I just moved nearby history loading a few states further
|
//so I just moved nearby history loading a few states further
|
||||||
if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
|
if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
|
||||||
{
|
{
|
||||||
FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance();
|
if (FSFloaterNearbyChat* nearby_chat = FSFloaterNearbyChat::getInstance())
|
||||||
if (nearby_chat) nearby_chat->loadHistory();
|
nearby_chat->loadHistory();
|
||||||
}
|
}
|
||||||
display_startup();
|
do_startup_frame();
|
||||||
// </FS:Ansariel> [FS communication UI]
|
// </FS:Ansariel> [FS communication UI]
|
||||||
|
|
||||||
// <FS:KC> FIRE-18250: Option to disable default eye movement
|
// <FS:KC> FIRE-18250: Option to disable default eye movement
|
||||||
|
|
@ -2549,13 +2549,14 @@ bool idle_startup()
|
||||||
LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
|
LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
|
||||||
LLStatusBar::sendMoneyBalanceRequest();
|
LLStatusBar::sendMoneyBalanceRequest();
|
||||||
|
|
||||||
do_startup_frame();
|
|
||||||
// <FS:Ansariel> Moved before inventory creation.
|
// <FS:Ansariel> Moved before inventory creation.
|
||||||
// request all group information
|
// request all group information
|
||||||
LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Requesting Agent Data during startup" << LL_ENDL;
|
LL_INFOS("Agent_GroupData") << "GROUPDEBUG: Requesting Agent Data during startup" << LL_ENDL;
|
||||||
gAgent.sendAgentDataUpdateRequest();
|
gAgent.sendAgentDataUpdateRequest();
|
||||||
display_startup();
|
|
||||||
// </FS:Ansariel>
|
// </FS:Ansariel>
|
||||||
|
|
||||||
|
do_startup_frame();
|
||||||
|
|
||||||
// Inform simulator of our language preference
|
// Inform simulator of our language preference
|
||||||
LLAgentLanguage::update();
|
LLAgentLanguage::update();
|
||||||
|
|
||||||
|
|
@ -2808,7 +2809,7 @@ bool idle_startup()
|
||||||
// Create the inventory views
|
// Create the inventory views
|
||||||
LL_INFOS() << "Creating Inventory Views" << LL_ENDL;
|
LL_INFOS() << "Creating Inventory Views" << LL_ENDL;
|
||||||
LLFloaterReg::getInstance("inventory");
|
LLFloaterReg::getInstance("inventory");
|
||||||
//do_startup_frame();
|
do_startup_frame();
|
||||||
|
|
||||||
// [RLVa:KB] - Checked: RLVa-1.1.0
|
// [RLVa:KB] - Checked: RLVa-1.1.0
|
||||||
if (RlvHandler::isEnabled())
|
if (RlvHandler::isEnabled())
|
||||||
|
|
@ -2898,7 +2899,7 @@ bool idle_startup()
|
||||||
//ok, we're done, set it back to false.
|
//ok, we're done, set it back to false.
|
||||||
gSavedSettings.setBOOL("FSFirstRunAfterSettingsRestore", false);
|
gSavedSettings.setBOOL("FSFirstRunAfterSettingsRestore", false);
|
||||||
}
|
}
|
||||||
display_startup();
|
do_startup_frame();
|
||||||
// </FS:CR>
|
// </FS:CR>
|
||||||
|
|
||||||
if (gSavedSettings.getBOOL("HelpFloaterOpen"))
|
if (gSavedSettings.getBOOL("HelpFloaterOpen"))
|
||||||
|
|
@ -3074,7 +3075,7 @@ bool idle_startup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // OPENSIM
|
#endif // OPENSIM
|
||||||
display_startup();
|
do_startup_frame();
|
||||||
// </FS:CR>
|
// </FS:CR>
|
||||||
|
|
||||||
LLStartUp::setStartupState( STATE_PRECACHE );
|
LLStartUp::setStartupState( STATE_PRECACHE );
|
||||||
|
|
@ -4972,24 +4973,7 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
|
||||||
LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);
|
LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only save mfa_hash for future logins if the user wants their info remembered.
|
LLLoginInstance::getInstance()->saveMFAHash(response);
|
||||||
if(response.has("mfa_hash")
|
|
||||||
&& gSavedSettings.getBOOL("RememberUser")
|
|
||||||
&& LLLoginInstance::getInstance()->saveMFA())
|
|
||||||
{
|
|
||||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
|
||||||
std::string user_id(gUserCredential->userID());
|
|
||||||
gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]);
|
|
||||||
// TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically
|
|
||||||
gSecAPIHandler->syncProtectedMap();
|
|
||||||
}
|
|
||||||
else if (!LLLoginInstance::getInstance()->saveMFA())
|
|
||||||
{
|
|
||||||
std::string grid(LLGridManager::getInstance()->getGridId());
|
|
||||||
std::string user_id(gUserCredential->userID());
|
|
||||||
gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id);
|
|
||||||
gSecAPIHandler->syncProtectedMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// <FS:Ansariel> OpenSim legacy economy support
|
// <FS:Ansariel> OpenSim legacy economy support
|
||||||
#ifdef OPENSIM
|
#ifdef OPENSIM
|
||||||
|
|
@ -5092,6 +5076,7 @@ bool process_login_success_response(U32 &first_sim_size_x, U32 &first_sim_size_y
|
||||||
}
|
}
|
||||||
// </FS:Techwolf Lupindo>
|
// </FS:Techwolf Lupindo>
|
||||||
|
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
// JC: gesture loading done below, when we have an asset system
|
// JC: gesture loading done below, when we have an asset system
|
||||||
// in place. Don't delete/clear gUserCredentials until then.
|
// in place. Don't delete/clear gUserCredentials until then.
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,10 @@
|
||||||
#include "llavatarname.h"
|
#include "llavatarname.h"
|
||||||
#include "llavatarnamecache.h"
|
#include "llavatarnamecache.h"
|
||||||
|
|
||||||
|
#include "llviewernetwork.h" // <FS/> Access to GridManager
|
||||||
|
#include "lfsimfeaturehandler.h" // <FS/> Access to hyperGridURL
|
||||||
|
#include "llworldmapmessage.h" // <FS/> Access to sendNamedRegionRequest
|
||||||
|
|
||||||
// [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b)
|
// [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b)
|
||||||
#include "rlvhandler.h"
|
#include "rlvhandler.h"
|
||||||
// [/RLVa:KB]
|
// [/RLVa:KB]
|
||||||
|
|
@ -98,6 +102,46 @@ void LLTeleportHistory::goToItem(int idx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <FS> [FIRE-35355] OpenSim global position is dependent on the Grid you are on
|
||||||
|
#ifdef OPENSIM
|
||||||
|
if (LLGridManager::getInstance()->isInOpenSim())
|
||||||
|
{
|
||||||
|
if (mItems[mCurrentItem].mRegionID != mItems[idx].mRegionID)
|
||||||
|
{
|
||||||
|
LLSLURL slurl = mItems[idx].mSLURL;
|
||||||
|
std::string grid = slurl.getGrid();
|
||||||
|
std::string current_grid = LFSimFeatureHandler::instance().hyperGridURL();
|
||||||
|
std::string gatekeeper = LLGridManager::getInstance()->getGatekeeper(grid);
|
||||||
|
|
||||||
|
// Requesting region information from the server is only required when changing grid
|
||||||
|
if (slurl.isValid() && grid != current_grid)
|
||||||
|
{
|
||||||
|
if (!gatekeeper.empty())
|
||||||
|
{
|
||||||
|
slurl = LLSLURL(gatekeeper + ":" + slurl.getRegion(), slurl.getPosition(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mRequestedItem != -1)
|
||||||
|
{
|
||||||
|
return; // We already have a request in progress and don't want to spam the server
|
||||||
|
}
|
||||||
|
|
||||||
|
mRequestedItem = idx;
|
||||||
|
|
||||||
|
LLWorldMapMessage::getInstance()->sendNamedRegionRequest(
|
||||||
|
slurl.getRegion(),
|
||||||
|
boost::bind(&LLTeleportHistory::regionNameCallback, this, idx, _1, _2, _3, _4),
|
||||||
|
slurl.getSLURLString(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
return; // The teleport will occur in the callback with the correct global position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// </FS>
|
||||||
|
|
||||||
// Attempt to teleport to the requested item.
|
// Attempt to teleport to the requested item.
|
||||||
gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
|
gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
|
||||||
mRequestedItem = idx;
|
mRequestedItem = idx;
|
||||||
|
|
@ -210,6 +254,22 @@ void LLTeleportHistory::updateCurrentLocation(const LLVector3d& new_pos)
|
||||||
mItems[mCurrentItem] = LLTeleportHistoryItem(RlvStrings::getString(RlvStringKeys::Hidden::Parcel), LLVector3d::zero);
|
mItems[mCurrentItem] = LLTeleportHistoryItem(RlvStrings::getString(RlvStringKeys::Hidden::Parcel), LLVector3d::zero);
|
||||||
}
|
}
|
||||||
// [/RLVa:KB]
|
// [/RLVa:KB]
|
||||||
|
|
||||||
|
// <FS> [FIRE-35355] OpenSim global position is dependent on the Grid you are on,
|
||||||
|
// so we need to store the slurl so we can request the global position later
|
||||||
|
#ifdef OPENSIM
|
||||||
|
if (LLGridManager::getInstance()->isInOpenSim())
|
||||||
|
{
|
||||||
|
auto regionp = gAgent.getRegion();
|
||||||
|
if (regionp)
|
||||||
|
{
|
||||||
|
LLVector3 new_pos_local = gAgent.getPosAgentFromGlobal(new_pos);
|
||||||
|
LLSLURL slurl = LLSLURL(LFSimFeatureHandler::instance().hyperGridURL(), regionp->getName(), new_pos_local);
|
||||||
|
mItems[mCurrentItem].mSLURL = slurl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// </FS>
|
||||||
}
|
}
|
||||||
|
|
||||||
//dump(); // LO - removing the dump from happening every time we TP.
|
//dump(); // LO - removing the dump from happening every time we TP.
|
||||||
|
|
@ -287,3 +347,35 @@ void LLTeleportHistory::dump() const
|
||||||
LL_INFOS() << line.str() << LL_ENDL;
|
LL_INFOS() << line.str() << LL_ENDL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <FS> [FIRE-35355] Callback for OpenSim so we can teleport to the correct global position on another grid
|
||||||
|
void LLTeleportHistory::regionNameCallback(int idx, U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
|
||||||
|
{
|
||||||
|
if (region_handle)
|
||||||
|
{
|
||||||
|
// Sanity checks again just in case since time has passed since the request was made
|
||||||
|
if (idx < 0 || idx >= (int)mItems.size())
|
||||||
|
{
|
||||||
|
LL_WARNS() << "Invalid teleport history index (" << idx << ") specified" << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx == mCurrentItem)
|
||||||
|
{
|
||||||
|
LL_WARNS() << "Will not teleport to the same location." << LL_ENDL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVector3d origin_pos = from_region_handle(region_handle);
|
||||||
|
LLVector3d global_pos(origin_pos + LLVector3d(slurl.getPosition()));
|
||||||
|
|
||||||
|
// Attempt to teleport to the target grids region
|
||||||
|
gAgent.teleportViaLocation(global_pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LL_WARNS() << "Invalid teleport history region handle" << LL_ENDL;
|
||||||
|
onTeleportFailed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// </FS>
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
#include <boost/signals2.hpp>
|
#include <boost/signals2.hpp>
|
||||||
#include "llteleporthistorystorage.h"
|
#include "llteleporthistorystorage.h"
|
||||||
|
|
||||||
|
#include "llslurl.h" // <FS/> Access to LLSLURL
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An item of the teleport history.
|
* An item of the teleport history.
|
||||||
|
|
@ -47,8 +49,11 @@ public:
|
||||||
LLTeleportHistoryItem()
|
LLTeleportHistoryItem()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
LLTeleportHistoryItem(std::string title, LLVector3d global_pos)
|
// <FS> [FIRE-35355] OpenSim requires knowing the grid to teleport correctly if changing grids
|
||||||
: mTitle(title), mGlobalPos(global_pos)
|
//LLTeleportHistoryItem(std::string title, LLVector3d global_pos)
|
||||||
|
// : mTitle(title), mGlobalPos(global_pos)
|
||||||
|
LLTeleportHistoryItem(std::string title, LLVector3d global_pos, const LLSLURL& slurl = LLSLURL())
|
||||||
|
: mTitle(title), mGlobalPos(global_pos), mSLURL(slurl)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -61,6 +66,7 @@ public:
|
||||||
std::string mFullTitle; // human-readable location title including coordinates
|
std::string mFullTitle; // human-readable location title including coordinates
|
||||||
LLVector3d mGlobalPos; // global position
|
LLVector3d mGlobalPos; // global position
|
||||||
LLUUID mRegionID; // region ID for getting the region info
|
LLUUID mRegionID; // region ID for getting the region info
|
||||||
|
LLSLURL mSLURL; // <FS/> [FIRE-35355] slurl for the location required for OpenSim
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -180,6 +186,10 @@ private:
|
||||||
*/
|
*/
|
||||||
static std::string getCurrentLocationTitle(bool full, const LLVector3& local_pos_override);
|
static std::string getCurrentLocationTitle(bool full, const LLVector3& local_pos_override);
|
||||||
|
|
||||||
|
// <FS> [FIRE-35355] Callback for OpenSim so we can teleport to the correct global position on another grid
|
||||||
|
void regionNameCallback(int idx, U64 handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport);
|
||||||
|
// </FS>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually, the teleport history.
|
* Actually, the teleport history.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -2089,12 +2089,14 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
|
||||||
// So a 1024x1024 texture with a dicard of 6 will become 32x32 and a 2048x2048 texture with a discard of 7 will become a 64x64 texture.
|
// So a 1024x1024 texture with a dicard of 6 will become 32x32 and a 2048x2048 texture with a discard of 7 will become a 64x64 texture.
|
||||||
if (discardlevel > MAX_DISCARD_LEVEL)
|
if (discardlevel > MAX_DISCARD_LEVEL)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("FixBadDiscardLevel");
|
||||||
|
|
||||||
S32 w = head[0]; // Get the current width from the header (16)
|
S32 w = head[0]; // Get the current width from the header (16)
|
||||||
S32 h = head[1]; // Get the current height from the header (16)
|
S32 h = head[1]; // Get the current height from the header (16)
|
||||||
|
|
||||||
// Expand the width and height by teh difference between the discard and MAX_DISCARD_LEVEL bit shifted to the left. (Expand power of 2 textures)
|
// Expand the width and height by teh difference between the discard and MAX_DISCARD_LEVEL bit shifted to the left. (Expand power of 2 textures)
|
||||||
w <<= MAX_DISCARD_LEVEL - discardlevel;
|
w <<= discardlevel - MAX_DISCARD_LEVEL;
|
||||||
h <<= MAX_DISCARD_LEVEL - discardlevel;
|
h <<= discardlevel - MAX_DISCARD_LEVEL;
|
||||||
|
|
||||||
// Set the discard level to the MAX_DISCARD_LEVEL
|
// Set the discard level to the MAX_DISCARD_LEVEL
|
||||||
discardlevel = MAX_DISCARD_LEVEL;
|
discardlevel = MAX_DISCARD_LEVEL;
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,7 @@ LLVersionInfo::FSViewerMaturity LLVersionInfo::getFSViewerMaturity() const
|
||||||
static const boost::regex is_alpha_channel("\\bAlpha(x64)?\\b");
|
static const boost::regex is_alpha_channel("\\bAlpha(x64)?\\b");
|
||||||
static const boost::regex is_release_channel("\\bRelease(x64)?\\b");
|
static const boost::regex is_release_channel("\\bRelease(x64)?\\b");
|
||||||
static const boost::regex is_nightly_channel("\\bNightly(x64)?\\b");
|
static const boost::regex is_nightly_channel("\\bNightly(x64)?\\b");
|
||||||
|
static const boost::regex is_streaming_channel("\\bStreaming\\b");
|
||||||
|
|
||||||
if (ll_regex_search(channel, is_release_channel))
|
if (ll_regex_search(channel, is_release_channel))
|
||||||
{
|
{
|
||||||
|
|
@ -245,6 +246,10 @@ LLVersionInfo::FSViewerMaturity LLVersionInfo::getFSViewerMaturity() const
|
||||||
{
|
{
|
||||||
maturity = FSViewerMaturity::NIGHTLY_VIEWER;
|
maturity = FSViewerMaturity::NIGHTLY_VIEWER;
|
||||||
}
|
}
|
||||||
|
else if (ll_regex_search(channel, is_streaming_channel))
|
||||||
|
{
|
||||||
|
maturity = FSViewerMaturity::STREAMING_VIEWER;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
maturity = FSViewerMaturity::UNOFFICIAL_VIEWER;
|
maturity = FSViewerMaturity::UNOFFICIAL_VIEWER;
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ public:
|
||||||
BETA_VIEWER,
|
BETA_VIEWER,
|
||||||
NIGHTLY_VIEWER,
|
NIGHTLY_VIEWER,
|
||||||
RELEASE_VIEWER,
|
RELEASE_VIEWER,
|
||||||
|
STREAMING_VIEWER,
|
||||||
};
|
};
|
||||||
FSViewerMaturity getFSViewerMaturity() const;
|
FSViewerMaturity getFSViewerMaturity() const;
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,7 @@
|
||||||
#include "lggbeamcolormapfloater.h"
|
#include "lggbeamcolormapfloater.h"
|
||||||
#include "lggbeammapfloater.h"
|
#include "lggbeammapfloater.h"
|
||||||
#include "llfloaterdisplayname.h"
|
#include "llfloaterdisplayname.h"
|
||||||
|
#include "fsfloaterprimfeed.h"
|
||||||
#include "llfloaterflickr.h"
|
#include "llfloaterflickr.h"
|
||||||
#include "llfloaterscriptrecover.h"
|
#include "llfloaterscriptrecover.h"
|
||||||
#include "llfloatersearchreplace.h"
|
#include "llfloatersearchreplace.h"
|
||||||
|
|
@ -630,6 +631,7 @@ void LLViewerFloaterReg::registerFloaters()
|
||||||
LLFloaterReg::add("export_collada", "floater_export_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ColladaExportFloater>);
|
LLFloaterReg::add("export_collada", "floater_export_collada.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<ColladaExportFloater>);
|
||||||
LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>);
|
LLFloaterReg::add("delete_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeleteQueue>);
|
||||||
LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
|
LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>);
|
||||||
|
LLFloaterReg::add("primfeed", "floater_primfeed.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterPrimfeed>);
|
||||||
LLFloaterReg::add("fs_asset_blacklist", "floater_fs_asset_blacklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAssetBlacklist>);
|
LLFloaterReg::add("fs_asset_blacklist", "floater_fs_asset_blacklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAssetBlacklist>);
|
||||||
LLFloaterReg::add("fs_avatar_render_settings", "floater_fs_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAvatarRenderSettings>);
|
LLFloaterReg::add("fs_avatar_render_settings", "floater_fs_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterAvatarRenderSettings>);
|
||||||
LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterBlocklist>);
|
LLFloaterReg::add("fs_blocklist", "floater_fs_blocklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<FSFloaterBlocklist>);
|
||||||
|
|
|
||||||
|
|
@ -2757,6 +2757,28 @@ class LLAdvancedCompressFileTest : public view_listener_t
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// <FS:Beq> Primfeed integration test functions (can be removed when the feature is stable)
|
||||||
|
///////////////////
|
||||||
|
// PRIMFEED AUTH //
|
||||||
|
///////////////////
|
||||||
|
#include "fsprimfeedauth.h"
|
||||||
|
class LLAdvancedPrimfeedAuth : public view_listener_t
|
||||||
|
{
|
||||||
|
bool handleEvent(const LLSD& userdata)
|
||||||
|
{
|
||||||
|
FSPrimfeedAuth::initiateAuthRequest();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class LLAdvancedPrimfeedAuthReset : public view_listener_t
|
||||||
|
{
|
||||||
|
bool handleEvent(const LLSD& userdata)
|
||||||
|
{
|
||||||
|
FSPrimfeedAuth::resetAuthStatus();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// </FS:Beq>
|
||||||
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
// SHOW DEBUG SETTINGS //
|
// SHOW DEBUG SETTINGS //
|
||||||
|
|
@ -11882,6 +11904,19 @@ class LLWorldEnvSettings : public view_listener_t
|
||||||
#endif
|
#endif
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
|
|
||||||
|
// <FS:Darl> Redundant environment toggles revert to shared environment
|
||||||
|
LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL);
|
||||||
|
LLUUID skyid = (sky) ? sky->getAssetId() : LLUUID::null;
|
||||||
|
bool repeatedEnvTogglesShared = gSavedSettings.getBOOL("FSRepeatedEnvTogglesShared");
|
||||||
|
|
||||||
|
if(repeatedEnvTogglesShared && ((skyid == LLEnvironment::KNOWN_SKY_SUNRISE && event_name == "sunrise") ||
|
||||||
|
(skyid == LLEnvironment::KNOWN_SKY_MIDDAY && event_name == "noon") ||
|
||||||
|
(skyid == LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY && event_name == "legacy noon") ||
|
||||||
|
(skyid == LLEnvironment::KNOWN_SKY_SUNSET && event_name == "sunset") ||
|
||||||
|
(skyid == LLEnvironment::KNOWN_SKY_MIDNIGHT && event_name == "midnight")))
|
||||||
|
event_name = "region";
|
||||||
|
// </FS:Darl>
|
||||||
|
|
||||||
if (event_name == "sunrise")
|
if (event_name == "sunrise")
|
||||||
{
|
{
|
||||||
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
|
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
|
||||||
|
|
@ -12906,6 +12941,8 @@ void initialize_menus()
|
||||||
view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
|
view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
|
||||||
view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
|
view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
|
||||||
view_listener_t::addMenu(new LLAdvancedCompressFileTest(), "Advanced.CompressFileTest");
|
view_listener_t::addMenu(new LLAdvancedCompressFileTest(), "Advanced.CompressFileTest");
|
||||||
|
view_listener_t::addMenu(new LLAdvancedPrimfeedAuth(), "Advanced.PrimfeedAuth");
|
||||||
|
view_listener_t::addMenu(new LLAdvancedPrimfeedAuthReset(), "Advanced.PrimfeedAuthReset");
|
||||||
view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
|
view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
|
||||||
view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
|
view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
|
||||||
view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
|
view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
|
||||||
|
|
|
||||||
|
|
@ -6687,6 +6687,7 @@ void process_alert_core(const std::string& message, bool modal)
|
||||||
if (text.substr(0, restart_cancelled.length()) == restart_cancelled)
|
if (text.substr(0, restart_cancelled.length()) == restart_cancelled)
|
||||||
{
|
{
|
||||||
LLFloaterRegionRestarting::close();
|
LLFloaterRegionRestarting::close();
|
||||||
|
fs_report_region_restart_to_channel(-1); // <FS:Darl> Announce region restart to a defined chat channel
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string new_msg =LLNotifications::instance().getGlobalString(text);
|
std::string new_msg =LLNotifications::instance().getGlobalString(text);
|
||||||
|
|
@ -8755,7 +8756,14 @@ void fs_report_region_restart_to_channel(S32 seconds)
|
||||||
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||||
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
||||||
msg->nextBlockFast(_PREHASH_ChatData);
|
msg->nextBlockFast(_PREHASH_ChatData);
|
||||||
msg->addStringFast(_PREHASH_Message, "region_restart_in:" + llformat("%d", seconds));
|
if(seconds >= 0)
|
||||||
|
{
|
||||||
|
msg->addStringFast(_PREHASH_Message, "region_restart_in:" + llformat("%d", seconds));
|
||||||
|
}
|
||||||
|
else // Input is a negative number
|
||||||
|
{
|
||||||
|
msg->addStringFast(_PREHASH_Message, "region_restart_cancelled");
|
||||||
|
}
|
||||||
msg->addU8Fast(_PREHASH_Type, CHAT_TYPE_WHISPER);
|
msg->addU8Fast(_PREHASH_Type, CHAT_TYPE_WHISPER);
|
||||||
msg->addS32("Channel", channel);
|
msg->addS32("Channel", channel);
|
||||||
gAgent.sendReliableMessage();
|
gAgent.sendReliableMessage();
|
||||||
|
|
|
||||||
|
|
@ -835,7 +835,7 @@ void LLViewerObjectList::setAllObjectDefaultTextures(U32 nChannel, bool fShowDef
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// [/SL:KB]
|
// [/SL:KB]
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
//void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
|
//void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
|
||||||
// Added time limit on processing of objects as they affect the texture system (They also calcuate mMaxVirtualSize and mPixelArea)
|
// Added time limit on processing of objects as they affect the texture system (They also calcuate mMaxVirtualSize and mPixelArea)
|
||||||
void LLViewerObjectList::updateApparentAngles(LLAgent &agent, F32 max_time)
|
void LLViewerObjectList::updateApparentAngles(LLAgent &agent, F32 max_time)
|
||||||
|
|
@ -845,7 +845,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent, F32 max_time)
|
||||||
LLViewerObject *objectp;
|
LLViewerObject *objectp;
|
||||||
|
|
||||||
S32 num_updates, max_value;
|
S32 num_updates, max_value;
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
// Remove the old code as it worked on fixed number of updates (Total # of Object / 128) per frame
|
// Remove the old code as it worked on fixed number of updates (Total # of Object / 128) per frame
|
||||||
// and some objects had nothing to do while others were avatars or volumes and could t
|
// and some objects had nothing to do while others were avatars or volumes and could t
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ public:
|
||||||
void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool compressed=false);
|
void processObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type, bool compressed=false);
|
||||||
void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
|
void processCompressedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
|
||||||
void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
|
void processCachedObjectUpdate(LLMessageSystem *mesgsys, void **user_data, EObjectUpdateType update_type);
|
||||||
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings, not happening with SL Viewer
|
// <FS:minerjr> [FIRE-35081] Blurry prims not changing with graphics settings
|
||||||
//void updateApparentAngles(LLAgent &agent);
|
//void updateApparentAngles(LLAgent &agent);
|
||||||
// Added time limit on processing of objects as they affect the texture system
|
// Added time limit on processing of objects as they affect the texture system
|
||||||
void updateApparentAngles(LLAgent &agent, F32 max_time);
|
void updateApparentAngles(LLAgent &agent, F32 max_time);
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ namespace
|
||||||
|
|
||||||
void newRegionEntry(LLViewerRegion& region)
|
void newRegionEntry(LLViewerRegion& region)
|
||||||
{
|
{
|
||||||
|
LL_PROFILE_ZONE_SCOPED; // <FS:Beq/> improve instrumentation
|
||||||
LL_INFOS("LLViewerRegion") << "Entering region [" << region.getName() << "]" << LL_ENDL;
|
LL_INFOS("LLViewerRegion") << "Entering region [" << region.getName() << "]" << LL_ENDL;
|
||||||
gDebugInfo["CurrentRegion"] = region.getName();
|
gDebugInfo["CurrentRegion"] = region.getName();
|
||||||
LLAppViewer::instance()->writeDebugInfo();
|
LLAppViewer::instance()->writeDebugInfo();
|
||||||
|
|
@ -3983,11 +3984,14 @@ bool LLViewerRegion::bakesOnMeshEnabled() const
|
||||||
mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean());
|
mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <FS:Beq> FIRE-35602 etc - Mesh not appearing after TP/login (opensim only)
|
||||||
|
#ifdef OPENSIM
|
||||||
bool LLViewerRegion::meshRezEnabled() const
|
bool LLViewerRegion::meshRezEnabled() const
|
||||||
{
|
{
|
||||||
return (mSimulatorFeatures.has("MeshRezEnabled") &&
|
return (mSimulatorFeatures.has("MeshRezEnabled") && mSimulatorFeatures["MeshRezEnabled"].asBoolean());
|
||||||
mSimulatorFeatures["MeshRezEnabled"].asBoolean());
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
// </FS:Beq>
|
||||||
|
|
||||||
bool LLViewerRegion::dynamicPathfindingEnabled() const
|
bool LLViewerRegion::dynamicPathfindingEnabled() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue