diff --git a/autobuild.xml b/autobuild.xml index abe87be495..1a30613d64 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -22,16 +22,16 @@ archive hash - db1a758da143fe0177df2b472eaa8d78 + ba107bef7cdb9c8548d62e749d9af6fd url - http://3p.firestormviewer.org/SDL2-2.0.20-linux64-222610218.tar.bz2 + http://3p.firestormviewer.org/SDL2-2.24.1-linux64-222872152.tar.bz2 name linux64 version - 2.0.20 + 2.24.1 gstreamer10 @@ -164,9 +164,9 @@ archive hash - 1f887cbafc0fe2af1e85783de0f14102 + 0008a7b291fa1863ba41424b4e3ac302 url - http://3p.firestormviewer.org/jemalloc-5.2.1-linux64-210451204.tar.bz2 + http://3p.firestormviewer.org/jemalloc-5.3.0-linux64-222631217.tar.bz2 name linux64 @@ -1084,11 +1084,11 @@ archive hash - 971a4c8accc851994039ef36785bed38 + fec86a4837ae9c6932c10af11851c4d0 hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-2.02.07-darwin-222051107.tar.bz2 + file:///opt/firestorm/fmodstudio-2.02.09-darwin64-5.tar.bz2 name darwin @@ -1098,11 +1098,11 @@ archive hash - 21d50d222f005c033452ee3fad44bff1 + a45bb657d668b7f1b4fa4c88eb81a80a hash_algorithm md5 url - file:///opt/firestorm/fmodstudio-2.02.07-linux64_bionic-222191132.tar.bz2 + file:///opt/firestorm/fmodstudio-2.02.09-linux64-222891103.tar.bz2 name linux64 @@ -1112,11 +1112,11 @@ archive hash - 611c5389b0354e6b64a7de50b93fafdb + 6dd278518e791dbc2841e337feb295db hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.07-windows-222041046.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.09-windows-222890940.tar.bz2 name windows @@ -1126,18 +1126,18 @@ archive hash - 1b0b4d70d172c9b1eaac211f051ca599 + 1b7ced6f750b12f0d014556705019534 hash_algorithm md5 url - file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.07-windows64-222041047.tar.bz2 + file:///c:/cygwin/opt/firestorm/fmodstudio-2.02.09-windows64-222890941.tar.bz2 name windows64 version - 2.02.07 + 2.02.09 fontconfig @@ -1886,7 +1886,7 @@ libpng copyright - Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson + Copyright (c) 1995-2022 The PNG Reference Library Authors. description PNG Reference library license @@ -1914,9 +1914,9 @@ archive hash - 83ae55031f81dace9dcf688cc5510010 + 134089ec8c1eead9436b69c326790fc0 url - http://3p.firestormviewer.org/libpng-1.6.8.180841558-linux64-180841558.tar.bz2 + http://3p.firestormviewer.org/libpng-1.6.38.222890126-linux64-222890126.tar.bz2 name linux64 @@ -2632,16 +2632,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 411c000af6328e454ff7064f90c18a81 + 8ad6779b81899afb7bd803ac2e2af37a url - http://3p.firestormviewer.org/open_libndofdev-0.13.222610246-linux64-222610246.tar.bz2 + http://3p.firestormviewer.org/open_libndofdev-0.13.222872202-linux64-222872202.tar.bz2 name linux64 version - 0.13.222610246 + 0.13.222872202 openal diff --git a/doc/contributions.txt b/doc/contributions.txt index b1fa0adf42..09ceef976c 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -407,6 +407,7 @@ Cinder Roxley STORM-2136 STORM-2144 SL-3404 + SL-17634 Clara Young Coaldust Numbers VWR-1095 @@ -1130,6 +1131,7 @@ Nicky Dasmijn SL-16438 SL-17218 SL-17238 + SL-17585 Nicky Perian OPEN-1 STORM-1087 diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index acb455a1fd..44760810dc 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -949,6 +949,9 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } + // initialize mJointAliasMap + getJointAliases(); + // avatar_lad.xml : if( !loadSkeletonNode() ) { @@ -1069,7 +1072,6 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } } - return TRUE; } diff --git a/indra/llappearance/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp index 29d3427315..c3ad605331 100644 --- a/indra/llappearance/llpolymesh.cpp +++ b/indra/llappearance/llpolymesh.cpp @@ -612,14 +612,16 @@ BOOL LLPolyMeshSharedData::loadMesh( const std::string& fileName ) // we reached the end of the morphs break; } - LLPolyMorphData* morph_data = new LLPolyMorphData(std::string(morphName)); + std::string morph_name(morphName); + LLPolyMorphData* morph_data = new LLPolyMorphData(morph_name); BOOL result = morph_data->loadBinary(fp, this); if (!result) { - delete morph_data; - continue; + LL_WARNS() << "Failure loading " << morph_name << " from " << fileName << LL_ENDL; + delete morph_data; + continue; } mMorphData.insert(morph_data); diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 822e422daf..d23f5081b3 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -156,7 +156,9 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) if (mVertexIndices[v] > 10000) { - LL_ERRS() << "Bad morph index: " << mVertexIndices[v] << LL_ENDL; + // Bad install? These are usually .llm files from 'character' fodler + LL_WARNS() << "Bad morph index " << v << ": " << mVertexIndices[v] << LL_ENDL; + return FALSE; } diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 2278cd4afd..31bc64cd10 100644 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -35,6 +35,8 @@ #include "llendianswizzle.h" #include "llassetstorage.h" #include "llrefcount.h" +#include "threadpool.h" +#include "workqueue.h" #include "llvorbisencode.h" @@ -45,15 +47,13 @@ extern LLAudioEngine *gAudiop; -LLAudioDecodeMgr *gAudioDecodeMgrp = NULL; - static const S32 WAV_HEADER_SIZE = 44; ////////////////////////////////////////////////////////////////////////////// -class LLVorbisDecodeState : public LLRefCount +class LLVorbisDecodeState : public LLThreadSafeRefCount { public: class WriteResponder : public LLLFSThread::Responder @@ -537,156 +537,266 @@ void LLVorbisDecodeState::flushBadFile() class LLAudioDecodeMgr::Impl { - friend class LLAudioDecodeMgr; -public: - Impl() {}; - ~Impl() {}; + friend class LLAudioDecodeMgr; + Impl(); + public: - void processQueue(const F32 num_secs = 0.005); + void processQueue(); -protected: - std::deque mDecodeQueue; - LLPointer mCurrentDecodep; + void startMoreDecodes(); + void enqueueFinishAudio(const LLUUID &decode_id, LLPointer& decode_state); + void checkDecodesFinished(); + + protected: + std::deque mDecodeQueue; + std::map> mDecodes; }; - -void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) +LLAudioDecodeMgr::Impl::Impl() { - LLUUID uuid; +} - LLTimer decode_timer; +// Returns the in-progress decode_state, which may be an empty LLPointer if +// there was an error and there is no more work to be done. +LLPointer beginDecodingAndWritingAudio(const LLUUID &decode_id); - BOOL done = FALSE; - while (!done) - { - if (mCurrentDecodep) - { - BOOL res; +// Return true if finished +bool tryFinishAudio(const LLUUID &decode_id, LLPointer decode_state); - // Decode in a loop until we're done or have run out of time. - while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs)) - { - // decodeSection does all of the work above - } +void LLAudioDecodeMgr::Impl::processQueue() +{ + // First, check if any audio from in-progress decodes are ready to play. If + // so, mark them ready for playback (or errored, in case of error). + checkDecodesFinished(); - if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid()) - { - // We had an error when decoding, abort. - LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL; - mCurrentDecodep->flushBadFile(); + // Second, start as many decodes from the queue as permitted + startMoreDecodes(); +} - if (gAudiop) - { - LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); - adp->setHasValidData(false); - adp->setHasCompletedDecode(true); - } +void LLAudioDecodeMgr::Impl::startMoreDecodes() +{ + llassert_always(gAudiop); - mCurrentDecodep = NULL; - done = TRUE; - } + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak + // pointer + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + const LL::ThreadPool::ptr_t general_thread_pool = LL::ThreadPool::getInstance("General"); + llassert_always(main_queue); + llassert_always(general_queue); + llassert_always(general_thread_pool); + // Set max decodes to double the thread count of the general work queue. + // This ensures the general work queue is full, but prevents theoretical + // buildup of buffers in memory due to disk writes once the + // LLVorbisDecodeState leaves the worker thread (see + // LLLFSThread::sLocal->write). This is probably as fast as we can get it + // without modifying/removing LLVorbisDecodeState, at which point we should + // consider decoding the audio during the asset download process. + // -Cosmic,2022-05-11 + const size_t max_decodes = general_thread_pool->getWidth() * 2; - if (!res) - { - // We've used up out time slice, bail... - done = TRUE; - } - else if (mCurrentDecodep) - { - if (gAudiop && mCurrentDecodep->finishDecode()) - { - // We finished! - LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); - if (!adp) - { - LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << LL_ENDL; - } - else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone()) - { - adp->setHasCompletedDecode(true); - adp->setHasDecodedData(true); - adp->setHasValidData(true); + while (!mDecodeQueue.empty() && mDecodes.size() < max_decodes) + { + const LLUUID decode_id = mDecodeQueue.front(); + mDecodeQueue.pop_front(); - // At this point, we could see if anyone needs this sound immediately, but - // I'm not sure that there's a reason to - we need to poll all of the playing - // sounds anyway. - //LL_INFOS("AudioEngine") << "Finished the vorbis decode, now what?" << LL_ENDL; - } - else - { - adp->setHasCompletedDecode(true); - LL_INFOS("AudioEngine") << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << LL_ENDL; - } - mCurrentDecodep = NULL; - } - done = TRUE; // done for now - } - } + // Don't decode the same file twice + if (mDecodes.find(decode_id) != mDecodes.end()) + { + continue; + } + if (gAudiop->hasDecodedFile(decode_id)) + { + continue; + } - if (!done) - { - if (mDecodeQueue.empty()) - { - // Nothing else on the queue. - done = TRUE; - } - else - { - LLUUID uuid; - uuid = mDecodeQueue.front(); - mDecodeQueue.pop_front(); - if (!gAudiop || gAudiop->hasDecodedFile(uuid)) - { - // This file has already been decoded, don't decode it again. - continue; - } + // Kick off a decode + mDecodes[decode_id] = LLPointer(NULL); + try + { + main_queue->postTo( + general_queue, + [decode_id]() // Work done on general queue + { + LLPointer decode_state = beginDecodingAndWritingAudio(decode_id); - LL_DEBUGS() << "Decoding " << uuid << " from audio queue!" << LL_ENDL; + if (!decode_state) + { + if (gAudiop) + gAudiop->markSoundCorrupt(decode_id); - std::string uuid_str; - std::string d_path; + // Audio decode has errored + return decode_state; + } - LLTimer timer; - timer.reset(); + // Disk write of decoded audio is now in progress off-thread + return decode_state; + }, + [decode_id, this](LLPointer decode_state) // Callback to main thread + mutable { + if (!gAudiop) + { + // There is no LLAudioEngine anymore. This might happen if + // an audio decode is enqueued just before shutdown. + return; + } - uuid.toString(uuid_str); - // Sound cache - //d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf"; - d_path = gDirUtilp->getExpandedFilename(LL_PATH_FS_SOUND_CACHE,uuid_str) + ".dsf"; - // + // At this point, we can be certain that the pointer to "this" + // is valid because the lifetime of "this" is dependent upon + // the lifetime of gAudiop. - mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path); - if (!mCurrentDecodep->initDecode()) - { - gAudiop->markSoundCorrupt( uuid ); - mCurrentDecodep = NULL; - } - } - } - } + enqueueFinishAudio(decode_id, decode_state); + }); + } + catch (const LLThreadSafeQueueInterrupt&) + { + // Shutdown + // Consider making processQueue() do a cleanup instead + // of starting more decodes + LL_WARNS() << "Tried to start decoding on shutdown" << LL_ENDL; + } + } +} + +LLPointer beginDecodingAndWritingAudio(const LLUUID &decode_id) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; + + LL_DEBUGS() << "Decoding " << decode_id << " from audio queue!" << LL_ENDL; + + // Sound cache + //std::string d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, decode_id.asString()) + ".dsf"; + std::string d_path = gDirUtilp->getExpandedFilename(LL_PATH_FS_SOUND_CACHE, decode_id.asString()) + ".dsf"; + // + LLPointer decode_state = new LLVorbisDecodeState(decode_id, d_path); + + if (!decode_state->initDecode()) + { + return NULL; + } + + // Decode in a loop until we're done + while (!decode_state->decodeSection()) + { + // decodeSection does all of the work above + } + + if (!decode_state->isDone()) + { + // Decode stopped early, or something bad happened to the file + // during decoding. + LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data or decode has been canceled, aborting decode" << LL_ENDL; + decode_state->flushBadFile(); + return NULL; + } + + if (!decode_state->isValid()) + { + // We had an error when decoding, abort. + LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data, aborting decode" << LL_ENDL; + decode_state->flushBadFile(); + return NULL; + } + + // Kick off the writing of the decoded audio to the disk cache. + // The receiving thread can then cheaply call finishDecode() again to check + // if writing has finished. Someone has to hold on to the refcounted + // decode_state to prevent it from getting destroyed during write. + decode_state->finishDecode(); + + return decode_state; +} + +void LLAudioDecodeMgr::Impl::enqueueFinishAudio(const LLUUID &decode_id, LLPointer& decode_state) +{ + // Assumed fast + if (tryFinishAudio(decode_id, decode_state)) + { + // Done early! + auto decode_iter = mDecodes.find(decode_id); + llassert(decode_iter != mDecodes.end()); + mDecodes.erase(decode_iter); + return; + } + + // Not done yet... enqueue it + mDecodes[decode_id] = decode_state; +} + +void LLAudioDecodeMgr::Impl::checkDecodesFinished() +{ + auto decode_iter = mDecodes.begin(); + while (decode_iter != mDecodes.end()) + { + const LLUUID& decode_id = decode_iter->first; + const LLPointer& decode_state = decode_iter->second; + if (tryFinishAudio(decode_id, decode_state)) + { + decode_iter = mDecodes.erase(decode_iter); + } + else + { + ++decode_iter; + } + } +} + +bool tryFinishAudio(const LLUUID &decode_id, LLPointer decode_state) +{ + // decode_state is a file write in progress unless finished is true + bool finished = decode_state && decode_state->finishDecode(); + if (!finished) + { + return false; + } + + llassert_always(gAudiop); + + LLAudioData *adp = gAudiop->getAudioData(decode_id); + if (!adp) + { + LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << decode_id << LL_ENDL; + return true; + } + + bool valid = decode_state && decode_state->isValid(); + // Mark current decode finished regardless of success or failure + adp->setHasCompletedDecode(true); + // Flip flags for decoded data + adp->setHasDecodeFailed(!valid); + adp->setHasDecodedData(valid); + // When finished decoding, there will also be a decoded wav file cached on + // disk with the .dsf extension + if (valid) + { + adp->setHasWAVLoadFailed(false); + } + + return true; } ////////////////////////////////////////////////////////////////////////////// LLAudioDecodeMgr::LLAudioDecodeMgr() { - mImpl = new Impl; + mImpl = new Impl(); } LLAudioDecodeMgr::~LLAudioDecodeMgr() { - delete mImpl; + delete mImpl; + mImpl = nullptr; } -void LLAudioDecodeMgr::processQueue(const F32 num_secs) +void LLAudioDecodeMgr::processQueue() { - mImpl->processQueue(num_secs); + mImpl->processQueue(); } BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) { // Protect against corrupted sounds. Just do a quit exit instead of trying to decode over and over. - if( gAudiop->isCorruptSound( uuid ) ) + if (gAudiop && gAudiop->isCorruptSound(uuid)) return FALSE; // diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h index ceaff3f2d8..4c17b46156 100644 --- a/indra/llaudio/llaudiodecodemgr.h +++ b/indra/llaudio/llaudiodecodemgr.h @@ -32,24 +32,23 @@ #include "llassettype.h" #include "llframetimer.h" +#include "llsingleton.h" +template class LLPointer; class LLVorbisDecodeState; -class LLAudioDecodeMgr +class LLAudioDecodeMgr : public LLSingleton { + LLSINGLETON(LLAudioDecodeMgr); + ~LLAudioDecodeMgr(); public: - LLAudioDecodeMgr(); - ~LLAudioDecodeMgr(); - - void processQueue(const F32 num_secs = 0.005); + void processQueue(); BOOL addDecodeRequest(const LLUUID &uuid); void addAudioRequest(const LLUUID &uuid); protected: class Impl; - Impl* mImpl; + Impl* mImpl; }; -extern LLAudioDecodeMgr *gAudioDecodeMgrp; - #endif diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 20fb59ee6b..66c12164ab 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -90,18 +90,10 @@ void LLAudioEngine::setDefaults() mLastStatus = 0; - mNumChannels = 0; mEnableWind = false; - S32 i; - for (i = 0; i < MAX_CHANNELS; i++) - { - mChannels[i] = NULL; - } - for (i = 0; i < MAX_BUFFERS; i++) - { - mBuffers[i] = NULL; - } + mChannels.fill(nullptr); + mBuffers.fill(nullptr); mMasterGain = 1.f; // Setting mInternalGain to an out of range value fixes the issue reported in STORM-830. @@ -118,18 +110,14 @@ void LLAudioEngine::setDefaults() } -bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine::init(void* userdata, const std::string &app_title) { setDefaults(); - mNumChannels = num_channels; mUserData = userdata; allocateListener(); - // Initialize the decode manager - gAudioDecodeMgrp = new LLAudioDecodeMgr; - LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL; return true; @@ -144,10 +132,6 @@ void LLAudioEngine::shutdown() mStreamingAudioImpl = NULL; // - // Clean up decode manager - delete gAudioDecodeMgrp; - gAudioDecodeMgrp = NULL; - // Clean up wind source cleanupWind(); @@ -169,14 +153,14 @@ void LLAudioEngine::shutdown() // Clean up channels S32 i; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { delete mChannels[i]; mChannels[i] = NULL; } // Clean up buffers - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { delete mBuffers[i]; mBuffers[i] = NULL; @@ -242,7 +226,7 @@ std::string LLAudioEngine::getInternetStreamURL() void LLAudioEngine::updateChannels() { S32 i; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (mChannels[i]) { @@ -253,20 +237,14 @@ void LLAudioEngine::updateChannels() } } -static const F32 default_max_decode_time = .002f; // 2 ms -void LLAudioEngine::idle(F32 max_decode_time) +void LLAudioEngine::idle() { - if (max_decode_time <= 0.f) - { - max_decode_time = default_max_decode_time; - } - // "Update" all of our audio sources, clean up dead ones. // Primarily does position updating, cleanup of unused audio sources. // Also does regeneration of the current priority of each audio source. S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -486,7 +464,7 @@ void LLAudioEngine::idle(F32 max_decode_time) commitDeferredChanges(); // Flush unused buffers that are stale enough - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -502,7 +480,7 @@ void LLAudioEngine::idle(F32 max_decode_time) // Clear all of the looped flags for the channels - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (mChannels[i]) { @@ -511,7 +489,7 @@ void LLAudioEngine::idle(F32 max_decode_time) } // Decode audio files - gAudioDecodeMgrp->processQueue(max_decode_time); + LLAudioDecodeMgr::getInstance()->processQueue(); // Call this every frame, just in case we somehow // missed picking it up in all the places that can add @@ -545,7 +523,7 @@ bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu { if (audio_uuid.notNull()) { - gAudioDecodeMgrp->addDecodeRequest(audio_uuid); + LLAudioDecodeMgr::getInstance()->addDecodeRequest(audio_uuid); } } else @@ -574,7 +552,7 @@ void LLAudioEngine::enableWind(bool enable) LLAudioBuffer * LLAudioEngine::getFreeBuffer() { S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (!mBuffers[i]) { @@ -587,7 +565,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() // Grab the oldest unused buffer F32 max_age = -1.f; S32 buffer_id = -1; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -618,7 +596,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) { S32 i; - for (i = 0; i < mNumChannels; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -646,7 +624,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) F32 min_priority = 10000.f; LLAudioChannel *min_channelp = NULL; - for (i = 0; i < mNumChannels; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { LLAudioChannel *channelp = mChannels[i]; LLAudioSource *sourcep = channelp->getSource(); @@ -673,7 +651,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp) { S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i] == bufferp) { @@ -696,7 +674,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid) getAudioData(uuid); // We don't care about the return value, this is just to make sure // that we have an entry, which will mean that the audio engine knows about this - if (gAudioDecodeMgrp->addDecodeRequest(uuid)) + if (LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid)) { // This means that we do have a local copy, and we're working on decoding it. return true; @@ -981,6 +959,7 @@ LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id) LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; // Protect against corrupted sounds. Just do a quick exit instead of trying to decode over and over again. if( isCorruptSound( audio_uuid ) ) return 0; @@ -1075,7 +1054,7 @@ void LLAudioEngine::startNextTransfer() // Check all channels for currently playing sounds. F32 max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1103,7 +1082,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1114,7 +1093,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.isNull()) { max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1139,7 +1118,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1151,7 +1130,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.isNull()) { max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1179,7 +1158,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1207,7 +1186,7 @@ void LLAudioEngine::startNextTransfer() } adp = asp->getCurrentData(); - if (adp && !adp->hasLocalData() && adp->hasValidData()) + if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1215,7 +1194,7 @@ void LLAudioEngine::startNextTransfer() } adp = asp->getQueuedData(); - if (adp && !adp->hasLocalData() && adp->hasValidData()) + if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1230,7 +1209,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1271,7 +1250,7 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) { // Make sure everything is cleared - adp->setHasValidData(false); + adp->setHasDecodeFailed(true); adp->setHasLocalData(false); adp->setHasDecodedData(false); adp->setHasCompletedDecode(true); @@ -1289,9 +1268,9 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v else { // LL_INFOS() << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL; - adp->setHasValidData(true); + adp->setHasDecodeFailed(false); adp->setHasLocalData(true); - gAudioDecodeMgrp->addDecodeRequest(uuid); + LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid); } } gAudiop->mCurrentTransfer = LLUUID::null; @@ -1455,11 +1434,15 @@ void LLAudioSource::update() { // Hack - try and load the sound. Will do this as a callback // on decode later. - if (adp->load() && adp->getBuffer()) + if (adp->getBuffer()) { play(adp->getID()); } - else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done + else if (adp->hasDecodedData() && !adp->hasWAVLoadFailed()) + { + adp->load(); + } + else if (adp->hasCompletedDecode() && adp->hasDecodeFailed()) // Only mark corrupted after decode is done { LL_WARNS() << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL; mCorrupted = true ; @@ -1767,12 +1750,12 @@ bool LLAudioSource::hasPendingPreloads() const { LLAudioData *adp = iter->second; // note: a bad UUID will forever be !hasDecodedData() - // but also !hasValidData(), hence the check for hasValidData() + // but also hasDecodeFailed(), hence the check for hasDecodeFailed() if (!adp) { continue; } - if (!adp->hasDecodedData() && adp->hasValidData()) + if (!adp->hasDecodedData() && !adp->hasDecodeFailed()) { // This source is still waiting for a preload return true; @@ -1929,7 +1912,8 @@ LLAudioData::LLAudioData(const LLUUID &uuid) : mHasLocalData(false), mHasDecodedData(false), mHasCompletedDecode(false), - mHasValidData(true) + mHasDecodeFailed(false), + mHasWAVLoadFailed(false) { if (uuid.isNull()) { @@ -1964,12 +1948,14 @@ bool LLAudioData::load() { // We already have this sound in a buffer, don't do anything. LL_INFOS() << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL; + mHasWAVLoadFailed = false; return true; } if (!gAudiop) { LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + mHasWAVLoadFailed = true; return false; } @@ -1978,6 +1964,8 @@ bool LLAudioData::load() { // No free buffers, abort. LL_INFOS() << "Not able to allocate a new audio buffer, aborting." << LL_ENDL; + // *TODO: Mark this failure differently so the audio engine could retry loading this buffer in the future + mHasWAVLoadFailed = true; return true; } @@ -1989,7 +1977,8 @@ bool LLAudioData::load() wav_path= gDirUtilp->getExpandedFilename(LL_PATH_FS_SOUND_CACHE,uuid_str) + ".dsf"; // - if (!mBufferp->loadWAV(wav_path)) + mHasWAVLoadFailed = !mBufferp->loadWAV(wav_path); + if (mHasWAVLoadFailed) { // Hrm. Right now, let's unset the buffer, since it's empty. gAudiop->cleanupBuffer(mBufferp); @@ -2001,7 +1990,8 @@ bool LLAudioData::load() mHasLocalData = false; mHasDecodedData = false; mHasCompletedDecode = false; - mHasValidData = true; + mHasDecodeFailed = false; + mHasWAVLoadFailed = false; gAudiop->preloadSound(mID); } // @@ -2078,7 +2068,7 @@ void LLAudioEngine::removeAudioData(const LLUUID& audio_uuid) if (buf) { S32 i; - for (i = 0; i < MAX_BUFFERS; ++i) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; ++i) { if (mBuffers[i] == buf) { diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 783fcdd91e..74e264377e 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -49,10 +49,10 @@ const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f; const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f; const F32 DEFAULT_MIN_DISTANCE = 2.0f; -#define MAX_CHANNELS 30 +#define LL_MAX_AUDIO_CHANNELS 30 // FIRE-4276: Increase number of audio buffers -//#define MAX_BUFFERS 40 // Some extra for preloading, maybe? -#define MAX_BUFFERS 60 +//#define LL_MAX_AUDIO_BUFFERS 40 // Some extra for preloading, maybe? +#define LL_MAX_AUDIO_BUFFERS 60 // class LLAudioSource; @@ -93,7 +93,7 @@ public: virtual ~LLAudioEngine(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title); + virtual bool init(void *userdata, const std::string &app_title); virtual std::string getDriverName(bool verbose) = 0; virtual void shutdown(); @@ -101,7 +101,7 @@ public: //virtual void processQueue(const LLUUID &sound_guid); virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at); virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0; - virtual void idle(F32 max_decode_time = 0.f); + virtual void idle(); virtual void updateChannels(); // @@ -238,7 +238,6 @@ protected: S32 mLastStatus; - S32 mNumChannels; bool mEnableWind; LLUUID mCurrentTransfer; // Audio file currently being transferred by the system @@ -253,11 +252,11 @@ protected: source_map mAllSources; data_map mAllData; - LLAudioChannel *mChannels[MAX_CHANNELS]; + std::array mChannels; // Buffers needs to change into a different data structure, as the number of buffers // that we have active should be limited by RAM usage, not count. - LLAudioBuffer *mBuffers[MAX_BUFFERS]; + std::array mBuffers; F32 mMasterGain; F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true. @@ -418,32 +417,36 @@ protected: class LLAudioData { -public: - LLAudioData(const LLUUID &uuid); - bool load(); + public: + LLAudioData(const LLUUID &uuid); + bool load(); - LLUUID getID() const { return mID; } - LLAudioBuffer *getBuffer() const { return mBufferp; } + LLUUID getID() const { return mID; } + LLAudioBuffer *getBuffer() const { return mBufferp; } - bool hasLocalData() const { return mHasLocalData; } - bool hasDecodedData() const { return mHasDecodedData; } - bool hasCompletedDecode() const { return mHasCompletedDecode; } - bool hasValidData() const { return mHasValidData; } + bool hasLocalData() const { return mHasLocalData; } + bool hasDecodedData() const { return mHasDecodedData; } + bool hasCompletedDecode() const { return mHasCompletedDecode; } + bool hasDecodeFailed() const { return mHasDecodeFailed; } + bool hasWAVLoadFailed() const { return mHasWAVLoadFailed; } - void setHasLocalData(const bool hld) { mHasLocalData = hld; } - void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } - void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; } - void setHasValidData(const bool hvd) { mHasValidData = hvd; } + void setHasLocalData(const bool hld) { mHasLocalData = hld; } + void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } + void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; } + void setHasDecodeFailed(const bool hdf) { mHasDecodeFailed = hdf; } + void setHasWAVLoadFailed(const bool hwlf) { mHasWAVLoadFailed = hwlf; } - friend class LLAudioEngine; // Severe laziness, bad. + friend class LLAudioEngine; // Severe laziness, bad. -protected: - LLUUID mID; - LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. - bool mHasLocalData; // Set true if the sound asset file is available locally - bool mHasDecodedData; // Set true if the sound file has been decoded - bool mHasCompletedDecode; // Set true when the sound is decoded - bool mHasValidData; // Set false if decoding failed, meaning the sound asset is bad + protected: + LLUUID mID; + LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. + bool mHasLocalData; // Set true if the encoded sound asset file is available locally + bool mHasDecodedData; // Set true if the decoded sound file is available on disk + bool mHasCompletedDecode; // Set true when the sound is decoded + bool mHasDecodeFailed; // Set true if decoding failed, meaning the sound asset is bad + bool mHasWAVLoadFailed; // Set true if loading the decoded WAV file failed, meaning the sound asset should be decoded instead if + // possible }; diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index fe8487a151..9b215337e9 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -152,7 +152,7 @@ LLAudioEngine_FMODSTUDIO::~LLAudioEngine_FMODSTUDIO() // mSystem gets cleaned up at shutdown() } -bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine_FMODSTUDIO::init(void* userdata, const std::string &app_title) { U32 version; FMOD_RESULT result; @@ -164,7 +164,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons return false; //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. - LLAudioEngine::init(num_channels, userdata, app_title); + LLAudioEngine::init(userdata, app_title); result = mSystem->getVersion(&version); Check_FMOD_Error(result, "FMOD::System::getVersion"); @@ -176,7 +176,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons } // In this case, all sounds, PLUS wind and stream will be software. - result = mSystem->setSoftwareChannels(num_channels + EXTRA_SOUND_CHANNELS); + result = mSystem->setSoftwareChannels(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS); Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); Check_FMOD_Error(mSystem->setCallback(systemCallback), "FMOD::System::setCallback"); @@ -219,7 +219,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; if ((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK && - (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, const_cast(app_title.c_str()))) == FMOD_OK) + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, const_cast(app_title.c_str()))) == FMOD_OK) { LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; audio_ok = true; @@ -241,7 +241,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; if ((result = mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA)) == FMOD_OK && - (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0)) == FMOD_OK) + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, 0)) == FMOD_OK) { LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; audio_ok = true; @@ -282,7 +282,9 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons #else // LL_LINUX // initialize the FMOD engine - result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0); + // number of channel in this case looks to be identiacal to number of max simultaneously + // playing objects and we can set practically any number + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, 0); if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format")) { result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/); @@ -290,7 +292,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { return false; } - result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0); + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, 0); } if (Check_FMOD_Error(result, "Error initializing FMOD Studio")) { diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h index 91f7cc89e4..0c9b4d186f 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.h +++ b/indra/llaudio/llaudioengine_fmodstudio.h @@ -57,7 +57,7 @@ public: virtual ~LLAudioEngine_FMODSTUDIO(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); + virtual bool init(void *user_data, const std::string &app_title); virtual std::string getDriverName(bool verbose); virtual void allocateListener(); diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 5e36b5b161..1b8a870798 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -52,10 +52,10 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() } // virtual -bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title) { mWindGen = NULL; - LLAudioEngine::init(num_channels, userdata, app_title); + LLAudioEngine::init(userdata, app_title); if(!alutInit(NULL, NULL)) { diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 366f9259e3..a3cab97cd2 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -40,7 +40,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL(); - virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); + virtual bool init(void *user_data, const std::string &app_title); virtual std::string getDriverName(bool verbose); virtual void allocateListener(); diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 17b744f7b7..cc6e37ebe6 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1225,8 +1225,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 //----------------------------------------------------------------------------- // deserialize() +// +// allow_invalid_joints should be true when handling existing content, to avoid breakage. +// During upload, we should be more restrictive and reject such animations. //----------------------------------------------------------------------------- -BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) +BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; mJointMotionList = new LLKeyframeMotion::JointMotionList; @@ -1359,6 +1362,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) return FALSE; } + //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside + LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e"); + LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a"); + if (female_land_anim == asset_id || formal_female_land_anim == asset_id) + { + LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; + mJointMotionList->mLoop = FALSE; + } + //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- @@ -1467,6 +1479,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) if (joint) { S32 joint_num = joint->getJointNum(); + joint_name = joint->getName(); // canonical name in case this is an alias. // LL_INFOS() << " joint: " << joint_name << LL_ENDL; if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) { @@ -1481,7 +1494,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) { LL_WARNS() << "invalid joint name: " << joint_name << " for animation " << asset_id << LL_ENDL; - //return FALSE; + if (!allow_invalid_joints) + { + return FALSE; + } } joint_motion->mJointName = joint_name; @@ -2156,8 +2172,9 @@ U32 LLKeyframeMotion::getFileSize() //----------------------------------------------------------------------------- // dumpToFile() //----------------------------------------------------------------------------- -void LLKeyframeMotion::dumpToFile(const std::string& name) +bool LLKeyframeMotion::dumpToFile(const std::string& name) { + bool succ = false; if (isLoaded()) { std::string outfile_base; @@ -2174,10 +2191,24 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) const LLUUID& id = getID(); outfile_base = id.asString(); } - std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim"); + + if (gDirUtilp->getExtension(outfile_base).empty()) + { + outfile_base += ".anim"; + } + std::string outfilename; + if (gDirUtilp->getDirName(outfile_base).empty()) + { + outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base); + } + else + { + outfilename = outfile_base; + } if (LLFile::isfile(outfilename)) { - return; + LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL; + return false; } S32 file_size = getFileSize(); @@ -2191,11 +2222,13 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) outfile.open(outfilename, LL_APR_WPB); if (outfile.getFileHandle()) { - outfile.write(buffer, file_size); + S32 wrote_bytes = outfile.write(buffer, file_size); + succ = (wrote_bytes == file_size); } } delete [] buffer; } + return succ; } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 9a927ede9a..96746f57c9 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -156,9 +156,9 @@ public: public: U32 getFileSize(); BOOL serialize(LLDataPacker& dp) const; - BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id); + BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); BOOL isLoaded() { return mJointMotionList != NULL; } - void dumpToFile(const std::string& name); + bool dumpToFile(const std::string& name); // setters for modifying a keyframe animation @@ -432,6 +432,9 @@ protected: F32 mLastUpdateTime; F32 mLastLoopedTime; AssetStatus mAssetStatus; + +public: + void setCharacter(LLCharacter* character) { mCharacter = character; } }; class LLKeyframeDataCache diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 2aee688d4a..5fdf596235 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -254,6 +254,11 @@ set(llcommon_HEADER_FILES StackWalker.h ) +if (DARWIN) + list(APPEND llcommon_HEADER_FILES llsys_objc.h) + list(APPEND llcommon_SOURCE_FILES llsys_objc.mm) +endif (DARWIN) + # Tracy Profiler support list(APPEND llcommon_SOURCE_FILES llprofiler.cpp) @@ -309,8 +314,8 @@ target_link_libraries( ll::tracy ) -target_include_directories( llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories( llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) +target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) add_dependencies(llcommon stage_third_party_libs) diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 849867586a..d6ae1284d3 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -212,11 +212,9 @@ U64 LLMemory::getCurrentRSS() mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT; if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS) { -// residentSize = basicInfo.resident_size; - // Although this method is defined to return the "resident set size," - // in fact what callers want from it is the total virtual memory - // consumed by the application. - residentSize = basicInfo.virtual_size; + residentSize = basicInfo.resident_size; + // 64-bit macos apps allocate 32 GB or more at startup, and this is reflected in virtual_size. + // basicInfo.virtual_size is not what we want. } else { diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp index 5cbd346411..6852b5536a 100644 --- a/indra/llcommon/llrefcount.cpp +++ b/indra/llcommon/llrefcount.cpp @@ -30,7 +30,7 @@ #include "llerror.h" // maximum reference count before sounding memory leak alarm -const S32 gMaxRefCount = 65536; +const S32 gMaxRefCount = S32_MAX; LLRefCount::LLRefCount(const LLRefCount& other) : mRef(0) diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 570c065554..0c9becfe67 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -64,6 +64,7 @@ using namespace llsd; # include // GetPerformanceInfo() et al. # include #elif LL_DARWIN +# include "llsys_objc.h" # include # include # include @@ -74,12 +75,6 @@ using namespace llsd; # include # include # include - -// disable warnings about Gestalt calls being deprecated -// until Apple get's on the ball and provides an alternative -// -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - #elif LL_LINUX # include # include @@ -289,12 +284,9 @@ LLOSInfo::LLOSInfo() : { const char * DARWIN_PRODUCT_NAME = "Mac OS X"; - SInt32 major_version, minor_version, bugfix_version; - OSErr r1 = Gestalt(gestaltSystemVersionMajor, &major_version); - OSErr r2 = Gestalt(gestaltSystemVersionMinor, &minor_version); - OSErr r3 = Gestalt(gestaltSystemVersionBugFix, &bugfix_version); + S32 major_version, minor_version, bugfix_version = 0; - if((r1 == noErr) && (r2 == noErr) && (r3 == noErr)) + if (LLGetDarwinOSInfo(major_version, minor_version, bugfix_version)) { mMajorVer = major_version; mMinorVer = minor_version; @@ -1446,10 +1438,3 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile) if (dst != NULL) gzclose(dst); return retval; } - -#if LL_DARWIN -// disable warnings about Gestalt calls being deprecated -// until Apple get's on the ball and provides an alternative -// -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif diff --git a/indra/llcommon/llsys_objc.h b/indra/llcommon/llsys_objc.h new file mode 100644 index 0000000000..35599a574b --- /dev/null +++ b/indra/llcommon/llsys_objc.h @@ -0,0 +1,33 @@ +/** + * @file llsys_objc.h + * @brief Header file for llsys_objc.mm + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLSYS_OBJC_H +#define LL_LLSYS_OBJC_H + +bool LLGetDarwinOSInfo(int &major, int &minor, int &patch); + + +#endif // LL_LLSYS_OBJC_H diff --git a/indra/llcommon/llsys_objc.mm b/indra/llcommon/llsys_objc.mm new file mode 100644 index 0000000000..cdb1e320d5 --- /dev/null +++ b/indra/llcommon/llsys_objc.mm @@ -0,0 +1,64 @@ +/** + * @file llsys_objc.mm + * @brief obj-c implementation of the system information functions + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#import "llsys_objc.h" +#import + +static int intAtStringIndex(NSArray *array, int index) +{ + return [(NSString *)[array objectAtIndex:index] integerValue]; +} + +bool LLGetDarwinOSInfo(int &major, int &minor, int &patch) +{ + if (NSAppKitVersionNumber > NSAppKitVersionNumber10_8) + { + NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; + major = osVersion.majorVersion; + minor = osVersion.minorVersion; + patch = osVersion.patchVersion; + } + else + { + NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile: + @"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"]; + NSArray* versions = [versionString componentsSeparatedByString:@"."]; + NSUInteger count = [versions count]; + if (count > 0) + { + major = intAtStringIndex(versions, 0); + if (count > 1) + { + minor = intAtStringIndex(versions, 1); + if (count > 2) + { + patch = intAtStringIndex(versions, 2); + } + } + } + } + return true; +} diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index ba914035e2..d5adf11264 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -22,6 +22,7 @@ #include "stringize.h" LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity): + super(name), mQueue(name, capacity), mName("ThreadPool:" + name), mThreadCount(threads) diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index b79c9b9090..f8eec3b457 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -22,8 +22,10 @@ namespace LL { - class ThreadPool + class ThreadPool: public LLInstanceTracker { + private: + using super = LLInstanceTracker; public: /** * Pass ThreadPool a string name. This can be used to look up the diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 96574a18b9..70fd65bd0c 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -403,7 +403,7 @@ namespace LL [result = std::forward(callable)(), callback = std::move(callback)] () - { callback(std::move(result)); }; + mutable { callback(std::move(result)); }; } }; @@ -449,7 +449,7 @@ namespace LL callable = std::move(callable), callback = std::move(callback)] () - { + mutable { // Use postMaybe() below in case this originating WorkQueue // has been closed or destroyed. Remember, the outer lambda is // now running on a thread servicing the target WorkQueue, and @@ -513,7 +513,7 @@ namespace LL // We dare to bind a reference to Promise because it's // specifically designed for cross-thread communication. [&promise, callable = std::move(callable)]() - { + mutable { try { // call the caller's callable and trigger promise with result @@ -542,7 +542,7 @@ namespace LL time, // &promise is designed for cross-thread access [&promise, callable = std::move(callable)]() - { + mutable { try { callable(); diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index 448459b76d..a4e056101b 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -71,9 +71,9 @@ LLDiskCache::LLDiskCache(const std::string cache_dir, // WARNING: purge() is called by LLPurgeDiskCacheThread. As such it must // NOT touch any LLDiskCache data without introducing and locking a mutex! -// Interaction through the filesystem itself should be safe. Lets say thread +// Interaction through the filesystem itself should be safe. Let’s say thread // A is accessing the cache file for reading/writing and thread B is trimming -// the cache. Lets also assume using llifstream to open a file and +// the cache. Let’s also assume using llifstream to open a file and // boost::filesystem::remove are not atomic (which will be pretty much the // case). @@ -150,49 +150,86 @@ void LLDiskCache::purge() LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL; // Extra accounting to track the retention of static assets + //std::vector file_removed; + std::vector file_removed; int keep{0}; int del{0}; int skip{0}; // + if (mEnableCacheDebugInfo) + { + file_removed.reserve(file_info.size()); + } uintmax_t file_size_total = 0; for (file_info_t& entry : file_info) { file_size_total += entry.second.first; - std::string action = ""; - if (file_size_total > mMaxSizeBytes) + bool should_remove = file_size_total > mMaxSizeBytes; + // Make sure static assets are not eliminated + S32 action{ should_remove ? 0 : 1 }; + if (should_remove) { - action = "DELETE:"; - // Make sure static assets are not eliminated - auto uuid_as_string = gDirUtilp->getBaseFileName(entry.second.second,true); - uuid_as_string = uuid_as_string.substr(mCacheFilenamePrefix.size() + 1, 36);// skip "sl_cache_" and trailing "_N" + auto uuid_as_string = gDirUtilp->getBaseFileName(entry.second.second, true); + uuid_as_string = uuid_as_string.substr(mCacheFilenamePrefix.size() + 1, 36);// skip "sl_cache_" and trailing "_N" // LL_INFOS() << "checking UUID=" < - boost::filesystem::remove(entry.second.second, ec); - if (ec.failed()) - { - LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL; - } - } } - else - { - keep++; // Extra accounting to track the retention of static assets - action = " KEEP:"; - } - + // if (mEnableCacheDebugInfo) { + // Static asset stuff + //file_removed.push_back(should_remove); + file_removed.push_back(action); + } + if (should_remove) + { + boost::filesystem::remove(entry.second.second, ec); + if (ec.failed()) + { + LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL; + } + } + } + + if (mEnableCacheDebugInfo) + { + auto end_time = std::chrono::high_resolution_clock::now(); + auto execute_time = std::chrono::duration_cast(end_time - start_time).count(); + + // Log afterward so it doesn't affect the time measurement + // Logging thousands of file results can take hundreds of milliseconds + for (size_t i = 0; i < file_info.size(); ++i) + { + const file_info_t& entry = file_info[i]; + // Static asset stuff + //const bool removed = file_removed[i]; + //const std::string action = removed ? "DELETE:" : "KEEP:"; + std::string action{}; + switch (file_removed[i]) + { + default: + case 0: + action = "KEEP"; + keep++; + break; + case 1: + action = "DELETE"; + del++; + break; + case 2: + action = "STATIC"; + skip++; + break; + } + // + // have to do this because of LL_INFO/LL_END weirdness std::ostringstream line; @@ -203,12 +240,7 @@ void LLDiskCache::purge() line << " (" << file_size_total << "/" << mMaxSizeBytes << ")"; LL_INFOS() << line.str() << LL_ENDL; } - } - if (mEnableCacheDebugInfo) - { - auto end_time = std::chrono::high_resolution_clock::now(); - auto execute_time = std::chrono::duration_cast(end_time - start_time).count(); LL_INFOS() << "Total dir size after purge is " << dirFileSize(mCacheDir) << LL_ENDL; LL_INFOS() << "Cache purge took " << execute_time << " ms to execute for " << file_info.size() << " files" << LL_ENDL; LL_INFOS() << "Deleted: " << del << " Skipped: " << skip << " Kept: " << keep << LL_ENDL; // Extra accounting to track the retention of static assets diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 9d12929323..e562ef4e66 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -50,52 +50,59 @@ extern float gOctreeMinSize; #define LL_OCTREE_MAX_CAPACITY 128 #endif*/ -template class LLOctreeNode; +// T is the type of the element referenced by the octree node. +// T_PTR determines how pointers to elements are stored internally. +// LLOctreeNode> assumes ownership of inserted elements and +// deletes elements removed from the tree. +// LLOctreeNode doesn't take ownership of inserted elements, so the API +// user is responsible for managing the storage lifecycle of elements added to +// the tree. +template class LLOctreeNode; -template +template class LLOctreeListener: public LLTreeListener { public: typedef LLTreeListener BaseType; - typedef LLOctreeNode oct_node; + typedef LLOctreeNode oct_node; virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0; virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0; }; -template +template class LLOctreeTraveler { public: - virtual void traverse(const LLOctreeNode* node); - virtual void visit(const LLOctreeNode* branch) = 0; + virtual void traverse(const LLOctreeNode* node); + virtual void visit(const LLOctreeNode* branch) = 0; }; -template -class LLOctreeTravelerDepthFirst : public LLOctreeTraveler +template +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler { public: - virtual void traverse(const LLOctreeNode* node) override; + virtual void traverse(const LLOctreeNode* node) override; }; -template +template class alignas(16) LLOctreeNode : public LLTreeNode { LL_ALIGN_NEW public: - typedef LLOctreeTraveler oct_traveler; - typedef LLTreeTraveler tree_traveler; - typedef std::vector< LLPointer > element_list; // note: don't remove the whitespace between "> >" - typedef LLPointer* element_iter; - typedef const LLPointer* const_element_iter; + typedef LLOctreeTraveler oct_traveler; + typedef LLTreeTraveler tree_traveler; + typedef std::vector element_list; + typedef typename element_list::iterator element_iter; + typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; - typedef LLOctreeNode** child_list; - typedef LLOctreeNode** child_iter; + typedef LLOctreeNode** child_list; + typedef LLOctreeNode** child_iter; - typedef LLTreeNode BaseType; - typedef LLOctreeNode oct_node; - typedef LLOctreeListener oct_listener; + typedef LLTreeNode BaseType; + typedef LLOctreeNode oct_node; + typedef LLOctreeListener oct_listener; enum { @@ -110,9 +117,6 @@ public: mOctant(octant) { llassert(size[0] >= gOctreeMinSize*0.5f); - //always keep a NULL terminated list to avoid out of bounds exceptions in debug builds - mData.push_back(NULL); - mDataEnd = &mData[0]; mCenter = center; mSize = size; @@ -124,8 +128,6 @@ public: ND_OCTREE_LOG << "set octant to " << (U32)mOctant << " mCenter " << mCenter << " mParent->mCenter " << mParent->mCenter << ND_OCTREE_LOG_END; } - mElementCount = 0; - clearChildren(); } @@ -133,15 +135,14 @@ public: { BaseType::destroyListeners(); - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { mData[i]->setBinIndex(-1); mData[i] = NULL; } mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; for (U32 i = 0; i < getChildCount(); i++) { @@ -241,14 +242,12 @@ public: void accept(oct_traveler* visitor) { visitor->visit(this); } virtual bool isLeaf() const { return mChildCount == 0; } - U32 getElementCount() const { return mElementCount; } - bool isEmpty() const { return mElementCount == 0; } - element_list& getData() { return mData; } - const element_list& getData() const { return mData; } - element_iter getDataBegin() { return &mData[0]; } - element_iter getDataEnd() { return mDataEnd; } - const_element_iter getDataBegin() const { return &mData[0]; } - const_element_iter getDataEnd() const { return mDataEnd; } + U32 getElementCount() const { return (U32)mData.size(); } + bool isEmpty() const { return mData.empty(); } + element_iter getDataBegin() { return mData.begin(); } + element_iter getDataEnd() { return mData.end(); } + const_element_iter getDataBegin() const { return mData.cbegin(); } + const_element_iter getDataEnd() const { return mData.cend(); } U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } @@ -266,7 +265,7 @@ public: U8 idx = mChildMap[i]; if (idx != NO_CHILD_NODES) { - LLOctreeNode* child = mChild[idx]; + oct_node* child = mChild[idx]; if (child->getOctant() != i) { @@ -284,7 +283,7 @@ public: oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) { - LLOctreeNode* node = this; + oct_node* node = this; if (node->isInside(pos, rad)) { @@ -306,7 +305,7 @@ public: } else if (!node->contains(rad) && node->getParent()) { //if we got here, data does not exist in this node - return ((LLOctreeNode*) node->getParent())->getNodeAt(pos, rad); + return ((oct_node*) node->getParent())->getNodeAt(pos, rad); } return node; @@ -321,7 +320,7 @@ public: OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL; return false; } - LLOctreeNode* parent = getOctParent(); + oct_node* parent = getOctParent(); ND_OCTREE_LOG << "Inserting data, this->getSize " << this->getSize() << " this->getElementCount() " << this->getElementCount() << " this->getChildCount() " << this->getChildCount() << std::endl << " this->mMin " << this->mMin << " this->mMax " << this->mMax << std::endl @@ -338,12 +337,8 @@ public: (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here ND_OCTREE_LOG << "Inserting data into this" << ND_OCTREE_LOG_END; - - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -376,7 +371,7 @@ public: size.mul(0.5f); //push center in direction of data - LLOctreeNode::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); // handle case where floating point number gets too small LLVector4a val; @@ -394,12 +389,8 @@ public: // { ND_OCTREE_LOG << "Adding to parent and exit" << ND_OCTREE_LOG_END; - - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -427,7 +418,7 @@ public: llassert(size[0] >= gOctreeMinSize*0.5f); //make the new kid - child = new LLOctreeNode(center, size, this); + child = new oct_node(center, size, this); addChild(child); child->insert(data); @@ -462,28 +453,25 @@ public: } void _remove(T* data, S32 i) - { //precondition -- mElementCount > 0, idx is in range [0, mElementCount) + { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount()) - mElementCount--; data->setBinIndex(-1); - if (mElementCount > 0) + const U32 new_element_count = getElementCount() - 1; + if (new_element_count > 0) { - if (mElementCount != i) + if (new_element_count != i) { - mData[i] = mData[mElementCount]; //might unref data, do not access data after this point + mData[i] = mData[new_element_count]; //might unref data, do not access data after this point mData[i]->setBinIndex(i); } - mData[mElementCount] = NULL; + mData[new_element_count] = NULL; mData.pop_back(); - mDataEnd = &mData[mElementCount]; } else { mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; } this->notifyRemoval(data); @@ -496,7 +484,7 @@ public: S32 i = data->getBinIndex(); - if (i >= 0 && i < mElementCount) + if (i >= 0 && i < getElementCount()) { if (mData[i] == data) { //found it @@ -539,7 +527,8 @@ public: void removeByAddress(T* data) { - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { if (mData[i] == data) { //we have data @@ -551,7 +540,7 @@ public: for (U32 i = 0; i < getChildCount(); i++) { //we don't contain data, so pass this guy down - LLOctreeNode* child = (LLOctreeNode*) getChild(i); + oct_node* child = (oct_node*) getChild(i); child->removeByAddress(data); } } @@ -709,22 +698,20 @@ protected: oct_node* mParent; U8 mOctant; - LLOctreeNode* mChild[8]; + oct_node* mChild[8]; U8 mChildMap[8]; U32 mChildCount; element_list mData; - element_iter mDataEnd; - U32 mElementCount; }; //just like a regular node, except it might expand on insert and compress on balance -template -class LLOctreeRoot : public LLOctreeNode +template +class LLOctreeRoot : public LLOctreeNode { public: - typedef LLOctreeNode BaseType; - typedef LLOctreeNode oct_node; + typedef LLOctreeNode BaseType; + typedef LLOctreeNode oct_node; LLOctreeRoot(const LLVector4a& center, const LLVector4a& size, @@ -805,7 +792,7 @@ public: oct_node* node = this->getNodeAt(data); if (node == this) { - LLOctreeNode::insert(data); + oct_node::insert(data); } else if (node->isInside(data->getPositionGroup())) { @@ -825,13 +812,13 @@ public: LLVector4a center, size; center = this->getCenter(); size = this->getSize(); - LLOctreeNode::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); this->setCenter(center); size.mul(2.f); this->setSize(size); this->updateMinMax(); } - LLOctreeNode::insert(data); + oct_node::insert(data); } else { @@ -843,7 +830,7 @@ public: //expand this node LLVector4a newcenter(center); - LLOctreeNode::pushCenter(newcenter, size, data); + oct_node::pushCenter(newcenter, size, data); this->setCenter(newcenter); LLVector4a size2 = size; size2.mul(2.f); @@ -853,11 +840,11 @@ public: llassert(size[0] >= gOctreeMinSize); //copy our children to a new branch - LLOctreeNode* newnode = new LLOctreeNode(center, size, this); + oct_node* newnode = new oct_node(center, size, this); for (U32 i = 0; i < this->getChildCount(); i++) { - LLOctreeNode* child = this->getChild(i); + oct_node* child = this->getChild(i); newnode->addChild(child); } @@ -883,8 +870,8 @@ public: //======================== // LLOctreeTraveler //======================== -template -void LLOctreeTraveler::traverse(const LLOctreeNode* node) +template +void LLOctreeTraveler::traverse(const LLOctreeNode* node) { node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) @@ -893,8 +880,8 @@ void LLOctreeTraveler::traverse(const LLOctreeNode* node) } } -template -void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) +template +void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) { for (U32 i = 0; i < node->getChildCount(); i++) { diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 21803e6817..2b192b45de 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -388,7 +388,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } -class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: const LLVolumeFace* mFace; @@ -398,7 +398,7 @@ public: mFace = face; } - virtual void visit(const LLOctreeNode* branch) + virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME @@ -416,8 +416,7 @@ public: min = *(tri->mV[0]); max = *(tri->mV[0]); - for (LLOctreeNode::const_element_iter iter = - branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) + for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { //for each triangle in node //stretch by triangles in node @@ -2463,6 +2462,13 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) //copy out indices S32 num_indices = idx.size() / 2; + const S32 indices_to_discard = num_indices % 3; + if (indices_to_discard > 0) + { + // Invalid number of triangle indices + LL_WARNS() << "Incomplete triangle discarded from face! Indices count " << num_indices << " was not divisible by 3. face index: " << i << " Total: " << face_count << LL_ENDL; + num_indices -= indices_to_discard; + } face.resizeIndices(num_indices); if (num_indices > 2 && !face.mIndices) @@ -2478,8 +2484,7 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) } U16* indices = (U16*) &(idx[0]); - U32 count = idx.size()/2; - for (U32 j = 0; j < count; ++j) + for (U32 j = 0; j < num_indices; ++j) { face.mIndices[j] = indices[j]; } @@ -3900,8 +3905,8 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, #if DEBUG_SILHOUETTE_EDGE_MAP //for each triangle - U32 count = face.mNumIndices; - for (U32 j = 0; j < count/3; j++) { + U32 tri_count = face.mNumIndices / 3; + for (U32 j = 0; j < tri_count; j++) { //get vertices S32 v1 = face.mIndices[j*3+0]; S32 v2 = face.mIndices[j*3+1]; @@ -3919,7 +3924,7 @@ void LLVolume::generateSilhouetteVertices(std::vector &vertices, continue; } - if (nIndex >= (S32) count/3) { + if (nIndex >= (S32)tri_count) { continue; } //get neighbor vertices @@ -4211,13 +4216,13 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en } else { - if (!face.mOctree) + if (!face.getOctree()) { face.createOctree(); } LLOctreeTriangleRayIntersect intersect(start, dir, &face, &closest_t, intersection, tex_coord, normal, tangent_out); - intersect.traverse(face.mOctree); + intersect.traverse(face.getOctree()); if (intersect.mHitFace) { hit_face = i; @@ -4772,6 +4777,7 @@ LLVolumeFace::LLVolumeFace() : #endif mWeightsScrubbed(FALSE), mOctree(NULL), + mOctreeTriangles(NULL), mOptimized(FALSE) { mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); @@ -4801,8 +4807,9 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mJointIndices(NULL), #endif mWeightsScrubbed(FALSE), - mOctree(NULL) -{ + mOctree(NULL), + mOctreeTriangles(NULL) +{ mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3); mCenter = mExtents+2; *this = src; @@ -4942,8 +4949,7 @@ void LLVolumeFace::freeData() mJustWeights = NULL; #endif - delete mOctree; - mOctree = NULL; + destroyOctree(); } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -4951,8 +4957,7 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME //tree for this face is no longer valid - delete mOctree; - mOctree = NULL; + destroyOctree(); LL_CHECK_MEMORY BOOL ret = FALSE ; @@ -5675,23 +5680,28 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME - if (mOctree) + if (getOctree()) { return; } ND_OCTREE_LOG << "Creating octree with scale " << scaler << " mNumIndices " << mNumIndices << ND_OCTREE_LOG_END; + llassert(mNumIndices % 3 == 0); - mOctree = new LLOctreeRoot(center, size, NULL); + mOctree = new LLOctreeRoot(center, size, NULL); new LLVolumeOctreeListener(mOctree); + const U32 num_triangles = mNumIndices / 3; + // Initialize all the triangles we need + mOctreeTriangles = new LLVolumeTriangle[num_triangles]; - for (U32 i = 0; i < mNumIndices; i+= 3) + for (U32 triangle_index = 0; triangle_index < num_triangles; ++triangle_index) { //for each triangle - LLPointer tri = new LLVolumeTriangle(); + const U32 index = triangle_index * 3; + LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; - const LLVector4a& v0 = mPositions[mIndices[i]]; - const LLVector4a& v1 = mPositions[mIndices[i+1]]; - const LLVector4a& v2 = mPositions[mIndices[i+2]]; + const LLVector4a& v0 = mPositions[mIndices[index]]; + const LLVector4a& v1 = mPositions[mIndices[index + 1]]; + const LLVector4a& v2 = mPositions[mIndices[index + 2]]; //store pointers to vertex data tri->mV[0] = &v0; @@ -5699,9 +5709,9 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe tri->mV[2] = &v2; //store indices - tri->mIndex[0] = mIndices[i]; - tri->mIndex[1] = mIndices[i+1]; - tri->mIndex[2] = mIndices[i+2]; + tri->mIndex[0] = mIndices[index]; + tri->mIndex[1] = mIndices[index + 1]; + tri->mIndex[2] = mIndices[index + 2]; //get minimum point LLVector4a min = v0; @@ -5726,7 +5736,7 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe tri->mRadius = size.getLength3().getF32() * scaler; - ND_OCTREE_LOG << "insertion " << i + ND_OCTREE_LOG << "insertion " << index << " tri.mV " << *tri->mV[0] << "/" << *tri->mV[1] << "/" << *tri->mV[2] << " tri.mIndex " << tri->mIndex[0] << "/" << tri->mIndex[1] << "/" << tri->mIndex[2] << ND_OCTREE_LOG_END; @@ -5752,6 +5762,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe } } +void LLVolumeFace::destroyOctree() +{ + delete mOctree; + mOctree = NULL; + delete[] mOctreeTriangles; + mOctreeTriangles = NULL; +} + +const LLOctreeNode* LLVolumeFace::getOctree() const +{ + return mOctree; +} + void LLVolumeFace::swapData(LLVolumeFace& rhs) { @@ -6623,6 +6646,7 @@ void LLVolumeFace::allocateJointIndices(S32 num_verts) void LLVolumeFace::resizeIndices(S32 num_indices) { ll_aligned_free_16(mIndices); + llassert(num_indices % 3 == 0); if (num_indices) { diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index e2afee35d5..079ca8ac72 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -35,7 +35,8 @@ class LLVolumeParams; class LLProfile; class LLPath; -template class LLOctreeNode; +template class LLPointer; +template class LLOctreeNode; class LLVolumeFace; class LLVolume; @@ -913,6 +914,9 @@ public: bool cacheOptimize(); void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); + void destroyOctree(); + // Get a reference to the octree, which may be null + const LLOctreeNode* getOctree() const; enum { @@ -980,13 +984,14 @@ public: // Which joints are rigged to, and the bounding box of any rigged // vertices per joint. LLJointRiggingInfoTab mJointRiggingInfoTab; - - LLOctreeNode* mOctree; //whether or not face has been cache optimized BOOL mOptimized; private: + LLOctreeNode* mOctree; + LLVolumeTriangle* mOctreeTriangles; + BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE); diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index fb232d5f6c..6894d04d3c 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -75,7 +75,7 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c } -LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode* node) +LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode* node) { node->addListener(this); } @@ -85,13 +85,12 @@ LLVolumeOctreeListener::~LLVolumeOctreeListener() } -void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child) +void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, + LLOctreeNode* child) { new LLVolumeOctreeListener(child); } - LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) @@ -108,7 +107,7 @@ LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& sta mEnd.setAdd(mStart, mDir); } -void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode* node) +void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode* node) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); @@ -122,9 +121,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode } } -void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) +void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) { - for (LLOctreeNode::const_element_iter iter = + for (typename LLOctreeNode::const_element_iter iter = node->getDataBegin(); iter != node->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -219,7 +218,7 @@ const F32& LLVolumeTriangle::getBinRadius() const //TEST CODE -void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) +void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -256,7 +255,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) } //children fit, check data - for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); + for (typename LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -273,4 +272,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) } } - diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index b2bc440368..d65bca5e52 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -77,11 +77,11 @@ public: }; -class alignas(16) LLVolumeOctreeListener : public LLOctreeListener +class alignas(16) LLVolumeOctreeListener : public LLOctreeListener { LL_ALIGN_NEW public: - LLVolumeOctreeListener(LLOctreeNode* node); + LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) @@ -96,11 +96,9 @@ public: } //LISTENER FUNCTIONS - virtual void handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child); + virtual void handleChildAddition(const LLOctreeNode* parent, LLOctreeNode* child); virtual void handleStateChange(const LLTreeNode* node) { } - virtual void handleChildRemoval(const LLOctreeNode* parent, - const LLOctreeNode* child) { } + virtual void handleChildRemoval(const LLOctreeNode* parent, const LLOctreeNode* child) { } virtual void handleInsertion(const LLTreeNode* node, LLVolumeTriangle* tri) { } virtual void handleRemoval(const LLTreeNode* node, LLVolumeTriangle* tri) { } virtual void handleDestruction(const LLTreeNode* node) { } @@ -111,7 +109,7 @@ public: LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; -class LLOctreeTriangleRayIntersect : public LLOctreeTraveler +class LLOctreeTriangleRayIntersect : public LLOctreeTraveler { public: const LLVolumeFace* mFace; @@ -129,14 +127,14 @@ public: const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); - void traverse(const LLOctreeNode* node); + void traverse(const LLOctreeNode* node); - virtual void visit(const LLOctreeNode* node); + virtual void visit(const LLOctreeNode* node); }; -class LLVolumeOctreeValidate : public LLOctreeTraveler +class LLVolumeOctreeValidate : public LLOctreeTraveler { - virtual void visit(const LLOctreeNode* branch); + virtual void visit(const LLOctreeNode* branch); }; #endif diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index 64de380107..6e0db19f4c 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -311,8 +311,9 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp) std::ostream& operator<<(std::ostream& s, const LLPartSysData &data) { s << "Flags: " << std::hex << data.mFlags; - s << " Pattern: " << std::hex << (U32) data.mPattern << "\n"; - s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; + s << "Pattern: " << std::hex << (U32) data.mPattern << "\n"; + s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; + s << "Particle Age: " << data.mPartData.mMaxAge << "\n"; s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n"; s << "Burst Rate: " << data.mBurstRate << "\n"; s << "Burst Radius: " << data.mBurstRadius << "\n"; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 4dbab8b59d..6d3b089d1f 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -391,6 +391,8 @@ void LLModel::setVolumeFaceData( U32 num_verts, U32 num_indices) { + llassert(num_indices % 3 == 0); + LLVolumeFace& face = mVolumeFaces[f]; face.resizeVertices(num_verts); @@ -904,7 +906,6 @@ LLSD LLModel::writeModel( LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm) { - std::string::size_type cur_offset = 0; LLSD header; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 40bde8935e..36f1f86853 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -746,6 +746,14 @@ bool LLGLManager::initGL() LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL; return false; } + + if (!mHasFramebufferObject) + { + mHasRequirements = FALSE; + + LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_framebuffer_object" << LL_ENDL; + return false; + } stop_glerror(); @@ -761,14 +769,6 @@ bool LLGLManager::initGL() //HACK always disable texture multisample, use FXAA instead mHasTextureMultisample = FALSE; -#if LL_WINDOWS -// FIRE-7603: Revert MAINT-804 because FBO's and shadows appear to be working now! - //if (mIsIntel && mGLVersion <= 3.f) - //{ //never try to use framebuffer objects on older intel drivers (crashy) - // mHasFramebufferObject = FALSE; - //} -// -#endif if (mHasFramebufferObject) { diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 7acb8aeeec..eb876450cf 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -133,7 +133,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mUsage = usage; mUseDepth = depth; - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) + if (sUseFBO || use_fbo) { if (depth) { diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index c8cea38461..ab6844d820 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -671,7 +671,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (file == NULL) { - LL_SHADER_LOADING_WARNS() << "GLSL Shader file not found: " << open_file_name << LL_ENDL; + LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL; return 0; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index c45941a198..942af90fd8 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -1872,7 +1872,14 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask) remove(mCursorPos, 1, FALSE); } } +// FIRE-32175 - Linux/SDL2: Alt-Tab pushes a tab character into scripts and notecards +#if LL_SDL2 + // catch spurious ALT+Tab + else if (!mask) +#else +// else +#endif // FIRE-32175 - Linux/SDL2: Alt-Tab pushes a tab character into scripts and notecards { // S32 spaces_needed = SPACES_PER_TAB - (offset % SPACES_PER_TAB); diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 090d8f409d..564920a5e2 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -181,3 +181,10 @@ endif (llwindow_HEADER_FILES) target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) target_include_directories( llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(CARBON_LIBRARY Carbon) + target_link_libraries(llwindow ${CARBON_LIBRARY}) +endif (DARWIN) + diff --git a/indra/llwindow/llkeyboardsdl2.cpp b/indra/llwindow/llkeyboardsdl2.cpp index 402feed1d5..594818869e 100644 --- a/indra/llwindow/llkeyboardsdl2.cpp +++ b/indra/llwindow/llkeyboardsdl2.cpp @@ -148,7 +148,7 @@ void LLKeyboardSDL::resetMaskKeys() mKeyLevel[KEY_CONTROL] = TRUE; } - if(mask & KMOD_LALT) + if(mask & KMOD_ALT) { mKeyLevel[KEY_ALT] = TRUE; } @@ -170,7 +170,7 @@ MASK LLKeyboardSDL::updateModifiers(const U32 mask) out_mask |= MASK_CONTROL; } - if(mask & KMOD_LALT) + if(mask & KMOD_ALT) { out_mask |= MASK_ALT; } @@ -252,7 +252,7 @@ MASK LLKeyboardSDL::currentMask(BOOL for_mouse_event) result |= MASK_SHIFT; if (mask & KMOD_CTRL) result |= MASK_CONTROL; - if (mask & KMOD_LALT) + if (mask & KMOD_ALT) result |= MASK_ALT; // For keyboard events, consider Meta keys equivalent to Control diff --git a/indra/llwindow/llwindowsdl2.cpp b/indra/llwindow/llwindowsdl2.cpp index 17bf62d7b5..3e6dcf1ea2 100644 --- a/indra/llwindow/llwindowsdl2.cpp +++ b/indra/llwindow/llwindowsdl2.cpp @@ -41,6 +41,10 @@ #include "llfindlocale.h" #include "llframetimer.h" +// if there is a better methood to get at the settings from llwindow/ let me know! -Zi +#include "llcontrol.h" +extern LLControlGroup gSavedSettings; + #ifdef LL_GLIB #include #endif @@ -130,7 +134,8 @@ namespace Atom XA_CLIPBOARD; Atom XA_TARGETS; Atom PVT_PASTE_BUFFER; - long const MAX_PASTE_BUFFER_SIZE = 16383; + // Unused in the current clipboard implementation -Zi + // long const MAX_PASTE_BUFFER_SIZE = 16383; void filterSelectionRequest( XEvent aEvent ) { @@ -277,11 +282,23 @@ bool LLWindowSDL::getSelectionText( Atom aSelection, Atom aType, LLWString &text maybe_lock_display(); Atom type; - int format{}; - unsigned long len{},remaining {}; + int format {}; + unsigned long len {}, size {}; unsigned char* data = nullptr; + + // get type and size of the clipboard contents first + XGetWindowProperty( mSDL_Display, mSDL_XWindowID, + PVT_PASTE_BUFFER, 0, 0, False, + AnyPropertyType, &type, &format, &len, + &size, &data); + XFree(data); + + // now get the real data, we don't really have a size limit here, but we need + // to tell the X11 clipboard how much space we have, which happens to be exactly + // the size of the current clipboard contents + unsigned long remaining {}; int res = XGetWindowProperty(mSDL_Display, mSDL_XWindowID, - PVT_PASTE_BUFFER, 0, MAX_PASTE_BUFFER_SIZE, False, + PVT_PASTE_BUFFER, 0, size, False, AnyPropertyType, &type, &format, &len, &remaining, &data); if (data && len) @@ -393,6 +410,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, // IME - International input compositing, i.e. for Japanese / Chinese text input // Preeditor means here the actual XUI input field currently in use + mIMEEnabled = false; mPreeditor = nullptr; #if LL_X11 @@ -661,7 +679,12 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B // IME - International input compositing, i.e. for Japanese / Chinese text input // Request the IME interface to show over-the-top compositing while typing - SDL_SetHint( SDL_HINT_IME_INTERNAL_EDITING, "1"); + mIMEEnabled = gSavedSettings.getBOOL("SDL2IMEEnabled"); + + if (mIMEEnabled) + { + SDL_SetHint( SDL_HINT_IME_INTERNAL_EDITING, "1"); + } if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 ) { @@ -883,7 +906,12 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B glClear(GL_COLOR_BUFFER_BIT); SDL_GL_SwapWindow(mWindow); - SDL_StartTextInput(); + // start text input immediately when IME is not enabled + if (!mIMEEnabled) + { + SDL_StartTextInput(); + } + //make sure multisampling is disabled by default glDisable(GL_MULTISAMPLE_ARB); @@ -1770,11 +1798,40 @@ void LLWindowSDL::gatherInput() static U64 previousTextinputTime = 0; SDL_Event event; + // mask to apply to the keyup/keydown modifiers to handle AltGr keys correctly + static U32 altGrMask = 0x00; + // Handle all outstanding SDL events while (SDL_PollEvent(&event)) { switch (event.type) { + case SDL_SYSWMEVENT: + { + XEvent e = event.syswm.msg->msg.x11.event; + if (e.type == KeyPress || e.type == KeyRelease) + { + // XLookupKeysym doesn't work here because of the weird way the "index" is + // tied to the e->state and we don't get the necessary information at this + // point, so we use the more expensive XLookupString which apparently knows + // all of the secrets inside XKeyEvent. -Zi + + KeySym ks; + static char str[256+1]; + XLookupString((XKeyEvent *) &e, str, 256, &ks, nullptr); + + if (ks == XK_ISO_Level3_Shift) + { + altGrMask = KMOD_RALT; + } + else if (ks == XK_Alt_R) + { + altGrMask = 0x00; + } + } + break; + } + case SDL_MOUSEWHEEL: if( event.wheel.y != 0 ) mCallbacks->handleScrollWheel(this, -event.wheel.y); @@ -1794,6 +1851,10 @@ void LLWindowSDL::gatherInput() { auto string = utf8str_to_utf16str( event.text.text ); mKeyModifiers = gKeyboard->currentMask( FALSE ); + if (altGrMask) + { + mKeyModifiers &= ~MASK_ALT; + } mInputType = "textinput"; for( auto key: string ) { @@ -1812,7 +1873,7 @@ void LLWindowSDL::gatherInput() case SDL_KEYDOWN: mKeyVirtualKey = event.key.keysym.sym; - mKeyModifiers = event.key.keysym.mod; + mKeyModifiers = event.key.keysym.mod & (~altGrMask); mInputType = "keydown"; // treat all possible Enter/Return keys the same @@ -1821,7 +1882,7 @@ void LLWindowSDL::gatherInput() mKeyVirtualKey = SDLK_RETURN; } - if (mKeyVirtualKey == SDLK_RETURN) + if (mKeyVirtualKey == SDLK_RETURN && mIMEEnabled) { // block spurious enter key events that break up IME entered lines in teh wrong places U64 eventTimeDiff = LLFrameTimer::getTotalTime() - previousTextinputTime; @@ -1854,7 +1915,7 @@ void LLWindowSDL::gatherInput() case SDL_KEYUP: mKeyVirtualKey = event.key.keysym.sym; - mKeyModifiers = event.key.keysym.mod; + mKeyModifiers = event.key.keysym.mod & (~altGrMask); mInputType = "keyup"; // treat all possible Enter/Return keys the same @@ -2636,6 +2697,10 @@ void* LLWindowSDL::createSharedContext() LLCoordScreen size; if (getSize(&size)) { + // tickle window size to fix font going blocky on login screen since SDL 2.24.0 + size.mX--; + setSize(size); + size.mX++; setSize(size); } @@ -2670,11 +2735,32 @@ void LLWindowSDL::toggleVSync(bool enable_vsync) } // +void LLWindowSDL::enableIME(bool b) +{ + mIMEEnabled = b; + + if (mIMEEnabled) + { + SDL_SetHint( SDL_HINT_IME_INTERNAL_EDITING, "1"); + SDL_StopTextInput(); + } + else + { + SDL_SetHint( SDL_HINT_IME_INTERNAL_EDITING, "0"); + SDL_StartTextInput(); + } +} + // IME - International input compositing, i.e. for Japanese / Chinese text input // Put the IME window at the right place (near current text input). // Point coordinates should be the top of the current text line. void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position) { + if (!mIMEEnabled) + { + return; + } + LLCoordWindow win_pos; convertCoords( position, &win_pos ); @@ -2690,6 +2776,11 @@ void LLWindowSDL::setLanguageTextInput(const LLCoordGL& position) // IME - International input compositing, i.e. for Japanese / Chinese text input void LLWindowSDL::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b) { + if (!mIMEEnabled) + { + return; + } + if (preeditor != mPreeditor && !b) { // This condition may occur with a call to diff --git a/indra/llwindow/llwindowsdl2.h b/indra/llwindow/llwindowsdl2.h index 05530f8766..83807d12db 100644 --- a/indra/llwindow/llwindowsdl2.h +++ b/indra/llwindow/llwindowsdl2.h @@ -136,6 +136,8 @@ public: /*virtual*/ void setTitle(const std::string& title); + void enableIME(bool b); + static std::vector getDynamicFallbackFontList(); // Not great that these are public, but they have to be accessible @@ -205,6 +207,7 @@ protected: SDL_GLContext mContext; SDL_Cursor* mSDLCursors[UI_CURSOR_COUNT]; LLPreeditor* mPreeditor; + bool mIMEEnabled; std::string mWindowTitle; double mOriginalAspectRatio; diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 5dbe61b99e..10abd6ae5b 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.5 +6.6.6 diff --git a/indra/newview/app_settings/camera/TPP.xml b/indra/newview/app_settings/camera/TPP.xml new file mode 100644 index 0000000000..00dde609af --- /dev/null +++ b/indra/newview/app_settings/camera/TPP.xml @@ -0,0 +1,120 @@ + + + AvatarSitRotation + + Comment + Avatar real sitting rotation used in preset + Persist + 1 + Type + Quaternion + Value + + 0 + 0 + 0 + 1 + + + CameraAngle + + Comment + Camera field of view angle (Radians) + Persist + 1 + Type + F32 + Value + 1.047197551 + + CameraOffsetBuild + + Comment + Default camera position relative to focus point when entering build mode + Persist + 1 + Type + Vector3 + Value + + -6 + 0 + 6 + + + CameraOffsetRearView + + Comment + Initial camera offset from avatar in Shoulder View + Persist + 1 + Type + Vector3 + Value + + -3 + -0.4 + -0.2 + + + CameraOffsetScale + + Comment + Scales the default offset + Persist + 1 + Type + F32 + Value + 1.1 + + CameraZoomFraction + + Comment + Mousewheel driven fraction of zoom + Persist + 1 + Type + F32 + Value + 0.90322577953338623 + + FocusOffsetRearView + + Comment + Initial focus point offset relative to avatar for the camera preset Shoulder View (x-axis is forward) + Persist + 1 + Type + Vector3D + Value + + 0.9 + -0.7 + 0.2 + + + PresetCameraActive + + Comment + Name of currently selected preference + Persist + 1 + Type + String + Value + Default + + TrackFocusObject + + Comment + Camera tracks last object zoomed on + Persist + 1 + Type + Boolean + Value + 1 + + + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e3ead578ed..b7e35e8559 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2928,7 +2928,7 @@ Type F32 Value - 20.0 + 40.0 DiskCacheDirName @@ -9567,17 +9567,6 @@ Value 1 - MiniMapPropertyLines - - Comment - Show property boundaries on the mini-map - Persist - 1 - Type - Boolean - Value - 0 - MiniMapPrimMaxRadius Comment @@ -9631,6 +9620,9 @@ Type Boolean Value + 1 MiniMapScale @@ -9644,6 +9636,17 @@ Value 128.0 + MiniMapShowPropertyLines + + Comment + Whether or not to show parcel borders on the MiniMap. + Persist + 1 + Type + Boolean + Value + 1 + MouseSensitivity Comment @@ -9917,13 +9920,13 @@ NonvisibleObjectsInMemoryTime Comment - Number of frames non-visible objects stay in memory before being removed. 0 means never to remove. + Number of frames non-visible objects stay in memory before being removed. 0 means max. Persist 1 Type U32 Value - 300 + 64 NoPreload @@ -14213,7 +14216,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type U32 Value - 1024 + 2048 SceneLoadLowMemoryBound @@ -26247,6 +26250,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value -4 + SDL2IMEEnabled + + Comment + Enable the international input method editor for Japanese, Chinese, etc. + Persist + 1 + Type + Boolean + Value + 0 + FSLocalMeshScaleAlwaysMeters Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 02d83925ea..b26194f278 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2; uniform float env_intensity; uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +#ifdef HAS_ALPHA_MASK uniform float minimum_alpha; #endif @@ -227,11 +227,12 @@ void main() vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); diffcol.rgb *= vertex_color.rgb; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) - - // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points - float bias = 0.001953125; // 1/512, or half an 8-bit quantization - if (diffcol.a < minimum_alpha-bias) +#ifdef HAS_ALPHA_MASK +#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND + if (diffcol.a*vertex_color.a < minimum_alpha) +#else + if (diffcol.a < minimum_alpha) +#endif { discard; } diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 2241a12545..6cfc0b0be2 100644 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -2,15 +2,15 @@ - - + + - - + + @@ -23,58 +23,58 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - + + + @@ -86,29 +86,29 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -123,49 +123,49 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + @@ -200,30 +200,30 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - - - + + + + diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index c2c57bc14d..d3780f0161 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -1731,7 +1731,6 @@ LLUUID cmdline_partial_name2key(std::string partial_name) LLStringUtil::replaceString(partial_name, ".", " "); FSRadar::entry_map_t radar_list = FSRadar::getInstance()->getRadarList(); - FSRadar::entry_map_t::iterator it_end = radar_list.end(); for (const auto& [avid, entry] : radar_list) { av_name = entry->getUserName(); diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae new file mode 100644 index 0000000000..085b2c7309 --- /dev/null +++ b/indra/newview/cube.dae @@ -0,0 +1,103 @@ + + + + + modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26 + + 2018-10-25T16:29:03Z + 2022-02-18T00:00:00Z + + Y_UP + + + + + + + + + + + + + + + + 0 0 0 1 + + + 0.137255 0.403922 0.870588 1 + + + 0.5 0.5 0.5 1 + + + 16 + + + 0 0 0 1 + + + 1 + + + 1 + + + + + + + + + + + + + + -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 + + + + + + + + + + + + + + + + 0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/fschathistory.cpp b/indra/newview/fschathistory.cpp index 1ca779bd0b..e3923c60e0 100644 --- a/indra/newview/fschathistory.cpp +++ b/indra/newview/fschathistory.cpp @@ -1292,6 +1292,12 @@ void FSChatHistory::setFocus(BOOL b) { LLTextEditor::setFocus(b); + // IME - Don't do anything here if IME is disabled + if (!gSavedSettings.getBOOL("SDL2IMEEnabled")) + { + return; + } + // IME - International input compositing, i.e. for Japanese / Chinese text input updateChatInputLine(); diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 83160b8453..37b8e02b0d 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -385,11 +385,29 @@ DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage" ClearErrors +INSTALL_FILES_START: + Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer # This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py %%INSTALL_FILES%% +IfErrors 0 INSTALL_FILES_DONE + StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE + MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START + # MB_ABORTRETRYIGNORE does not accept IDIGNORE + Goto INSTALL_FILES_DONE + +INSTALL_FILES_CANCEL: + # We are quiting, cleanup. + # Silence warnings from RemoveProgFilesOnInst. + StrCpy $SKIP_DIALOGS "true" + Call RemoveProgFilesOnInst + MessageBox MB_OK $(ErrorSecondLifeInstallSupport) + Quit + +INSTALL_FILES_DONE: + # Pass the installer's language to the client to use as a default StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" @@ -721,7 +739,9 @@ Function RemoveProgFilesOnInst Push $0 StrCpy $0 0 -PREINSTALLREMOVE: +ClearErrors + +PREINSTALL_REMOVE: # Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575 # Remove VMP @@ -742,17 +762,17 @@ RMDir /r "$INSTDIR\llplugin" IntOp $0 $0 + 1 -IfErrors 0 PREINSTALLDONE - IntCmp $0 1 PREINSTALLREMOVE #try again once - StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE - MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE +IfErrors 0 PREINSTALL_DONE + IntCmp $0 1 PREINSTALL_REMOVE #try again once + StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE + MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE # MB_ABORTRETRYIGNORE does not accept IDIGNORE - Goto PREINSTALLDONE + Goto PREINSTALL_DONE -PREINSTALLFAIL: +PREINSTALL_FAIL: Quit -PREINSTALLDONE: +PREINSTALL_DONE: # We are no longer including release notes with the viewer, so remove them. ;Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk" diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi index 0160af157e..f0284cdf37 100644 Binary files a/indra/newview/installers/windows/lang_da.nsi and b/indra/newview/installers/windows/lang_da.nsi differ diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi index d36873a462..164f165f50 100755 --- a/indra/newview/installers/windows/lang_de.nsi +++ b/indra/newview/installers/windows/lang_de.nsi @@ -70,6 +70,10 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Firestorm kann nicht entfernt ; CheckNetworkConnection LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..." +; error during installation +LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Firestorm konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert." +LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://www.firestormviewer.org/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://www.firestormviewer.org/support/." + ; ask to remove user's data files LangString RemoveDataFilesMB ${LANG_GERMAN} "Einstellungs- und Cache-Dateien in Dokumente und Einstellungen löschen?" diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi index 9eb0e4d618..911185e04b 100644 Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi index bfdbe6e9c7..37897d5981 100755 Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi index f3de969c98..fc263d1eab 100755 Binary files a/indra/newview/installers/windows/lang_fr.nsi and b/indra/newview/installers/windows/lang_fr.nsi differ diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi index 7388d62f49..34e3bdcebd 100755 Binary files a/indra/newview/installers/windows/lang_it.nsi and b/indra/newview/installers/windows/lang_it.nsi differ diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi index 3c01ecebc4..8322d86f81 100755 Binary files a/indra/newview/installers/windows/lang_ja.nsi and b/indra/newview/installers/windows/lang_ja.nsi differ diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi index 5cb00d6270..2a8ea7ef1d 100644 Binary files a/indra/newview/installers/windows/lang_pl.nsi and b/indra/newview/installers/windows/lang_pl.nsi differ diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi index f2ab414639..f25e8f00e0 100755 Binary files a/indra/newview/installers/windows/lang_pt-br.nsi and b/indra/newview/installers/windows/lang_pt-br.nsi differ diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi index 131b5377de..3f75a5b580 100755 Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi index 19006b9540..b19fdbf4c5 100755 Binary files a/indra/newview/installers/windows/lang_tr.nsi and b/indra/newview/installers/windows/lang_tr.nsi differ diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi index 0c5ead4b1a..81e7fab892 100755 Binary files a/indra/newview/installers/windows/lang_zh.nsi and b/indra/newview/installers/windows/lang_zh.nsi differ diff --git a/indra/newview/lggcontactsets.cpp b/indra/newview/lggcontactsets.cpp index f06f1b45a2..8273fb2d71 100644 --- a/indra/newview/lggcontactsets.cpp +++ b/indra/newview/lggcontactsets.cpp @@ -556,7 +556,6 @@ string_vec_t LGGContactSets::getFriendSets(const LLUUID& friend_id) { string_vec_t sets{}; - contact_set_map_t::iterator set_itr_end = mContactSets.end(); for (const auto& [set_name, set] : mContactSets) { if (set->hasFriend(friend_id)) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 757af5540b..5984f42118 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -103,6 +103,7 @@ #include "stringize.h" #include "boost/foreach.hpp" #include "llcorehttputil.h" +#include "lluiusage.h" // [RLVa:KB] - Checked: 2011-11-04 (RLVa-1.4.4a) #include "rlvactions.h" #include "rlvhandler.h" @@ -660,6 +661,8 @@ void LLAgent::ageChat() //----------------------------------------------------------------------------- void LLAgent::moveAt(S32 direction, bool reset) { + LLUIUsage::instance().logCommand("Agent.MoveAt"); + mMoveTimer.reset(); LLFirstUse::notMoving(false); @@ -4813,6 +4816,7 @@ void LLAgent::startTeleportRequest() } if (hasPendingTeleportRequest()) { + LLUIUsage::instance().logCommand("Agent.StartTeleportRequest"); mTeleportCanceled.reset(); if (!isMaturityPreferenceSyncedWithServer()) { diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 69a43cbe3d..5784d915d6 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -61,6 +61,11 @@ enum ECameraPreset /** Current view when a preset is saved */ CAMERA_PRESET_CUSTOM, +// Third Person Perspective camera + /** "Based on Penny Patton's optimized camera settings" */ + CAMERA_PRESET_TPP_VIEW, +// + // [RLVa:KB] - @setcam_eyeoffset and @setcam_focusoffset /* Used by RLVa */ CAMERA_RLV_SETCAM_VIEW, diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 1c4a43860d..5a77e44399 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -60,6 +60,8 @@ #include "llappviewer.h" #include "llcoros.h" #include "lleventcoro.h" +#include "lluiusage.h" + #include "llavatarpropertiesprocessor.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) @@ -1470,6 +1472,9 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, bool replace, LLPointer cb) { + LL_DEBUGS("UIUsage") << "wearItemsOnAvatar" << LL_ENDL; + LLUIUsage::instance().logCommand("Avatar.WearItem"); + bool first = true; LLInventoryObject::const_object_list_t items_to_link; @@ -3133,6 +3138,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName() << "'" << LL_ENDL; + LLUIUsage::instance().logCommand("Avatar.WearCategory"); if (gAgentCamera.cameraCustomizeAvatar()) { @@ -4484,6 +4490,8 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo { if (!isAgentAvatarValid()) return; + LLUIUsage::instance().logCommand("Avatar.CreateNewOutfit"); + LL_DEBUGS("Avatar") << "creating new outfit" << LL_ENDL; gAgentWearables.notifyLoadingStarted(); @@ -4525,6 +4533,9 @@ void LLAppearanceMgr::wearBaseOutfit() void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer cb /*= NULL*/, bool immediate_delete /*= false*/) // [/SL:KB] { + LL_DEBUGS("UIUsage") << "removeItemsFromAvatar" << LL_ENDL; + LLUIUsage::instance().logCommand("Avatar.RemoveItem"); + if (ids_to_remove.empty()) { LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL; @@ -5054,6 +5065,8 @@ public: "Quick Appearance"); if ( gInventory.getCategory( folder_uuid ) != NULL ) { + // Assume this is coming from the predefined avatars web floater + LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance"); LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false); // *TODOw: This may not be necessary if initial outfit is chosen already -- josh diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fc81121cf5..820f1e3395 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -635,7 +635,7 @@ static void settings_to_globals() gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); - LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); + LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); #if LL_DARWIN gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); @@ -2920,10 +2920,24 @@ bool LLAppViewer::initConfiguration() //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); LLXMLNodePtr root; - BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); + BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); if (!success) { - LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + if (gDirUtilp->fileExists(settings_file_list)) + { + LL_ERRS() << "Cannot load default configuration file settings_files.xml. " + << "Please reinstall viewer from https://secondlife.com/support/downloads/ " + << "and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } + else + { + LL_ERRS() << "Default configuration file settings_files.xml not found. " + << "Please reinstall viewer from https://secondlife.com/support/downloads/ " + << "and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } } mSettingsLocationList = new SettingsFiles(); @@ -4254,7 +4268,7 @@ void LLAppViewer::cleanupSavedSettings() } } - gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale ); + gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting()); // Some things are cached in LLAgent. if (gAgent.isInitialized()) @@ -5094,15 +5108,23 @@ bool LLAppViewer::initCache() // initialize the new disk cache using saved settings const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); + const U32 MB = 1024 * 1024; + const uintmax_t MIN_CACHE_SIZE = 256 * MB; + const uintmax_t MAX_CACHE_SIZE = 9984ll * MB; + const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB; + const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); + // Better cache size control + //const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); + //const F6432 texture_cache_percent = 100.0 - disk_cache_percent; + // + // note that the maximum size of this cache is defined as a percentage of the // total cache size - the 'CacheSize' pref - for all caches. - // Better asset cache size control - //const unsigned int cache_total_size_mb = gSavedSettings.getU32("CacheSize"); - //const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); - //const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100; + // Better cache size control + //const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100); const unsigned int disk_cache_mb = gSavedSettings.getU32("FSDiskCacheSize"); + const uintmax_t disk_cache_size = disk_cache_mb * 1024ULL * 1024ULL; // - const uintmax_t disk_cache_bytes = disk_cache_mb * 1024ULL * 1024ULL; const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); bool texture_cache_mismatch = false; @@ -5181,7 +5203,7 @@ bool LLAppViewer::initCache() // const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); - LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info); + LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info); if (!read_only) { @@ -5241,22 +5263,17 @@ bool LLAppViewer::initCache() LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache")); // Init the texture cache - // Allocate 80% of the cache size for textures - const S32 MB = 1024 * 1024; - const S64 MIN_CACHE_SIZE = 256 * MB; - const S64 MAX_CACHE_SIZE = 9984ll * MB; + // Allocate the remaining percent which is not allocated to the disk cache + // Better cache size control + //const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100); + const S64 texture_cache_size = (S64)cache_total_size; + // - S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; - cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); - - S64 texture_cache_size = cache_size; - - S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); - texture_cache_size -= extra; + LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()); - return true; + return true; } void LLAppViewer::addOnIdleCallback(const boost::function& cb) @@ -5983,8 +6000,7 @@ void LLAppViewer::idle() audio_update_wind(false); // this line actually commits the changes we've made to source positions, etc. - const F32 max_audio_decode_time = 0.002f; // 2 ms decode time - gAudiop->idle(max_audio_decode_time); + gAudiop->idle(); } } diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index f17deda451..672afb6923 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -78,6 +78,7 @@ #include "llsidepanelinventory.h" #include "llavatarname.h" #include "llagentui.h" +#include "lluiusage.h" // [RLVa:KB] - Checked: 2011-04-11 (RLVa-1.3.0) #include "rlvactions.h" #include "rlvcommon.h" @@ -164,7 +165,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin payload["id"] = id; payload["name"] = name; - LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); + LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); // add friend to recent people list LLRecentPeople::instance().add(id); @@ -1788,6 +1789,8 @@ bool LLAvatarActions::handleUnfreeze(const LLSD& notification, const LLSD& respo void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message) { const LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); + LLUIUsage::instance().logCommand("Agent.SendFriendRequest"); + send_improved_im(target_id, target_name, message, diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp index ea39f73a61..699f7d54b5 100644 --- a/indra/newview/llavatarpropertiesprocessor.cpp +++ b/indra/newview/llavatarpropertiesprocessor.cpp @@ -147,8 +147,18 @@ void LLAvatarPropertiesProcessor::sendRequest(const LLUUID& avatar_id, EAvatarPr void LLAvatarPropertiesProcessor::sendGenericRequest(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string &method) { - // indicate we're going to make a request - addPendingRequest(avatar_id, type); +// First run at profile behaviour fix for OpenSim +#ifdef OPENSIM // maintain legacy behaviour for now + // Suppress duplicate requests while waiting for a response from the network + if (isPendingRequest(avatar_id, type)) + { + // waiting for a response, don't re-request + return; + } +#endif //OPENSIM +// + // indicate we're going to make a request + addPendingRequest(avatar_id, type); std::vector strings; strings.push_back(avatar_id.asString()); @@ -178,11 +188,36 @@ void LLAvatarPropertiesProcessor::initAgentProfileCapRequest(const LLUUID& avata LLCoros::instance().launch("requestAgentUserInfoCoro", boost::bind(requestAvatarPropertiesCoro, cap_url, avatar_id)); } - void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avatar_id) { - sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); +// maintian legacy behaviour for OpenSim + if(!gAgent.getRegionCapability("AgentProfile").empty()) + { +// + sendRequest(avatar_id, APT_PROPERTIES, "AvatarPropertiesRequest"); + } +// maintian legacy behaviour for OpenSim +#ifdef OPENSIM + else + { + // this is the startup state when send_complete_agent_movement() message is sent. + // Before this, the AvatarPropertiesRequest message + // won't work so don't bother trying + if (LLStartUp::getStartupState() <= STATE_AGENT_SEND) + { + return; + } + + if (isPendingRequest(avatar_id, APT_PROPERTIES)) + { + // waiting for a response, don't re-request + return; + } + sendAvatarPropertiesRequestMessage(avatar_id); + } +#endif } +// void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id) { diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h index f778634d25..51198e8898 100644 --- a/indra/newview/llavatarpropertiesprocessor.h +++ b/indra/newview/llavatarpropertiesprocessor.h @@ -215,6 +215,10 @@ public: void sendAvatarGroupsRequest(const LLUUID& avatar_id); void sendAvatarTexturesRequest(const LLUUID& avatar_id); void sendAvatarClassifiedsRequest(const LLUUID& avatar_id); + // enable legacy profile access for OpenSim to work with new profile + void sendGenericRequestLegacy(const LLUUID& avatar_id, EAvatarProcessorType type, const std::string method); + void sendAvatarPropertiesRequestLegacy(const LLUUID& avatar_id); + // // Duplicate pick info requests are not suppressed. void sendPickInfoRequest(const LLUUID& creator_id, const LLUUID& pick_id); diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 5f2f26cf8f..51d4e94430 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -53,6 +53,7 @@ #include "llviewerobjectlist.h" #include "llvoavatar.h" #include "llavataractions.h" +#include "lluiusage.h" // Firestorm includes #include "fscommon.h" @@ -302,6 +303,8 @@ void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const void LLAvatarTracker::terminateBuddy(const LLUUID& id) { LL_DEBUGS() << "LLAvatarTracker::terminateBuddy()" << LL_ENDL; + LLUIUsage::instance().logCommand("Agent.TerminateFriendship"); + LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id); if(!buddy) return; mBuddyInfo.erase(id); @@ -800,7 +803,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) // we were tracking someone who went offline deleteTrackingData(); } - } + // } [FIRE-32324] least invasive change move this brace after the if. LL fix should follow sometime soon //[FIX FIRE-3522 : SJ] Notify Online/Offline to Nearby Chat even if chat_notify isnt true // Attempt to speed up things a little @@ -812,6 +815,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) // Look up the name of this agent for the notification LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload)); } + } // [FIRE-32324] least invasive change move this brace after the if mModifyMask |= LLFriendObserver::ONLINE; instance().notifyObservers(); diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp index 8cf40652b7..015af4d725 100644 --- a/indra/newview/llchatbar.cpp +++ b/indra/newview/llchatbar.cpp @@ -569,8 +569,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL // how to chat gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE); - LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command - // Look for "/20 foo" channel chats. S32 channel = 0; LLWString out_text = stripChannelNumber(wtext, &channel); diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 80d810d159..036ff17074 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -290,9 +290,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) pickerp->getCurG (), pickerp->getCurB (), subject->mColor.mV[VALPHA] ); // keep current alpha - subject->mColor = updatedColor; - subject->setControlValue(updatedColor.getValue()); - pickerp->setRevertOnCancel(TRUE); + + bool color_changed = subject->mColor != updatedColor; + if (color_changed) + { + subject->mColor = updatedColor; + subject->setControlValue(updatedColor.getValue()); + } + if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback) { subject->mOnCancelCallback( subject, LLSD()); @@ -306,6 +311,13 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) // just commit change subject->onCommit (); } + + if (pick_op == COLOR_CANCEL || pick_op == COLOR_SELECT) + { + // both select and cancel close LLFloaterColorPicker + // but COLOR_CHANGE does not + subject->setFocus(TRUE); + } } } } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 79f474fde5..faf4556dd9 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -133,6 +133,7 @@ public: inline LLFace* getFace(const S32 i) const; inline S32 getNumFaces() const; face_list_t& getFaces() { return mFaces; } + const face_list_t& getFaces() const { return mFaces; } //void removeFace(const S32 i); // SJB: Avoid using this, it's slow LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 959b7ad6dc..6caecb9dab 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -52,6 +52,7 @@ #include "fsperfstats.h" // performance stats support BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; +BOOL LLDrawPoolAlpha::sShowDebugAlphaRigged = FALSE; #define current_shader (LLGLSLShader::sCurBoundShaderPtr) @@ -59,6 +60,7 @@ static BOOL deferred_render = FALSE; // minimum alpha before discarding a fragment static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255 + // minimum alpha before discarding a fragment when rendering impostors static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f; @@ -148,6 +150,10 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram; prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms) + for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i) + { + prepare_alpha_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], false, false); // note: bindDeferredShader will get called during render loop for materials + } // first pass, render rigged objects only and render to depth buffer forwardRender(true); @@ -216,9 +222,15 @@ void LLDrawPoolAlpha::render(S32 pass) { minimum_alpha = MINIMUM_IMPOSTOR_ALPHA; } + prepare_forward_shader(fullbright_shader, minimum_alpha); prepare_forward_shader(simple_shader, minimum_alpha); + for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i) + { + prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha); + } + //first pass -- rigged only and drawn to depth buffer forwardRender(true); @@ -289,15 +301,17 @@ void LLDrawPoolAlpha::renderDebugAlpha() gGL.diffuseColor4f(0, 1, 0, 1); pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); - + // FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled + if (sShowDebugAlphaRigged) + { + // gHighlightProgram.mRiggedVariant->bind(); - gGL.diffuseColor4f(1, 0, 0, 1); - + gGL.diffuseColor4f(0, 1, 0, 1);// FIRE-32132 et al. (can plain PASS_ALPHA_MASK_RIGGED exist?) paint it green if so. pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); // Material alpha mask - gGL.diffuseColor4f(0, 0, 1, 1); + gGL.diffuseColor4f(0, 1, 1, 1);// FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); @@ -306,6 +320,9 @@ void LLDrawPoolAlpha::renderDebugAlpha() gGL.diffuseColor4f(0, 1, 0, 1); pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + // FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled + } + // LLGLSLShader::sCurBoundShaderPtr->unbind(); } } @@ -333,16 +350,6 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo& params = **k; - // Capture render times - if(params.mFace) - { - LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); - if(vobj->isAttachment()) - { - trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr ); - } - } - // if (params.mParticle) { @@ -350,7 +357,30 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) } bool rigged = (params.mAvatar != nullptr); + // Capture render times + if(params.mFace) + { + LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject(); + if(vobj->isAttachment()) + { + trackAttachments( vobj, rigged, &ratPtr ); + } + } + // gHighlightProgram.bind(rigged); + // FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled + if (rigged && !sShowDebugAlphaRigged) + { + // if we don't want to show rigged alpha highlights then skip + continue; + } + else if (rigged && sShowDebugAlphaRigged) + { + // if we do and this is rigged then use a different colour + gGL.diffuseColor4f(1, 0.5, 0, 1); + } + else // NB dangling else to drop through to "normal behaviour" + // gGL.diffuseColor4f(1, 0, 0, 1); if (rigged) diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index fa8ef0f227..c6ea0045cb 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -66,6 +66,7 @@ public: bool uploadMatrixPalette(const LLDrawInfo& params); static BOOL sShowDebugAlpha; + static BOOL sShowDebugAlphaRigged; private: LLGLSLShader* target_shader; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index ffa2e4712a..f2857fc02c 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -129,7 +129,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) // } - if (gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete()) + if (gPipeline.mBake.isComplete()) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -216,7 +216,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete(); + bool use_fbo = gPipeline.mBake.isComplete(); if (use_fbo) { diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 733af8b175..c571064189 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -2775,7 +2775,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3 if (!water.isUndefined()) { - environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time)); + environment->injectWaterSettings(water, experience_id, LLSettingsBase::Seconds(transition_time)); } if (updateenvironment) diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index e834be8a9e..ceb7a188bd 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -618,7 +618,25 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, } // check if we are dragging an existing item from the favorites bar - if (item && mDragItemId == item->getUUID()) + bool existing_drop = false; + if (item && mDragItemId == item->getUUID()) + { + // There is a chance of mDragItemId being obsolete + // ex: can happen if something interrupts viewer, which + // results in viewer not geting a 'mouse up' signal + for (LLInventoryModel::item_array_t::iterator i = mItems.begin(); i != mItems.end(); ++i) + { + LLViewerInventoryItem* currItem = *i; + + if (currItem->getUUID() == mDragItemId) + { + existing_drop = true; + break; + } + } + } + + if (existing_drop) { *accept = ACCEPT_YES_SINGLE; @@ -647,6 +665,7 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, if (mItems.empty()) { setLandingTab(NULL); + mLastTab = NULL; } handleNewFavoriteDragAndDrop(item, favorites_id, x, y); } @@ -662,6 +681,12 @@ BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) { + if (mItems.empty()) + { + // Isn't supposed to be empty + return; + } + // Identify the button hovered and the side to drop LLFavoriteLandmarkButton* dest = dynamic_cast(mLandingTab); bool insert_before = true; @@ -934,6 +959,7 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) if(mItems.empty()) { mBarLabel->setVisible(TRUE); + mLastTab = NULL; } else { @@ -980,6 +1006,10 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) dynamic_cast (*cur_it); if (button) { + if (mLastTab == button) + { + mLastTab = NULL; + } removeChild(button); delete button; } @@ -1026,6 +1056,17 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update) mLastTab = last_new_button; } + if (!mLastTab && mItems.size() > 0) + { + // mMoreTextBox was removed, so LLFavoriteLandmarkButtons + // should be the only ones in the list + LLFavoriteLandmarkButton* button = dynamic_cast (childs->back()); + if (button) + { + mLastTab = button; + } + } + mFirstDropDownItem = j; // Chevron button if (mFirstDropDownItem < mItems.size()) diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 0605d6001a..b35a1210e9 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -67,6 +67,8 @@ #include "llviewercontrol.h" // for gSavedSettings #include "llvoavatarself.h" +#include "aoengine.h" // FIRE-32315: Animation preview sometimes fails when FS AO is enabled + S32 LLFloaterBvhPreview::sOwnAvatarInstanceCount = 0; // Preview on own avatar const S32 PREVIEW_BORDER_WIDTH = 2; @@ -137,6 +139,13 @@ LLFloaterBvhPreview::LLFloaterBvhPreview(const std::string& filename) : if (mUseOwnAvatar) { sOwnAvatarInstanceCount++; + + // // Switch FS AO off during preview + mAOEnabled = gSavedPerAccountSettings.getBOOL("UseAO"); + if (mAOEnabled) + { + AOEngine::getInstance()->enable(false); + } } // @@ -387,7 +396,7 @@ BOOL LLFloaterBvhPreview::loadBVH() loaderp->serialize(dp); dp.reset(); LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; - BOOL success = motionp && motionp->deserialize(dp, mMotionID); + BOOL success = motionp && motionp->deserialize(dp, mMotionID, false); LL_INFOS("BVH") << "Done" << LL_ENDL; delete []buffer; @@ -535,6 +544,12 @@ LLFloaterBvhPreview::~LLFloaterBvhPreview() gAgentAvatarp->startDefaultMotions(); gAgentAvatarp->startMotion(ANIM_AGENT_STAND); } + + // Switch FS AO back on if it was disabled during preview + if (mAOEnabled) + { + AOEngine::getInstance()->enable(true); + } } // diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index 89fffe13cb..ec3122821a 100644 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -158,6 +158,9 @@ protected: // FIRE-17277: Allow entering Loop In/Loop Out as frames S32 mNumFrames; + + // FIRE-32315: Animation preview sometimes fails when FS AO is enabled + bool mAOEnabled; }; #endif // LL_LLFLOATERBVHPREVIEW_H diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 0c6c241d9b..5592320b4f 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -728,6 +728,12 @@ void LLFloaterCamera::switchToPreset(const std::string& name) { gAgentCamera.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW); } + // Third Person Perspective camera + else if (PRESETS_TPP_VIEW == name) + { + gAgentCamera.switchCameraPreset(CAMERA_PRESET_TPP_VIEW); + } + // else { gAgentCamera.switchCameraPreset(CAMERA_PRESET_CUSTOM); diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 4032aa6e28..4c63e8b93b 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -176,7 +176,6 @@ void LLFloaterColorPicker::showUI () openFloater(getKey()); setVisible ( TRUE ); setFocus ( TRUE ); - setRevertOnCancel(FALSE); // HACK: if system color picker is required - close the SL one we made and use default system dialog if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) ) @@ -188,15 +187,23 @@ void LLFloaterColorPicker::showUI () // code that will get switched in for default system color picker if ( swatch ) { + // Todo: this needs to be threaded for viewer not to timeout LLColor4 curCol = swatch->get (); send_agent_pause(); - getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] ); + bool commit = getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] ); send_agent_resume(); - setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); - setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); + if (commit) + { + setOrigRgb(curCol[0], curCol[1], curCol[2]); + setCurRgb(curCol[0], curCol[1], curCol[2]); - LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE ); + LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_SELECT); + } + else + { + LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_CANCEL); + } } closeFloater(); @@ -404,10 +411,7 @@ void LLFloaterColorPicker::onClickCancel ( void* data ) if ( self ) { - if(self->getRevertOnCancel()) - { - self->cancelSelection (); - } + self->cancelSelection(); self->closeFloater(); } } diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index c5becd46fc..ce56a469cf 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -104,9 +104,6 @@ class LLFloaterColorPicker void setMouseDownInSwatch (BOOL mouse_down_in_swatch); BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; } - void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; }; - BOOL getRevertOnCancel () { return mRevertOnCancel; } - BOOL isColorChanged (); // called when text entries (RGB/HSL etc.) are changed by user @@ -149,8 +146,6 @@ class LLFloaterColorPicker BOOL mMouseDownInHueRegion; BOOL mMouseDownInSwatch; - BOOL mRevertOnCancel; - const S32 mRGBViewerImageLeft; const S32 mRGBViewerImageTop; const S32 mRGBViewerImageWidth; diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index ad5cf428d7..da22c5ff6e 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -46,19 +46,60 @@ typedef std::pair folder_pair_t; -class LLLandmarksInventoryObserver : public LLInventoryAddedObserver +class LLLandmarksInventoryObserver : public LLInventoryObserver { public: LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) : mFloater(create_landmark_floater) {} + void changed(U32 mask) override + { + if (mFloater->getItem()) + { + checkChanged(mask); + } + else + { + checkCreated(mask); + } + } + protected: - /*virtual*/ void done() + void checkCreated(U32 mask) { + if (gInventory.getAddedIDs().empty()) + { + return; + } + + if (!(mask & LLInventoryObserver::ADD) || + !(mask & LLInventoryObserver::CREATE) || + !(mask & LLInventoryObserver::UPDATE_CREATE)) + { + return; + } + mFloater->setItem(gInventory.getAddedIDs()); } + void checkChanged(U32 mask) + { + if (gInventory.getChangedIDs().empty()) + { + return; + } + + if ((mask & LLInventoryObserver::LABEL) || + (mask & LLInventoryObserver::INTERNAL) || + (mask & LLInventoryObserver::REMOVE) || + (mask & LLInventoryObserver::STRUCTURE) || + (mask & LLInventoryObserver::REBUILD)) + { + mFloater->updateItem(gInventory.getChangedIDs(), mask); + } + } + private: LLFloaterCreateLandmark* mFloater; }; @@ -85,6 +126,9 @@ BOOL LLFloaterCreateLandmark::postBuild() getChild("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this)); getChild("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this)); + mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); + mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); + mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); return TRUE; @@ -212,6 +256,33 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id) } } +void LLFloaterCreateLandmark::onCommitTextChanges() +{ + if (mItem.isNull()) + { + return; + } + std::string current_title_value = mLandmarkTitleEditor->getText(); + std::string item_title_value = mItem->getName(); + std::string current_notes_value = mNotesEditor->getText(); + std::string item_notes_value = mItem->getDescription(); + + LLStringUtil::trim(current_title_value); + LLStringUtil::trim(current_notes_value); + + if (!current_title_value.empty() && + (item_title_value != current_title_value || item_notes_value != current_notes_value)) + { + LLPointer new_item = new LLViewerInventoryItem(mItem); + new_item->rename(current_title_value); + new_item->setDescription(current_notes_value); + LLPointer cb; + LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); + gInventory.accountForUpdate(up); + update_inventory_item(new_item, cb); + } +} + void LLFloaterCreateLandmark::onCreateFolderClicked() { LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(), @@ -286,6 +357,8 @@ void LLFloaterCreateLandmark::onSaveClicked() new_item->updateParentOnServer(FALSE); } + removeObserver(); + gInventory.updateItem(new_item); gInventory.notifyObservers(); @@ -294,6 +367,7 @@ void LLFloaterCreateLandmark::onSaveClicked() void LLFloaterCreateLandmark::onCancelClicked() { + removeObserver(); if (!mItem.isNull()) { LLUUID item_id = mItem->getUUID(); @@ -322,10 +396,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items) { if(!getItem()) { - removeObserver(); mItem = item; + mAssetID = mItem->getAssetUUID(); + setVisibleAndFrontmost(true); break; } } } } + +void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask) +{ + if (!getItem()) + { + return; + } + + LLUUID landmark_id = getItem()->getUUID(); + + for (uuid_set_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + const LLUUID& item_id = (*item_iter); + if (landmark_id == item_id) + { + if (getItem() != gInventory.getItem(item_id)) + { + // item is obsolete or removed + closeFloater(); + } + + LLUUID folder_id = mFolderCombo->getValue().asUUID(); + if (folder_id != mItem->getParentUUID()) + { + // user moved landmark in inventory, + // assume that we are done all other changes should already be commited + closeFloater(); + } + + if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID()) + { + closeFloater(); + } + + if (mask & LLInventoryObserver::LABEL) + { + mLandmarkTitleEditor->setText(mItem->getName()); + } + + if (mask & LLInventoryObserver::INTERNAL) + { + mNotesEditor->setText(mItem->getDescription()); + } + } + } +} diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h index 74ac5e651c..d84f5ae1fc 100644 --- a/indra/newview/llfloatercreatelandmark.h +++ b/indra/newview/llfloatercreatelandmark.h @@ -49,6 +49,7 @@ public: void onOpen(const LLSD& key); void setItem(const uuid_set_t& items); + void updateItem(const uuid_set_t& items, U32 mask); LLInventoryItem* getItem() { return mItem; } @@ -56,6 +57,7 @@ private: void setLandmarkInfo(const LLUUID &folder_id); void removeObserver(); void populateFoldersList(const LLUUID &folder_id = LLUUID::null); + void onCommitTextChanges(); void onCreateFolderClicked(); void onSaveClicked(); void onCancelClicked(); @@ -66,6 +68,7 @@ private: LLLineEditor* mLandmarkTitleEditor; LLTextEditor* mNotesEditor; LLUUID mLandmarksID; + LLUUID mAssetID; LLLandmarksInventoryObserver* mInventoryObserver; LLPointer mItem; diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 24673d5a7c..297ad24359 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -665,6 +665,7 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data) if (ctrl_action == ACTION_SAVE) { doApplyUpdateInventory(dayclone); + clearDirtyFlag(); } else if (ctrl_action == ACTION_SAVEAS) { diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index fec218ca3b..aa9a2c164a 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -296,6 +296,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) if (ctrl_action == ACTION_SAVE) { doApplyUpdateInventory(setting_clone); + clearDirtyFlag(); } else if (ctrl_action == ACTION_SAVEAS) { diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp index 948de6b2d7..6075ede579 100644 --- a/indra/newview/llfloaterhoverheight.cpp +++ b/indra/newview/llfloaterhoverheight.cpp @@ -107,28 +107,31 @@ void LLFloaterHoverHeight::onClose(bool app_quitting) // static void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData) { - LLSliderCtrl* sldrCtrl = static_cast(ctrl); - F32 value = sldrCtrl->getValueF32(); - LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z)); - LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; - // Legacy baking avatar z-offset - //gAgentAvatarp->setHoverOffset(offset, false); - if (gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled()) - { - if (sldrCtrl->isMouseHeldDown()) - { - gAgentAvatarp->setHoverOffset(offset, false); - } - else - { - gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", value); - } - } - else if (!gAgentAvatarp->isUsingServerBakes()) - { - gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", value); - } - // + if (isAgentAvatarValid()) + { + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + F32 value = sldrCtrl->getValueF32(); + LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z)); + LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; + // Legacy baking avatar z-offset + //gAgentAvatarp->setHoverOffset(offset, false); + if (gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled()) + { + if (sldrCtrl->isMouseHeldDown()) + { + gAgentAvatarp->setHoverOffset(offset, false); + } + else + { + gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", value); + } + } + else if (!gAgentAvatarp->isUsingServerBakes()) + { + gSavedPerAccountSettings.setF32("AvatarHoverOffsetZ", value); + } + // + } } // Do send-to-the-server work when slider drag completes, or new diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 3291e744d3..9c9df55dc4 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -708,7 +708,6 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate) { - LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command // Look for "/20 foo" channel chats. S32 channel = 0; LLWString out_text = stripChannelNumber(wtext, &channel); @@ -921,6 +920,12 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe } // [/RLVa:KB] + LL_DEBUGS("UIUsage") << "Nearby chat, text " << utf8_out_text << " type " << type << " channel " << channel << LL_ENDL; + if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP) // prune back some redundant logging + { + LLUIUsage::instance().logCommand("Chat.SendNearby"); // pseuo-command + } + LLMessageSystem* msg = gMessageSystem; if (channel >= 0) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 157c943653..9cfd1ebf23 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -3291,7 +3291,8 @@ BOOL LLPanelLandCovenant::postBuild() { mLastRegionID = LLUUID::null; mNextUpdateTime = 0; - + mTextEstateOwner = getChild("estate_owner_text"); + mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend); return TRUE; } @@ -3399,8 +3400,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name) LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); if (self) { - LLTextBox* editor = self->getChild("estate_owner_text"); - if (editor) editor->setText(name); + self->mTextEstateOwner->setText(name); } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index be05407411..daa47ae0a5 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -431,6 +431,7 @@ protected: private: LLUUID mLastRegionID; F64 mNextUpdateTime; //seconds since client start + LLTextBox* mTextEstateOwner; }; #endif diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index f10d7582a0..f098193774 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -51,6 +51,8 @@ // The minor cardinal direction labels are hidden if their height is more // than this proportion of the map. +// FIRE-32341: Make minor directions visible at reasonable mini map size again +//const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f; const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f; const S32 MAP_PADDING_LEFT = 0; @@ -81,46 +83,54 @@ LLFloaterMap::~LLFloaterMap() BOOL LLFloaterMap::postBuild() { - mMap = getChild("Net Map"); - // Synchronize tooltips throughout instances - //if (gSavedSettings.getBOOL("DoubleClickTeleport")) - //{ - // mMap->setToolTipMsg(getString("AltToolTipMsg")); - //} - //else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) - //{ - // mMap->setToolTipMsg(getString("ToolTipMsg")); - //} - // Synchronize tooltips throughout instances - sendChildToBack(mMap); - - mTextBoxNorth = getChild ("floater_map_north"); - mTextBoxEast = getChild ("floater_map_east"); - mTextBoxWest = getChild ("floater_map_west"); - mTextBoxSouth = getChild ("floater_map_south"); - mTextBoxSouthEast = getChild ("floater_map_southeast"); - mTextBoxNorthEast = getChild ("floater_map_northeast"); - mTextBoxSouthWest = getChild ("floater_map_southwest"); - mTextBoxNorthWest = getChild ("floater_map_northwest"); + mMap = getChild("Net Map"); + mMap->setToolTipMsg(getString("ToolTipMsg")); + mMap->setParcelNameMsg(getString("ParcelNameMsg")); + mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg")); + mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg")); + mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg")); + mMap->setRegionNameMsg(getString("RegionNameMsg")); + mMap->setToolTipHintMsg(getString("ToolTipHintMsg")); + mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg")); + sendChildToBack(mMap); - // Remove titlebar - stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT, - getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM); + mTextBoxNorth = getChild("floater_map_north"); + mTextBoxEast = getChild("floater_map_east"); + mTextBoxWest = getChild("floater_map_west"); + mTextBoxSouth = getChild("floater_map_south"); + mTextBoxSouthEast = getChild("floater_map_southeast"); + mTextBoxNorthEast = getChild("floater_map_northeast"); + mTextBoxSouthWest = getChild("floater_map_southwest"); + mTextBoxNorthWest = getChild("floater_map_northwest"); - updateMinorDirections(); + mTextBoxNorth->reshapeToFitText(); + mTextBoxEast->reshapeToFitText(); + mTextBoxWest->reshapeToFitText(); + mTextBoxSouth->reshapeToFitText(); + mTextBoxSouthEast->reshapeToFitText(); + mTextBoxNorthEast->reshapeToFitText(); + mTextBoxSouthWest->reshapeToFitText(); + mTextBoxNorthWest->reshapeToFitText(); - // Get the drag handle all the way in back - sendChildToBack(getDragHandle()); - // Remove titlebar - setIsChrome(TRUE); - getDragHandle()->setTitleVisible(TRUE); - // - - // keep onscreen - gFloaterView->adjustToFitScreen(this, FALSE); + // Remove titlebar + stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT, + getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM); - return TRUE; + updateMinorDirections(); + + // Get the drag handle all the way in back + sendChildToBack(getDragHandle()); + + // Remove titlebar + setIsChrome(TRUE); + getDragHandle()->setTitleVisible(TRUE); + // + + // keep onscreen + gFloaterView->adjustToFitScreen(this, false); + + return true; } BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) @@ -156,23 +166,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } -void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation ) +void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation) { - // Rotation is in radians. - // Rotation of 0 means x = 1, y = 0 on the unit circle. + // Rotation is in radians. + // Rotation of 0 means x = 1, y = 0 on the unit circle. - F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2; - F32 map_half_width = (F32)(getRect().getWidth() / 2) ; - F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2); - F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2); - F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width ); + F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2); + F32 map_half_width = (F32) (getRect().getWidth() / 2); + F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2); + F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2); + F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2); + F32 pos_half_height = map_half_height - text_half_height - extra_padding; + F32 pos_half_width = map_half_width - text_half_width - extra_padding; - // Inset by a little to account for position display. - radius -= 8.f; + F32 corner_angle = atan2(pos_half_height, pos_half_width); + F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI)); + if (rotation < 0) + { + rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top; + } + F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO)); + bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle; - text_box->setOrigin( - ll_round(map_half_width - text_half_width + radius * cos( rotation )), - ll_round(map_half_height - text_half_height + radius * sin( rotation )) ); + F32 part_x = cos(rotation); + F32 part_y = sin(rotation); + F32 y; + F32 x; + if (at_left_right_edge) + { + x = std::copysign(pos_half_width, part_x); + y = x * part_y / part_x; + } + else + { + y = std::copysign(pos_half_height, part_y); + x = y * part_x / part_y; + } + + text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height)); } void LLFloaterMap::updateMinorDirections() @@ -239,34 +270,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) updateMinorDirections(); } -// Unused as of 06-02-2014; Handled in LLNetMap -//void LLFloaterMap::handleZoom(const LLSD& userdata) -//{ -// std::string level = userdata.asString(); -// -// F32 scale = 0.0f; -// if (level == std::string("default")) -// { -// LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); -// if(pvar) -// { -// pvar->resetToDefault(); -// scale = gSavedSettings.getF32("MiniMapScale"); -// } -// } -// else if (level == std::string("close")) -// scale = LLNetMap::MAP_SCALE_MAX; -// else if (level == std::string("medium")) -// scale = LLNetMap::MAP_SCALE_MID; -// else if (level == std::string("far")) -// scale = LLNetMap::MAP_SCALE_MIN; -// if (scale != 0.0f) -// { -// mMap->setScale(scale); -// } -//} -// - LLFloaterMap* LLFloaterMap::getInstance() { return LLFloaterReg::getTypedInstance("mini_map"); diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index 1564b7483c..50900c6a7f 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -51,8 +51,6 @@ public: /*virtual*/ F32 getCurrentTransparency(); private: - // Unused as of 06-02-2014; Handled in LLNetMap - //void handleZoom(const LLSD& userdata); void setDirectionPos( LLTextBox* text_box, F32 rotation ); void updateMinorDirections(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index c82a6822cf..9aee06e600 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -535,13 +535,14 @@ void LLFloaterModelPreview::loadHighLodModel() loadModel(3); } -void LLFloaterModelPreview::loadModel(S32 lod) +void LLFloaterModelPreview::prepareToLoadModel(S32 lod) { // FIRE-15204: Viewer crashes when clicking "upload model" quickly twice then closing both filepickers if (mModelPreview->mLoading) { return; } + mModelPreview->mLoading = true; // mModelPreview->mLoading = true; @@ -549,22 +550,18 @@ void LLFloaterModelPreview::loadModel(S32 lod) { // loading physics from file mModelPreview->mPhysicsSearchLOD = lod; + mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false; } - +} +void LLFloaterModelPreview::loadModel(S32 lod) +{ + prepareToLoadModel(lod); (new LLMeshFilePicker(mModelPreview, lod))->getFile(); } void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm) { - // FIRE-15204: Viewer crashes when clicking "upload model" quickly twice then closing both filepickers - if (mModelPreview->mLoading) - { - return; - } - // - - mModelPreview->mLoading = true; - + prepareToLoadModel(lod); mModelPreview->loadModel(file_name, lod, force_disable_slm); } @@ -1187,7 +1184,8 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) } S32 file_mode = iface->getItemCount() - 1; - if (which_mode < file_mode) + S32 cube_mode = file_mode - 1; + if (which_mode < cube_mode) { // FIRE-30963 Support pre-defined physics shapes (initially cube) // S32 which_lod = num_lods - which_mode; @@ -1205,6 +1203,12 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) } // } + else if (which_mode == cube_mode) + { + std::string path = gDirUtilp->getAppRODataDir(); + gDirUtilp->append(path, "cube.dae"); + sInstance->loadModel(LLModel::LOD_PHYSICS, path); + } LLModelPreview *model_preview = sInstance->mModelPreview; if (model_preview) @@ -1875,15 +1879,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod) { if (lod == LLModel::LOD_PHYSICS) - { + { LLComboBox* lod_combo = findChild("physics_lod_combo"); if (lod_combo) { - lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1); // FIRE-30963 - better physics defaults + lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1); } } else -{ + { LLComboBox* lod_combo = findChild("lod_source_" + lod_name[lod]); if (lod_combo) { diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 4737a73311..138e049ad8 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -223,6 +223,7 @@ private: void resetUploadOptions(); void clearLogTab(); + void prepareToLoadModel(S32 lod); void createSmoothComboBox(LLComboBox* combo_box, float min, float max); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index ae1e9773fd..facbf4fe2b 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -805,6 +805,12 @@ BOOL LLFloaterPreference::postBuild() mPopupFilter = getChild("popup_filter"); // + // SDL2 IME support +#if LL_SDL2 + childSetVisible("use_ime", true); +#endif + // + return TRUE; } @@ -2106,7 +2112,6 @@ void LLFloaterPreference::refreshEnabledState() //BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && // bumpshiny && // shaders && - // gGLManager.mHasFramebufferObject && // (ctrl_wind_light->get()) ? TRUE : FALSE; //ctrl_deferred->setEnabled(enabled); @@ -2220,7 +2225,6 @@ void LLFloaterPreference::refreshEnabledState() BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) && - gGLManager.mHasFramebufferObject && (ctrl_wind_light->get()) ? TRUE : FALSE; ctrl_deferred->setEnabled(enabled); @@ -2359,8 +2363,7 @@ void LLFloaterPreference::disableUnavailableSettings() } // disabled deferred - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") || - !gGLManager.mHasFramebufferObject) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) { ctrl_shadows->setEnabled(FALSE); ctrl_shadows->setValue(0); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 79df19ad55..a6cdd25e85 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -47,6 +47,7 @@ #include "llagent.h" #include "llappviewer.h" +#include "llavataractions.h" #include "llavatarname.h" #include "llfloateravatarpicker.h" #include "llbutton.h" @@ -2062,7 +2063,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) setCtrlsEnabled(god || owner || manager); getChildView("apply_btn")->setEnabled(FALSE); - + getChildView("estate_owner")->setEnabled(TRUE); getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); @@ -2124,6 +2125,8 @@ BOOL LLPanelEstateInfo::postBuild() getChild("externally_visible_radio")->setFocus(TRUE); + getChild("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend); + return LLPanelRegionInfo::postBuild(); } @@ -2371,6 +2374,7 @@ BOOL LLPanelEstateCovenant::postBuild() { mEstateNameText = getChild("estate_name_text"); mEstateOwnerText = getChild("estate_owner_text"); + mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend); mLastModifiedText = getChild("covenant_timestamp_text"); mEditor = getChild("covenant_editor"); LLButton* reset_button = getChild("reset_covenant"); diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 82a603c17a..e44c5b5ad2 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -90,7 +90,6 @@ //--------------------------------------------------------------------------- // Constants //--------------------------------------------------------------------------- -static const F32 MAP_ZOOM_TIME = 0.2f; // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across @@ -346,7 +345,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data) BOOL LLFloaterWorldMap::postBuild() { - mPanel = getChild("objects_mapview"); + mMapView = dynamic_cast(getChild("objects_mapview")); LLComboBox *avatar_combo = getChild("friend combo"); avatar_combo->selectFirstItem(); @@ -367,16 +366,14 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); mListLandmarkCombo = dynamic_cast(landmark_combo); - mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f); - getChild("zoom slider")->setValue(mCurZoomVal); + F32 slider_zoom = mMapView->getZoom(); + getChild("zoom slider")->setValue(slider_zoom); // Use own expand/collapse function //getChild("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this)); setDefaultBtn(NULL); - mZoomTimer.stop(); - onChangeMaturity(); return TRUE; @@ -393,7 +390,7 @@ LLFloaterWorldMap::~LLFloaterWorldMap() // Parcel details on map // All cleaned up by LLView destructor - mPanel = NULL; + mMapView = NULL; // Inventory deletes all observers on shutdown mInventory = NULL; @@ -431,17 +428,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key) mIsClosing = FALSE; - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->clearLastClick(); + mMapView->clearLastClick(); { // reset pan on show, so it centers on you again if (!center_on_target) { - LLWorldMapView::setPan(0, 0, TRUE); + mMapView->setPan(0, 0, true); } - map_panel->updateVisibleBlocks(); + mMapView->updateVisibleBlocks(); // Reload items as they may have changed LLWorldMap::getInstance()->reloadItems(); @@ -489,18 +484,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask) BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { - if (!isMinimized() && isFrontmost()) - { - if(mPanel->pointInView(x, y)) - { - F32 slider_value = (F32)getChild("zoom slider")->getValue().asReal(); - slider_value += ((F32)clicks * -0.3333f); - getChild("zoom slider")->setValue(LLSD(slider_value)); - return TRUE; - } - } - - return LLFloater::handleScrollWheel(x, y, clicks); + if (!isMinimized() && isFrontmost()) + { + S32 map_x = x - mMapView->getRect().mLeft; + S32 map_y = y - mMapView->getRect().mBottom; + if (mMapView->pointInView(map_x, map_y)) + { + F32 old_slider_zoom = (F32) getChild("zoom slider")->getValue().asReal(); + F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f); + getChild("zoom slider")->setValue(LLSD(slider_zoom)); + mMapView->zoomWithPivot(slider_zoom, map_x, map_y); + return true; + } + } + + return LLFloater::handleScrollWheel(x, y, clicks); } @@ -634,32 +632,13 @@ void LLFloaterWorldMap::draw() setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); - - //RN: snaps to zoom value because interpolation caused jitter in the text rendering - // Performance improvement - //if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild("zoom slider")->getValue().asReal()) - if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)zoom_slider->getValue().asReal()) - // Performance improvement - { - mZoomTimer.start(); - } - F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME; - if (interp > 1.f) - { - interp = 1.f; - mZoomTimer.stop(); - } - // Performance improvement - //mCurZoomVal = lerp(mCurZoomVal, (F32)getChild("zoom slider")->getValue().asReal(), interp); - mCurZoomVal = lerp(mCurZoomVal, (F32)zoom_slider->getValue().asReal(), interp); - // Performance improvement - F32 map_scale = 256.f*pow(2.f, mCurZoomVal); - LLWorldMapView::setScale( map_scale ); + + mMapView->zoom((F32)getChild("zoom slider")->getValue().asReal()); // Enable/disable checkboxes depending on the zoom level // If above threshold level (i.e. low res) -> Disable all checkboxes // If under threshold level (i.e. high res) -> Enable all checkboxes - bool enable = LLWorldMapView::showRegionInfo(); + bool enable = mMapView->showRegionInfo(); // Performance improvement //getChildView("people_chk")->setEnabled(enable); //getChildView("infohub_chk")->setEnabled(enable); @@ -1362,9 +1341,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() S32 world_height_regions = MAX_VISIBLE_REGIONS; // Find how much space we have to display the world - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)mPanel; - LLRect view_rect = map_panel->getRect(); + LLRect view_rect = mMapView->getRect(); // View size in pixels S32 view_width = view_rect.getWidth(); @@ -1632,9 +1609,9 @@ void LLFloaterWorldMap::onShowTargetBtn() void LLFloaterWorldMap::onShowAgentBtn() { - LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate - // Set flag so user's location will be displayed if not tracking anything else - mSetToUserPosition = TRUE; + mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate + // Set flag so user's location will be displayed if not tracking anything else + mSetToUserPosition = true; } void LLFloaterWorldMap::onClickTeleportBtn() @@ -1736,9 +1713,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) pos_global.clearVec(); } - LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), - -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), - !animate); + F64 map_scale = (F64)mMapView->getScale(); + mMapView->setPanWithInterpTime(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), + -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)), + !animate, 0.1f); mWaitingForTracker = FALSE; } @@ -1973,7 +1951,7 @@ void LLFloaterWorldMap::onTeleportFinished() { if(isInVisibleChain()) { - LLWorldMapView::setPan(0, 0, TRUE); + mMapView->setPan(0, 0, TRUE); } } @@ -2048,9 +2026,8 @@ void LLFloaterWorldMap::onChangeMaturity() void LLFloaterWorldMap::onFocusLost() { - gViewerWindow->showCursor(); - LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->mPanning = FALSE; + gViewerWindow->showCursor(); + mMapView->mPanning = false; } LLPanelHideBeacon::LLPanelHideBeacon() : diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index f3cf0541d9..e6a33387f4 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -47,6 +47,7 @@ class LLInventoryObserver; class LLItemInfo; class LLLineEditor; class LLTabContainer; +class LLWorldMapView; // Parcel details on map class FSWorldMapParcelInfoObserver : public LLRemoteParcelInfoObserver @@ -189,11 +190,7 @@ protected: // Parcel details on map private: - LLPanel* mPanel; // Panel displaying the map - - // Ties to LLWorldMapView::sMapScale, in pixels per region - F32 mCurZoomVal; - LLFrameTimer mZoomTimer; + LLWorldMapView* mMapView; // Panel displaying the map // update display of teleport destination coordinates - pos is in global coordinates void updateTeleportCoordsDisplay( const LLVector3d& pos ); diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 35843fff9b..1bd691d9a9 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -64,6 +64,7 @@ #include "llviewerregion.h" #include #include "llcorehttputil.h" +#include "lluiusage.h" // [SL:KB] - Patch: Chat-GroupSessionEject | Checked: 2012-02-04 (Catznip-3.2.1) #include "llimview.h" @@ -1881,6 +1882,9 @@ void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id) //static void LLGroupMgr::sendGroupMemberJoin(const LLUUID& group_id) { + + LLUIUsage::instance().logCommand("Group.Join"); + LLMessageSystem *msg = gMessageSystem; msg->newMessageFast(_PREHASH_JoinGroupRequest); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 5fca351dbf..9e0b540813 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -76,6 +76,7 @@ #include "message.h" #include "llviewerregion.h" #include "llcorehttputil.h" +#include "lluiusage.h" // [RLVa:KB] - Checked: 2013-05-10 (RLVa-1.4.9) #include "rlvactions.h" #include "rlvcommon.h" @@ -911,6 +912,23 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f message["index"] = (LLSD::Integer)mMsgs.size(); message["is_history"] = is_history; + LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL; + if (from_id == gAgent.getID()) + { + if (mType == IM_SESSION_GROUP_START) + { + LLUIUsage::instance().logCommand("Chat.SendGroup"); + } + else if (mType == IM_NOTHING_SPECIAL) + { + LLUIUsage::instance().logCommand("Chat.SendIM"); + } + else + { + LLUIUsage::instance().logCommand("Chat.SendOther"); + } + } + mMsgs.push_front(message); if (mSpeakers && from_id.notNull()) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 77625c1360..98a31cb467 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -982,7 +982,11 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, // LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel && (active_panel->getName() != "All Items")) + // Don't offer "Show in Main View" for folders opened in separate inventory views + // as there are no tabs to switch to + // if (active_panel && (active_panel->getName() != "All Items")) + if (active_panel && (active_panel->getName() != "All Items") && (active_panel->getName() != "inv_panel")) + // { items.push_back(std::string("Show in Main Panel")); } @@ -3741,6 +3745,21 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) LLFloaterReg::showInstance("fs_partial_inventory", LLSD().with("start_folder_id", mUUID).with("start_folder_name", mDisplayName)); } // + + // Add "Reload folder" action to inventory + else if ("reload_folder" == action) + { + LLViewerInventoryCategory *cat = model->getCategory(mUUID); + + if (!cat) + { + return; + } + + cat->setVersion(LLViewerInventoryCategory::VERSION_UNKNOWN); + cat->fetch(); + } + // } void LLFolderBridge::gatherMessage(std::string& message, S32 depth, LLError::ELevel log_level) @@ -4200,7 +4219,20 @@ void LLFolderBridge::perform_pasteFromClipboard() { if (item && can_move_to_landmarks(item)) { - dropToFavorites(item); + if (LLClipboard::instance().isCutMode()) + { + LLViewerInventoryItem* viitem = dynamic_cast(item); + llassert(viitem); + if (viitem) + { + //changeItemParent() implicity calls dirtyFilter + changeItemParent(model, viitem, parent_id, FALSE); + } + } + else + { + dropToFavorites(item); + } } } else if (LLClipboard::instance().isCutMode()) @@ -4686,6 +4718,20 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items // Show folder in new window option items.push_back((std::string("Show in new Window"))); + // Add "Reload folder" action to inventory + // only allow reload for a single, non-root folder to prevent misuse + if (!(flags & ITEM_IN_MULTI_SELECTION)) + { + if (mUUID != model->findCategoryUUIDForType(LLFolderType::FT_ROOT_INVENTORY)) + { + if (mUUID != model->findLibraryCategoryUUIDForType(LLFolderType::FT_ROOT_INVENTORY)) + { + items.push_back(std::string("ReloadFolder")); + } + } + } + // + // Add menu items that are dependent on the contents of the folder. LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID); if (category && (marketplace_listings_id != mUUID)) @@ -4749,7 +4795,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items.push_back(std::string("IM All Contacts In Folder")); } - if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren()) + if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren() && (type != LLFolderType::FT_OUTFIT)) { items.push_back(std::string("Ungroup folder items")); } diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp index bbbde0711f..ce4ec668f1 100644 --- a/indra/newview/lllegacyatmospherics.cpp +++ b/indra/newview/lllegacyatmospherics.cpp @@ -482,8 +482,7 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) { LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); F32 depth = water_height - camera_height; - - // get the water param manager variables + LLColor4 water_fog_color(pwater->getWaterFogColor()); // adjust the color based on depth. We're doing linear approximations diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 45b157fe1f..87248d7e66 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -90,6 +90,7 @@ bool LLModelPreview::sIgnoreLoadedCallback = false; // static const F32 PREVIEW_DEG_POINT_SIZE(8.f); // static const F32 PREVIEW_ZOOM_LIMIT(10.f); // +static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape"; const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f; #include "glod/glod.h" // More flexible LOD generation @@ -636,6 +637,20 @@ void LLModelPreview::rebuildUploadData() LLFloaterModelPreview::addStringToLog(out, false); } } + if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS)) + { + // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition. + // That's ok, but might not what they wanted. Use default_physics_shape if found. + std::ostringstream out; + out << "No physics model specified for " << instance.mLabel; + if (mDefaultPhysicsShapeP) + { + out << " - using: " << DEFAULT_PHYSICS_MESH_NAME; + lod_model = mDefaultPhysicsShapeP; + } + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default. + } if (lod_model) { @@ -1319,6 +1334,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) } else { + if (loaded_lod == LLModel::LOD_PHYSICS) + { // Explicitly loading physics. See if there is a default mesh. + LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own. + mDefaultPhysicsShapeP = nullptr; + FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform); + mWarnOfUnmatchedPhyicsMeshes = true; + } BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching"); if (!legacyMatching) { @@ -1389,7 +1411,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); } - mModel[loaded_lod][idx]->mLabel = name; } } @@ -3807,7 +3828,6 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) mVertexBuffer[lod][mdl].push_back(vb); ++mesh_count; - } } } diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 92bb30db52..406ddfd0f4 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -232,6 +232,21 @@ private: static U32 countRootModels(LLModelLoader::model_list models); LLVector3 mGroundPlane[4]; void renderGroundPlane(float z_offset = 0.0f); + /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh. + /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when + /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()). + /// + /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When + /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when + /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot. + /// When there are multiple meshes in each file, they are matched by name or order, and some meshes + /// are broken up by limitations into multiple objects, and thus there can be mismatches.) + bool mWarnOfUnmatchedPhyicsMeshes{false}; + /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified. + /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME. + /// It is reset when such a name is not found, and when resetting the modelpreview. + /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true. + LLModel* mDefaultPhysicsShapeP{}; typedef enum { diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 7f8afe833e..ce1064e789 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -552,9 +552,9 @@ void LLNavigationBar::onLocationSelection() if(value.has("AssetUUID")) { - gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString())); - mSaveToLocationHistory = true; + // user teleported by manually inputting inventory landmark's name + mSaveToLocationHistory = false; return; } else diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index e92476f465..c0d59dbfed 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -37,6 +37,7 @@ #include "llfocusmgr.h" #include "lllocalcliprect.h" #include "llrender.h" +#include "llresmgr.h" #include "llui.h" #include "lltooltip.h" @@ -51,17 +52,19 @@ #include "llfloatersidepanelcontainer.h" // [/SL:KB] #include "llcallingcard.h" // LLAvatarTracker +#include "llfloaterland.h" #include "llfloaterworldmap.h" -// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3) #include "llparcel.h" -// [/SL:KB] #include "lltracker.h" #include "llsurface.h" // [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3) #include "lltrans.h" // [/SL:KB] +#include "llurlmatch.h" +#include "llurlregistry.h" #include "llviewercamera.h" #include "llviewercontrol.h" +#include "llviewerparcelmgr.h" #include "llviewertexture.h" #include "llviewertexturelist.h" #include "llviewermenu.h" @@ -90,7 +93,10 @@ static LLDefaultChildRegistry::Register r1("net_map"); const F32 LLNetMap::MAP_SCALE_MIN = 32; -const F32 LLNetMap::MAP_SCALE_MID = 1024; +const F32 LLNetMap::MAP_SCALE_FAR = 32; +const F32 LLNetMap::MAP_SCALE_MEDIUM = 128; +const F32 LLNetMap::MAP_SCALE_CLOSE = 256; +const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024; const F32 LLNetMap::MAP_SCALE_MAX = 4096; const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%) @@ -107,20 +113,16 @@ const S32 CIRCLE_STEPS = 100; LLNetMap::avatar_marks_map_t LLNetMap::sAvatarMarksMap; // F32 LLNetMap::sScale; // Synchronizing netmaps throughout instances -// Synchronize tooltips throughout instances -std::string LLNetMap::sToolTipMsg; -// Synchronize tooltips throughout instances - LLNetMap::LLNetMap (const Params & p) : LLUICtrl (p), mBackgroundColor (p.bg_color()), - mScale( MAP_SCALE_MID ), - mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ), + mScale( MAP_SCALE_MEDIUM ), + mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ), mObjectMapTPM(0.f), mObjectMapPixels(0.f), - mTargetPan(0.f, 0.f), mCurPan(0.f, 0.f), mStartPan(0.f, 0.f), + mPopupWorldPos(0.f, 0.f, 0.f), mMouseDown(0, 0), mPanning(false), // mUpdateNow(false), @@ -138,12 +140,18 @@ LLNetMap::LLNetMap (const Params & p) // [/SL:KB] mClosestAgentToCursor(), // mClosestAgentAtLastRightClick(), - // Synchronize tooltips throughout instances - //mToolTipMsg(), + mToolTipMsg(), mPopupMenu(NULL) { // Fixing borked minimap zoom level persistance //mScale = gSavedSettings.getF32("MiniMapScale"); + if (gAgent.isFirstLogin()) + { + // *HACK: On first run, set this to false for new users, otherwise the + // default is true to maintain consistent experience for existing + // users. + gSavedSettings.setBOOL("MiniMapRotate", false); + } //mPixelsPerMeter = mScale / REGION_WIDTH_METERS; //mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); setScale(gSavedSettings.getF32("MiniMapScale")); @@ -180,59 +188,63 @@ LLNetMap::~LLNetMap() BOOL LLNetMap::postBuild() { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - - registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2)); - registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar; + enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2)); + commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2)); + commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); + commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2)); + enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2)); + commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2)); + commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2)); // - registrar.add("Minimap.Mark", boost::bind(&LLNetMap::handleMark, this, _2)); - registrar.add("Minimap.ClearMark", boost::bind(&LLNetMap::handleClearMark, this)); - registrar.add("Minimap.ClearMarks", boost::bind(&LLNetMap::handleClearMarks, this)); + commitRegistrar.add("Minimap.Mark", boost::bind(&LLNetMap::handleMark, this, _2)); + commitRegistrar.add("Minimap.ClearMark", boost::bind(&LLNetMap::handleClearMark, this)); + commitRegistrar.add("Minimap.ClearMarks", boost::bind(&LLNetMap::handleClearMarks, this)); // - registrar.add("Minimap.Cam", boost::bind(&LLNetMap::handleCam, this)); - registrar.add("Minimap.StartTracking", boost::bind(&LLNetMap::handleStartTracking, this)); + commitRegistrar.add("Minimap.Cam", boost::bind(&LLNetMap::handleCam, this)); + commitRegistrar.add("Minimap.StartTracking", boost::bind(&LLNetMap::handleStartTracking, this)); // [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3) - registrar.add("Minimap.ShowProfile", boost::bind(&LLNetMap::handleShowProfile, this, _2)); - registrar.add("Minimap.TextureType", boost::bind(&LLNetMap::handleTextureType, this, _2)); - registrar.add("Minimap.ToggleOverlay", boost::bind(&LLNetMap::handleOverlayToggle, this, _2)); + commitRegistrar.add("Minimap.ShowProfile", boost::bind(&LLNetMap::handleShowProfile, this, _2)); + commitRegistrar.add("Minimap.TextureType", boost::bind(&LLNetMap::handleTextureType, this, _2)); + commitRegistrar.add("Minimap.ToggleOverlay", boost::bind(&LLNetMap::handleOverlayToggle, this, _2)); - registrar.add("Minimap.AddFriend", boost::bind(&LLNetMap::handleAddFriend, this)); - registrar.add("Minimap.AddToContactSet", boost::bind(&LLNetMap::handleAddToContactSet, this)); - registrar.add("Minimap.RemoveFriend", boost::bind(&LLNetMap::handleRemoveFriend, this)); - registrar.add("Minimap.IM", boost::bind(&LLNetMap::handleIM, this)); - registrar.add("Minimap.Call", boost::bind(&LLNetMap::handleCall, this)); - registrar.add("Minimap.Map", boost::bind(&LLNetMap::handleMap, this)); - registrar.add("Minimap.Share", boost::bind(&LLNetMap::handleShare, this)); - registrar.add("Minimap.Pay", boost::bind(&LLNetMap::handlePay, this)); - registrar.add("Minimap.OfferTeleport", boost::bind(&LLNetMap::handleOfferTeleport, this)); - registrar.add("Minimap.RequestTeleport", boost::bind(&LLNetMap::handleRequestTeleport, this)); - registrar.add("Minimap.TeleportToAvatar", boost::bind(&LLNetMap::handleTeleportToAvatar, this)); - registrar.add("Minimap.GroupInvite", boost::bind(&LLNetMap::handleGroupInvite, this)); - registrar.add("Minimap.GetScriptInfo", boost::bind(&LLNetMap::handleGetScriptInfo, this)); - registrar.add("Minimap.BlockUnblock", boost::bind(&LLNetMap::handleBlockUnblock, this)); - registrar.add("Minimap.Report", boost::bind(&LLNetMap::handleReport, this)); - registrar.add("Minimap.Freeze", boost::bind(&LLNetMap::handleFreeze, this)); - registrar.add("Minimap.Eject", boost::bind(&LLNetMap::handleEject, this)); - registrar.add("Minimap.Kick", boost::bind(&LLNetMap::handleKick, this)); - registrar.add("Minimap.TeleportHome", boost::bind(&LLNetMap::handleTeleportHome, this)); - registrar.add("Minimap.EstateBan", boost::bind(&LLNetMap::handleEstateBan, this)); - registrar.add("Minimap.Derender", boost::bind(&LLNetMap::handleDerender, this, false)); - registrar.add("Minimap.DerenderPermanent", boost::bind(&LLNetMap::handleDerender, this, true)); + commitRegistrar.add("Minimap.AddFriend", boost::bind(&LLNetMap::handleAddFriend, this)); + commitRegistrar.add("Minimap.AddToContactSet", boost::bind(&LLNetMap::handleAddToContactSet, this)); + commitRegistrar.add("Minimap.RemoveFriend", boost::bind(&LLNetMap::handleRemoveFriend, this)); + commitRegistrar.add("Minimap.IM", boost::bind(&LLNetMap::handleIM, this)); + commitRegistrar.add("Minimap.Call", boost::bind(&LLNetMap::handleCall, this)); + commitRegistrar.add("Minimap.Map", boost::bind(&LLNetMap::handleMap, this)); + commitRegistrar.add("Minimap.Share", boost::bind(&LLNetMap::handleShare, this)); + commitRegistrar.add("Minimap.Pay", boost::bind(&LLNetMap::handlePay, this)); + commitRegistrar.add("Minimap.OfferTeleport", boost::bind(&LLNetMap::handleOfferTeleport, this)); + commitRegistrar.add("Minimap.RequestTeleport", boost::bind(&LLNetMap::handleRequestTeleport, this)); + commitRegistrar.add("Minimap.TeleportToAvatar", boost::bind(&LLNetMap::handleTeleportToAvatar, this)); + commitRegistrar.add("Minimap.GroupInvite", boost::bind(&LLNetMap::handleGroupInvite, this)); + commitRegistrar.add("Minimap.GetScriptInfo", boost::bind(&LLNetMap::handleGetScriptInfo, this)); + commitRegistrar.add("Minimap.BlockUnblock", boost::bind(&LLNetMap::handleBlockUnblock, this)); + commitRegistrar.add("Minimap.Report", boost::bind(&LLNetMap::handleReport, this)); + commitRegistrar.add("Minimap.Freeze", boost::bind(&LLNetMap::handleFreeze, this)); + commitRegistrar.add("Minimap.Eject", boost::bind(&LLNetMap::handleEject, this)); + commitRegistrar.add("Minimap.Kick", boost::bind(&LLNetMap::handleKick, this)); + commitRegistrar.add("Minimap.TeleportHome", boost::bind(&LLNetMap::handleTeleportHome, this)); + commitRegistrar.add("Minimap.EstateBan", boost::bind(&LLNetMap::handleEstateBan, this)); + commitRegistrar.add("Minimap.Derender", boost::bind(&LLNetMap::handleDerender, this, false)); + commitRegistrar.add("Minimap.DerenderPermanent", boost::bind(&LLNetMap::handleDerender, this, true)); - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - enable_registrar.add("Minimap.CheckTextureType", boost::bind(&LLNetMap::checkTextureType, this, _2)); + enableRegistrar.add("Minimap.CheckTextureType", boost::bind(&LLNetMap::checkTextureType, this, _2)); - enable_registrar.add("Minimap.CanAddFriend", boost::bind(&LLNetMap::canAddFriend, this)); - enable_registrar.add("Minimap.CanRemoveFriend", boost::bind(&LLNetMap::canRemoveFriend, this)); - enable_registrar.add("Minimap.CanCall", boost::bind(&LLNetMap::canCall, this)); - enable_registrar.add("Minimap.CanMap", boost::bind(&LLNetMap::canMap, this)); - enable_registrar.add("Minimap.CanShare", boost::bind(&LLNetMap::canShare, this)); - enable_registrar.add("Minimap.CanOfferTeleport", boost::bind(&LLNetMap::canOfferTeleport, this)); - enable_registrar.add("Minimap.CanRequestTeleport", boost::bind(&LLNetMap::canRequestTeleport, this)); - enable_registrar.add("Minimap.IsBlocked", boost::bind(&LLNetMap::isBlocked, this)); - enable_registrar.add("Minimap.CanBlock", boost::bind(&LLNetMap::canBlock, this)); - enable_registrar.add("Minimap.VisibleFreezeEject", boost::bind(&LLNetMap::canFreezeEject, this)); - enable_registrar.add("Minimap.VisibleKickTeleportHome", boost::bind(&LLNetMap::canKickTeleportHome, this)); + enableRegistrar.add("Minimap.CanAddFriend", boost::bind(&LLNetMap::canAddFriend, this)); + enableRegistrar.add("Minimap.CanRemoveFriend", boost::bind(&LLNetMap::canRemoveFriend, this)); + enableRegistrar.add("Minimap.CanCall", boost::bind(&LLNetMap::canCall, this)); + enableRegistrar.add("Minimap.CanMap", boost::bind(&LLNetMap::canMap, this)); + enableRegistrar.add("Minimap.CanShare", boost::bind(&LLNetMap::canShare, this)); + enableRegistrar.add("Minimap.CanOfferTeleport", boost::bind(&LLNetMap::canOfferTeleport, this)); + enableRegistrar.add("Minimap.CanRequestTeleport", boost::bind(&LLNetMap::canRequestTeleport, this)); + enableRegistrar.add("Minimap.IsBlocked", boost::bind(&LLNetMap::isBlocked, this)); + enableRegistrar.add("Minimap.CanBlock", boost::bind(&LLNetMap::canBlock, this)); + enableRegistrar.add("Minimap.VisibleFreezeEject", boost::bind(&LLNetMap::canFreezeEject, this)); + enableRegistrar.add("Minimap.VisibleKickTeleportHome", boost::bind(&LLNetMap::canKickTeleportHome, this)); // [/SL:KB] // [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3) @@ -240,11 +252,11 @@ BOOL LLNetMap::postBuild() mParcelOverlayConn = LLViewerParcelOverlay::setUpdateCallback(boost::bind(&LLNetMap::refreshParcelOverlay, this)); // [/SL:KB] - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_mini_map.xml", gMenuHolder, + LLViewerMenuHolderGL::child_registry_t::instance()); + mPopupMenu->setItemEnabled("Re-center map", false); - // Synchronize tooltips throughout instances - LLNetMap::updateToolTipMsg(); - return TRUE; + return TRUE; } void LLNetMap::setScale( F32 scale ) @@ -313,13 +325,10 @@ void LLNetMap::draw() static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); //static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); - static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); + static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f)); static LLUIColor map_whisper_ring_color = LLUIColorTable::instance().getColor("MapWhisperRingColor", LLColor4::blue); // FIRE-17460 Add Whisper Chat Ring to Minimap static LLUIColor map_chat_ring_color = LLUIColorTable::instance().getColor("MapChatRingColor", LLColor4::yellow); static LLUIColor map_shout_ring_color = LLUIColorTable::instance().getColor("MapShoutRingColor", LLColor4::red); -// [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-08-17 (Catznip-3.3) - static LLUIColor map_property_line = LLUIColorTable::instance().getColor("MiniMapPropertyLine", LLColor4::white); -// [/SL:KB] if (mObjectImagep.isNull()) { @@ -333,11 +342,25 @@ void LLNetMap::draw() } // [/SL:KB] - static LLUICachedControl auto_center("MiniMapAutoCenter", true); - if (auto_center) + static LLUICachedControl auto_center("MiniMapAutoCenter", true); + bool auto_centering = auto_center && !mPanning; + mCentering = mCentering && !mPanning; + + if (auto_centering || mCentering) { - mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f)); + mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f)); } + bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f; + if (centered) + { + mCurPan.mV[0] = 0.0f; + mCurPan.mV[1] = 0.0f; + mCentering = false; + } + + bool can_recenter_map = !(centered || mCentering || auto_centering); + mPopupMenu->setItemEnabled("Re-center map", can_recenter_map); + updateAboutLandPopupButton(); // Prepare a scissor region F32 rotation = 0; @@ -388,6 +411,7 @@ void LLNetMap::draw() //S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters()); S32 region_width = ll_round(REGION_WIDTH_METERS); // Aurora Sim + const F32 scale_pixels_per_meter = mScale / region_width; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -396,8 +420,8 @@ void LLNetMap::draw() // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); - F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; - F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; + F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter; + F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter; // background region rectangle F32 bottom = relative_y; @@ -589,7 +613,7 @@ void LLNetMap::draw() } // [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3) - static LLCachedControl s_fShowPropertyLines(gSavedSettings, "MiniMapPropertyLines") ; + static LLCachedControl s_fShowPropertyLines(gSavedSettings, "MiniMapShowPropertyLines") ; if ( (s_fShowPropertyLines) && ((mUpdateParcelImage) || (dist_vec_squared2D(mParcelImageCenterGlobal, posCenterGlobal) > 9.0f)) ) { mUpdateParcelImage = false; @@ -604,7 +628,7 @@ void LLNetMap::draw() { const LLViewerRegion* pRegion = *itRegion; LLColor4U clrOverlay; if (pRegion->isAlive()) - clrOverlay = map_property_line.get(); + clrOverlay = map_parcel_outline_color.get(); else clrOverlay = LLColor4U(255, 128, 128, 255); renderPropertyLinesForRegion(pRegion, clrOverlay); @@ -617,8 +641,8 @@ void LLNetMap::draw() LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); LLVector3 camera_position = gAgentCamera.getCameraPositionAgent(); map_center_agent -= camera_position; - map_center_agent.mV[VX] *= mScale/region_width; - map_center_agent.mV[VY] *= mScale/region_width; + map_center_agent.mV[VX] *= scale_pixels_per_meter; + map_center_agent.mV[VY] *= scale_pixels_per_meter; // gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; @@ -688,6 +712,15 @@ void LLNetMap::draw() } // [/SL:KB] + // Replaced with Kitty's implementation + //for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + // iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + //{ + // LLViewerRegion* regionp = *iter; + // regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV); + //} + // + gGL.popMatrix(); // Mouse pointer in local coordinates @@ -888,47 +921,40 @@ void LLNetMap::draw() F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; - - F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); - F32 half_width_pixels = half_width_meters * meters_to_pixels; - F32 ctr_x = (F32)center_sw_left; - F32 ctr_y = (F32)center_sw_bottom; + F32 ctr_x = (F32)center_sw_left; + F32 ctr_y = (F32)center_sw_bottom; + const F32 steps_per_circle = 40.0f; + const F32 steps_per_radian = steps_per_circle / F_TWO_PI; + const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO; + const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO; + const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f)); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // Draw pick radius; from Ayamo Nozaki (Exodus Viewer) - static LLUIColor pick_radius_color = LLUIColorTable::instance().getColor("MapPickRadiusColor", map_frustum_color()); - gGL.color4fv((pick_radius_color()).mV); - gl_circle_2d(local_mouse_x, local_mouse_y, mDotRadius * fsMinimapPickScale, 32, true); - // + // Draw pick radius; from Ayamo Nozaki (Exodus Viewer) + static LLUIColor pick_radius_color = LLUIColorTable::instance().getColor("MapPickRadiusColor", map_frustum_color()); + gGL.color4fv((pick_radius_color()).mV); + gl_circle_2d(local_mouse_x, local_mouse_y, mDotRadius * fsMinimapPickScale, 32, true); + // - if( rotate_map ) - { - gGL.color4fv((map_frustum_color()).mV); - - gGL.begin( LLRender::TRIANGLES ); - gGL.vertex2f( ctr_x, ctr_y ); - gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); - gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); - gGL.end(); - } - else - { - gGL.color4fv((map_frustum_rotating_color()).mV); - - // If we don't rotate the map, we have to rotate the frustum. - gGL.pushMatrix(); - gGL.translatef( ctr_x, ctr_y, 0 ); - gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); - gGL.begin( LLRender::TRIANGLES ); - gGL.vertex2f( 0, 0 ); - gGL.vertex2f( -half_width_pixels, far_clip_pixels ); - gGL.vertex2f( half_width_pixels, far_clip_pixels ); - gGL.end(); - gGL.popMatrix(); - } + if( rotate_map ) + { + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); + gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color()); + gGL.popMatrix(); + } + else + { + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); + // If we don't rotate the map, we have to rotate the frustum. + gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); + gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color()); + gGL.popMatrix(); + } } gGL.popMatrix(); @@ -1017,6 +1043,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, } } +bool LLNetMap::isMouseOnPopupMenu() +{ + if (!mPopupMenu->isOpen()) + { + return false; + } + + S32 popup_x; + S32 popup_y; + LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y); + // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain + // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22 + constexpr S32 tolerance = 10; + // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space. + // Assume the size of the popup menu is much larger than the provided tolerance. + // In practice, this is a [tolerance]px margin around the popup menu. + for (S32 sign_x = -1; sign_x <= 1; sign_x += 2) + { + for (S32 sign_y = -1; sign_y <= 1; sign_y += 2) + { + if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance))) + { + return true; + } + } + } + return false; +} + +void LLNetMap::updateAboutLandPopupButton() +{ + if (!mPopupMenu->isOpen()) + { + return; + } + + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos); + if (!region) + { + mPopupMenu->setItemEnabled("About Land", false); + } + else + { + // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover + // parcel can be used to check if location-sensitive tooltip options are available. + if (isMouseOnPopupMenu()) + { + LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos); + LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); + bool valid_parcel = false; + if (hover_parcel) + { + valid_parcel = hover_parcel->getOwnerID().notNull(); + } + mPopupMenu->setItemEnabled("About Land", valid_parcel); + } + } +} + LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) { x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]); @@ -1047,83 +1132,185 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { - // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in - F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); + // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in + F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); F32 old_scale = mScale; - setScale(new_scale); + setScale(new_scale); - static LLUICachedControl auto_center("MiniMapAutoCenter", true); - if (!auto_center) - { - // Adjust pan to center the zoom on the mouse pointer - LLVector2 zoom_offset; - zoom_offset.mV[VX] = x - getRect().getWidth() / 2; - zoom_offset.mV[VY] = y - getRect().getHeight() / 2; - mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; - } + static LLUICachedControl auto_center("MiniMapAutoCenter", true); + if (!auto_center) + { + // Adjust pan to center the zoom on the mouse pointer + LLVector2 zoom_offset; + zoom_offset.mV[VX] = x - getRect().getWidth() / 2; + zoom_offset.mV[VY] = y - getRect().getHeight() / 2; + mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; + } - return TRUE; + return true; } -BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask) { - if (gDisconnected) - { - return FALSE; - } + if (gDisconnected) + { + return false; + } - // If the cursor is near an avatar on the minimap, a mini-inspector will be - // shown for the avatar, instead of the normal map tooltip. -// if (handleToolTipAgent(mClosestAgentToCursor)) + // If the cursor is near an avatar on the minimap, a mini-inspector will be + // shown for the avatar, instead of the normal map tooltip. +// if (handleToolTipAgent(mClosestAgentToCursor)) // [RLVa:KB] - Checked: RLVa-1.2.2 - bool fRlvCanShowName = (mClosestAgentToCursor.notNull()) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, mClosestAgentToCursor)); - if ( (fRlvCanShowName) && (handleToolTipAgent(mClosestAgentToCursor)) ) + bool fRlvCanShowName = (mClosestAgentToCursor.notNull()) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, mClosestAgentToCursor)); + if ( (fRlvCanShowName) && (handleToolTipAgent(mClosestAgentToCursor)) ) // [/RLVa:KB] - { - return TRUE; - } + { + return TRUE; + } + + // The popup menu uses the hover parcel when it is open and the mouse is on + // top of it, with some additional tolerance. Returning early here prevents + // fighting over that hover parcel when getting tooltip info in the + // tolerance region. + if (isMouseOnPopupMenu()) + { + return false; + } // [RLVa:KB] - Checked: RLVa-1.2.2 - LLStringUtil::format_map_t args; LLAvatarName avName; - args["[AGENT]"] = ( (!fRlvCanShowName) && (mClosestAgentToCursor.notNull()) && (LLAvatarNameCache::get(mClosestAgentToCursor, &avName)) ) ? RlvStrings::getAnonym(avName) + "\n" : ""; + LLStringUtil::format_map_t args; LLAvatarName avName; + args["[AGENT]"] = ( (!fRlvCanShowName) && (mClosestAgentToCursor.notNull()) && (LLAvatarNameCache::get(mClosestAgentToCursor, &avName)) ) ? RlvStrings::getAnonym(avName) + "\n" : ""; // [/RLVa:KB] - LLRect sticky_rect; - std::string region_name; - LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); - if(region) - { - // set sticky_rect - S32 SLOP = 4; - localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); - sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; - sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; + LLRect sticky_rect; + S32 SLOP = 4; + localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); + sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; + sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; -// region_name = region->getName(); + std::string parcel_name_msg; + std::string parcel_sale_price_msg; + std::string parcel_sale_area_msg; + std::string parcel_owner_msg; + std::string region_name_msg; + + LLVector3d posGlobal = viewPosToGlobal(x, y); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal); + if (region) + { +// std::string region_name = region->getName(); // [RLVa:KB] - Checked: RLVa-1.2.2 - region_name = (RlvActions::canShowLocation()) ? region->getName() : RlvStrings::getString(RlvStringKeys::Hidden::Region); + std::string region_name = (RlvActions::canShowLocation()) ? region->getName() : RlvStrings::getString(RlvStringKeys::Hidden::Region); // [/RLVa:KB] - // Synchronize tooltips throughout instances - //if (!region_name.empty()) - if (!region_name.empty() && LLNetMap::sToolTipMsg != "[REGION]") - { - region_name += "\n"; - } - } + if (!region_name.empty()) + { + region_name_msg = mRegionNameMsg; + LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}}); + } -// LLStringUtil::format_map_t args; - args["[REGION]"] = region_name; - // Synchronize tooltips throughout instances - //std::string msg = mToolTipMsg; - std::string msg = LLNetMap::sToolTipMsg; - // Synchronize tooltips throughout instances - LLStringUtil::format(msg, args); - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(msg) - .sticky_rect(sticky_rect)); - - return TRUE; + // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is + // ambiguous. + if (gSavedSettings.getBOOL("MiniMapShowPropertyLines")) + { + LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal); + LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); + if (hover_parcel) + { + //std::string parcel_name = hover_parcel->getName(); +// [RLVa:KB] - Checked: RLVa-1.2.2 + std::string parcel_name = (RlvActions::canShowLocation()) ? hover_parcel->getName() : RlvStrings::getString(RlvStringKeys::Hidden::Parcel); +// [/RLVa:KB] + if (!parcel_name.empty()) + { + parcel_name_msg = mParcelNameMsg; + LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}}); + } + + const LLUUID parcel_owner = hover_parcel->getOwnerID(); +// [RLVa:KB] - Checked: RLVa-1.2.2 + //std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString(); + std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, RlvActions::canShowName(RlvActions::SNC_DEFAULT, parcel_owner) ? "inspect" : "rlvanonym").getSLURLString(); +// [/RLVa:KB] + static LLUrlMatch parcel_owner_name_url_match; + LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match); + if (!parcel_owner_name_url_match.empty()) + { + parcel_owner_msg = mParcelOwnerMsg; + std::string parcel_owner_name = parcel_owner_name_url_match.getLabel(); + LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}}); + } + + if (hover_parcel->getForSale()) + { + const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID(); + const LLUUID agent_id = gAgent.getID(); + bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id; + if (show_for_sale) + { + S32 price = hover_parcel->getSalePrice(); + S32 area = hover_parcel->getArea(); + F32 cost_per_sqm = 0.0f; + if (area > 0) + { + cost_per_sqm = F32(price) / area; + } + std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price); + std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm); + parcel_sale_price_msg = mParcelSalePriceMsg; + LLStringUtil::format(parcel_sale_price_msg, + {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}}); + std::string formatted_area = llformat("%d", area); + parcel_sale_area_msg = mParcelSaleAreaMsg; + LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}}); + } + } + } + } + } + + // Synchronize double click handling throughout instances + std::string tool_tip_hint_msg; + //if (gSavedSettings.getBOOL("DoubleClickTeleport")) + //{ + // tool_tip_hint_msg = mAltToolTipHintMsg; + //} + //else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) + //{ + // tool_tip_hint_msg = mToolTipHintMsg; + //} + switch (gSavedSettings.getS32("FSNetMapDoubleClickAction")) + { + case 1: + tool_tip_hint_msg = mToolTipHintMsg; + break; + case 2: + tool_tip_hint_msg = mAltToolTipHintMsg; + break; + default: + break; + } + // + +// [RLVa:KB] - Checked: RLVa-1.2.2 + //LLStringUtil::format_map_t args; +// [/RLVa:KB] + args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n'; + args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n'; + args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n'; + args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n'; + args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n'; + args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n'; + + std::string msg = mToolTipMsg; + LLStringUtil::format(msg, args); + if (msg.back() == '\n') + { + msg.resize(msg.size() - 1); + } + LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect)); + + return true; } BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id) @@ -1497,50 +1684,51 @@ void LLNetMap::createParcelImage() } // [/SL:KB] -BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask) { - if (!(mask & MASK_SHIFT)) return FALSE; + // FIRE-32339: Mini map can't be dragged anymore + if (!(mask & MASK_SHIFT)) return FALSE; - // Start panning - gFocusMgr.setMouseCapture(this); + // Start panning + gFocusMgr.setMouseCapture(this); - mStartPan = mCurPan; - mMouseDown.mX = x; - mMouseDown.mY = y; - return TRUE; + mStartPan = mCurPan; + mMouseDown.mX = x; + mMouseDown.mY = y; + return true; } -BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask) { - if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3) - handleClick(x,y,mask); + if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3) + { + handleClick(x, y, mask); + } - if (hasMouseCapture()) - { - if (mPanning) - { - // restore mouse cursor - S32 local_x, local_y; - local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); - local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); - LLRect clip_rect = getRect(); - clip_rect.stretch(-8); - clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); - LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y); + if (hasMouseCapture()) + { + if (mPanning) + { + // restore mouse cursor + S32 local_x, local_y; + local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); + local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); + LLRect clip_rect = getRect(); + clip_rect.stretch(-8); + clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); + LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y); - // finish the pan - mPanning = false; + // finish the pan + mPanning = false; - mMouseDown.set(0, 0); + mMouseDown.set(0, 0); + } + gViewerWindow->showCursor(); + gFocusMgr.setMouseCapture(NULL); + return true; + } - // auto centre - mTargetPan.setZero(); - } - gViewerWindow->showCursor(); - gFocusMgr.setMouseCapture(NULL); - return TRUE; - } - return FALSE; + return false; } // [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3) @@ -1586,9 +1774,9 @@ void LLNetMap::handleShowProfile(const LLSD& sdParam) const { LLSD sdParams; sdParams["type"] = "remote_place"; - sdParams["x"] = mPosGlobalRightClick.mdV[VX]; - sdParams["y"] = mPosGlobalRightClick.mdV[VY]; - sdParams["z"] = mPosGlobalRightClick.mdV[VZ]; + sdParams["x"] = mPopupWorldPos.mdV[VX]; + sdParams["y"] = mPopupWorldPos.mdV[VY]; + sdParams["z"] = mPopupWorldPos.mdV[VZ]; FSFloaterPlaceDetails::showPlaceDetails(sdParams); } @@ -1616,10 +1804,10 @@ BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) { if (mPopupMenu) { + mPopupWorldPos = viewPosToGlobal(x, y); // [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3) mClosestAgentRightClick = mClosestAgentToCursor; mClosestAgentsRightClick = mClosestAgentsToCursor; - mPosGlobalRightClick = viewPosToGlobal(x, y); mPopupMenu->setItemVisible("Add to Set Multiple", mClosestAgentsToCursor.size() > 1); mPopupMenu->setItemVisible("More Options", mClosestAgentsToCursor.size() == 1); @@ -1735,6 +1923,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } +F32 LLNetMap::getScaleForName(std::string scale_name) +{ + if (scale_name == "very close") + { + return LLNetMap::MAP_SCALE_VERY_CLOSE; + } + else if (scale_name == "close") + { + return LLNetMap::MAP_SCALE_CLOSE; + } + else if (scale_name == "medium") + { + return LLNetMap::MAP_SCALE_MEDIUM; + } + else if (scale_name == "far") + { + return LLNetMap::MAP_SCALE_FAR; + } + return 0.0f; +} + // static bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop ) { @@ -1752,7 +1961,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) { if (!mPanning) { - // just started panning, so hide cursor + // Just started panning. Hide cursor. mPanning = true; gViewerWindow->hideCursor(); } @@ -1762,62 +1971,40 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) // Set pan to value at start of drag + offset mCurPan += delta; - mTargetPan = mCurPan; gViewerWindow->moveCursorToCenter(); } + } - // Doesn't really matter, cursor should be hidden - gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); - } - else - { - if (mask & MASK_SHIFT) - { - // If shift is held, change the cursor to hint that the map can be dragged - gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); - } - else - { - gViewerWindow->setCursor( UI_CURSOR_CROSS ); - } - } + if (mask & MASK_SHIFT) + { + // If shift is held, change the cursor to hint that the map can be + // dragged. However, holding shift is not required to drag the map. + gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); + } + else + { + gViewerWindow->setCursor( UI_CURSOR_CROSS ); + } return TRUE; } -void LLNetMap::handleZoom(const LLSD& userdata) +bool LLNetMap::isZoomChecked(const LLSD &userdata) { - std::string level = userdata.asString(); - - F32 scale = 0.0f; -// [SL:KB] - Patch: World-MinimapZoom | Checked: 2012-08-15 (Catznip-3.3) - //if (level == "close") - // scale = 2048.f; - //else if (level == "medium") - // scale = 512.f; - //else if (level == "far") - // scale = 128.f; -// [/Sl:KB] - if (level == std::string("default")) - { - LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); - if(pvar) - { - pvar->resetToDefault(); - scale = gSavedSettings.getF32("MiniMapScale"); - } - } - else if (level == std::string("close")) - scale = LLNetMap::MAP_SCALE_MAX; - else if (level == std::string("medium")) - scale = LLNetMap::MAP_SCALE_MID; - else if (level == std::string("far")) - scale = LLNetMap::MAP_SCALE_MIN; - if (scale != 0.0f) - { - setScale(scale); - } + std::string level = userdata.asString(); + F32 scale = getScaleForName(level); + return scale == mScale; +} + +void LLNetMap::setZoom(const LLSD &userdata) +{ + std::string level = userdata.asString(); + F32 scale = getScaleForName(level); + if (scale != 0.0f) + { + setScale(scale); + } } // Mark avatar feature @@ -1950,25 +2137,47 @@ void LLNetMap::handleStopTracking (const LLSD& userdata) } } -// Synchronize tooltips throughout instances -// static -void LLNetMap::updateToolTipMsg() +void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; } + +bool LLNetMap::isMapOrientationChecked(const LLSD &userdata) { - S32 fsNetMapDoubleClickAction = gSavedSettings.getS32("FSNetMapDoubleClickAction"); - switch (fsNetMapDoubleClickAction) - { - case 1: - LLNetMap::setToolTipMsg(LLTrans::getString("NetMapDoubleClickShowWorldMapToolTipMsg")); - break; - case 2: - LLNetMap::setToolTipMsg(LLTrans::getString("NetMapDoubleClickTeleportToolTipMsg")); - break; - default: - LLNetMap::setToolTipMsg(LLTrans::getString("NetMapDoubleClickNoActionToolTipMsg")); - break; - } + const std::string command_name = userdata.asString(); + const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate"); + if (command_name == "north_at_top") + { + return !rotate_map; + } + + if (command_name == "camera_at_top") + { + return rotate_map; + } + + return false; +} + +void LLNetMap::setMapOrientation(const LLSD &userdata) +{ + const std::string command_name = userdata.asString(); + if (command_name == "north_at_top") + { + gSavedSettings.setBOOL("MiniMapRotate", false); + } + else if (command_name == "camera_at_top") + { + gSavedSettings.setBOOL("MiniMapRotate", true); + } +} + +void LLNetMap::popupShowAboutLand(const LLSD &userdata) +{ + // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection. + LLViewerParcelMgr::getInstance()->deselectLand(); + LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos); + gMenuHolder->setParcelSelection(selection); + + LLFloaterReg::showInstance("about_land", LLSD(), false); } -// Synchronize tooltips throughout instances // Synchronize double click handling throughout instances void LLNetMap::performDoubleClickAction(LLVector3d pos_global) diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index a06a10b8e5..f2de5a91fe 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -66,9 +66,12 @@ protected: public: virtual ~LLNetMap(); - static const F32 MAP_SCALE_MIN; - static const F32 MAP_SCALE_MID; - static const F32 MAP_SCALE_MAX; + static const F32 MAP_SCALE_MIN; + static const F32 MAP_SCALE_FAR; + static const F32 MAP_SCALE_MEDIUM; + static const F32 MAP_SCALE_CLOSE; + static const F32 MAP_SCALE_VERY_CLOSE; + static const F32 MAP_SCALE_MAX; /*virtual*/ void draw(); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -84,14 +87,19 @@ public: /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); // [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3) - void refreshParcelOverlay() { mUpdateParcelImage = true; } + void refreshParcelOverlay() { mUpdateParcelImage = true; } // [/SL:KB] - void setScale( F32 scale ); - // Synchronize tooltips throughout instances - //void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } - static void setToolTipMsg(const std::string& msg) { sToolTipMsg = msg; } - static void updateToolTipMsg(); - // Synchronize tooltips throughout instances + void setScale(F32 scale); + + void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } + void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; } + void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; } + void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; } + void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; } + void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; } + void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; } + void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; } + void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); LLVector3d viewPosToGlobal(S32 x,S32 y); LLUUID getClosestAgentToCursor() const { return mClosestAgentToCursor; } @@ -122,6 +130,8 @@ private: const LLColor4& color, BOOL draw_arrow = TRUE); void drawRing(const F32 radius, LLVector3 pos_map, const LLUIColor& color); + bool isMouseOnPopupMenu(); + void updateAboutLandPopupButton(); BOOL handleToolTipAgent(const LLUUID& avatar_id); static void showAvatarInspector(const LLUUID& avatar_id); @@ -130,6 +140,7 @@ private: void createObjectImage(); void createParcelImage(); + F32 getScaleForName(std::string scale_name); void renderPropertyLinesForRegion(const LLViewerRegion* pRegion, const LLColor4U& clrOverlay); // [/SL:KB] // void createObjectImage(); @@ -152,11 +163,12 @@ private: F32 mObjectMapPixels; // Width of object map in pixels F32 mDotRadius; // Size of avatar markers - bool mPanning; // map is being dragged - LLVector2 mTargetPan; - LLVector2 mCurPan; - LLVector2 mStartPan; // pan offset at start of drag - LLCoordGL mMouseDown; // pointer position at start of drag + bool mPanning; // map is being dragged + bool mCentering; // map is being re-centered around the agent + LLVector2 mCurPan; + LLVector2 mStartPan; // pan offset at start of drag + LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened + LLCoordGL mMouseDown; // pointer position at start of drag LLVector3d mObjectImageCenterGlobal; LLPointer mObjectRawImagep; @@ -174,10 +186,15 @@ private: // [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3) LLVector3d mClosestAgentPosition; // [/SL:KB] - // Synchronize tooltips throughout instances - //std::string mToolTipMsg; - static std::string sToolTipMsg; - // Synchronize tooltips throughout instances + + std::string mToolTipMsg; + std::string mParcelNameMsg; + std::string mParcelSalePriceMsg; + std::string mParcelSaleAreaMsg; + std::string mParcelOwnerMsg; + std::string mRegionNameMsg; + std::string mToolTipHintMsg; + std::string mAltToolTipHintMsg; // Mark avatar feature typedef std::map avatar_marks_map_t; @@ -188,14 +205,18 @@ public: // Minimap improvements void handleShowProfile(const LLSD& sdParam) const; uuid_vec_t mClosestAgentsToCursor; - LLVector3d mPosGlobalRightClick; LLUUID mClosestAgentRightClick; uuid_vec_t mClosestAgentsRightClick; // private: - void handleZoom(const LLSD& userdata); - void handleStopTracking (const LLSD& userdata); + bool isZoomChecked(const LLSD& userdata); + void setZoom(const LLSD& userdata); + void handleStopTracking(const LLSD& userdata); + void activateCenterMap(const LLSD& userdata); + bool isMapOrientationChecked(const LLSD& userdata); + void setMapOrientation(const LLSD& userdata); + void popupShowAboutLand(const LLSD& userdata); void handleStartTracking(); void handleMark(const LLSD& userdata); void handleClearMark(); diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index ff33efe4aa..3632d7c631 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -84,6 +84,19 @@ void LLPanelProfileTab::setAvatarId(const LLUUID& avatar_id) { mAvatarId = avatar_id; mSelfProfile = (getAvatarId() == gAgentID); + + // FIRE-32179: Make drag-n-drop sharing of items possible again + LLProfileDropTarget* target = getChild("drop_target"); + if (avatar_id == gAgentID) + { + // hide drop target on own profile + target->setVisible(false); + } + else + { + target->setAgentID(avatar_id); + } + // } } diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 1823d55319..1b0b25629f 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -78,6 +78,7 @@ #include "llviewertexturelist.h" #include "llvoiceclient.h" #include "llweb.h" +#include "llviewernetwork.h" // For LLGridManager #include "fsdata.h" #include "llviewermenu.h" @@ -100,6 +101,8 @@ static const std::string PANEL_PROFILE_VIEW = "panel_profile_view"; static const std::string PROFILE_PROPERTIES_CAP = "AgentProfile"; static const std::string PROFILE_IMAGE_UPLOAD_CAP = "UploadAgentProfileImage"; +// FIRE-32184: Online/Offline status not working for non-friends +const U32 AVATAR_ONLINE_UNDEFINED = 0x1 << 31; ////////////////////////////////////////////////////////////////////////// @@ -164,7 +167,14 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id) avatar_data->flags = 0; - if (result["online"].asBoolean()) + // FIRE-32184: Online/Offline status not working for non-friends + // if (result["online"].asBoolean()) + if (result["online"].isUndefined()) + { + avatar_data->flags |= AVATAR_ONLINE_UNDEFINED; + } + else if (result["online"].asBoolean()) + // { avatar_data->flags |= AVATAR_ONLINE; } @@ -875,7 +885,7 @@ void LLFloaterProfilePermissions::onCancel() // LLPanelProfileSecondLife LLPanelProfileSecondLife::LLPanelProfileSecondLife() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() // alter ancestry to re-enable UDP , mAvatarNameCacheConnection() , mHasUnsavedDescriptionChanges(false) , mWaitingForImageUpload(false) @@ -889,6 +899,8 @@ LLPanelProfileSecondLife::~LLPanelProfileSecondLife() if (getAvatarId().notNull()) { LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); + // FIRE-32184: Online/Offline status not working for non-friends + LLAvatarPropertiesProcessor::getInstance()->removeObserver(getAvatarId(), &mPropertiesObserver); } if (LLVoiceClient::instanceExists()) @@ -916,7 +928,10 @@ BOOL LLPanelProfileSecondLife::postBuild() //mShowInSearchCombo = getChild("show_in_search"); mShowInSearchCheckbox = getChild("show_in_search"); // - mSecondLifePic = getChild("2nd_life_pic"); + // Allow proper texture swatch handling + // mSecondLifePic = getChild("2nd_life_pic"); + mSecondLifePic = getChild("2nd_life_pic"); + // mSecondLifePicLayout = getChild("image_panel"); mDescriptionEdit = getChild("sl_description_edit"); // mAgentActionMenuButton = getChild("agent_actions_menu"); // Fix LL UI/UX design accident @@ -940,6 +955,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mBlockButton = getChild("block"); mUnblockButton = getChild("unblock"); mAddFriendButton = getChild("add_friend"); + mRemoveFriendButton = getChild("remove_friend"); // Add "Remove Friend" button to profile mPayButton = getChild("pay"); mIMButton = getChild("im"); mOverflowButton = getChild("overflow_btn"); @@ -955,6 +971,7 @@ BOOL LLPanelProfileSecondLife::postBuild() mBlockButton->setCommitCallback([this](LLUICtrl*, void*) { onCommitMenu(LLSD("toggle_block_agent")); }, nullptr); mUnblockButton->setCommitCallback([this](LLUICtrl*, void*) { onCommitMenu(LLSD("toggle_block_agent")); }, nullptr); mAddFriendButton->setCommitCallback([this](LLUICtrl*, void*) { onCommitMenu(LLSD("add_friend")); }, nullptr); + mRemoveFriendButton->setCommitCallback([this](LLUICtrl*, void*) { onCommitMenu(LLSD("remove_friend")); }, nullptr); // Add "Remove Friend" button to profile mPayButton->setCommitCallback([this](LLUICtrl*, void*) { onCommitMenu(LLSD("pay")); }, nullptr); mIMButton->setCommitCallback([this](LLUICtrl*, void*) { onCommitMenu(LLSD("im")); }, nullptr); // @@ -970,7 +987,10 @@ BOOL LLPanelProfileSecondLife::postBuild() mCantSeeOnMapIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); mCanEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); mCantEditObjectsIcon->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentPermissionsDialog(); }); - mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); }); + // Allow proper texture swatch handling + // mSecondLifePic->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowAgentProfileTexture(); }); + mSecondLifePic->setCommitCallback(boost::bind(&LLPanelProfileSecondLife::onSecondLifePicChanged, this)); + // // RLVa support mRlvBehaviorCallbackConnection = gRlvHandler.setBehaviourCallback(boost::bind(&LLPanelProfileSecondLife::updateRlvRestrictions, this, _1)); @@ -978,10 +998,21 @@ BOOL LLPanelProfileSecondLife::postBuild() return TRUE; } +// FIRE-32184: Online/Offline status not working for non-friends +void LLPanelProfileSecondLife::onAvatarProperties(const LLAvatarData* d) +{ + // only update the "unknown" status if they are showing as online, otherwise + // we still don't know their true status + if (d->agent_id == gAgentID && d->flags & AVATAR_ONLINE) + { + processOnlineStatus(false, true, true); + } +} +// + void LLPanelProfileSecondLife::onOpen(const LLSD& key) { - LLPanelProfileTab::onOpen(key); - + LLPanelProfilePropertiesProcessorTab::onOpen(key); // alter ancestry to re-enable UDP resetData(); LLUUID avatar_id = getAvatarId(); @@ -1024,7 +1055,16 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) // // Todo: use PeopleContextMenu instead? // mAgentActionMenuButton->setMenu("menu_profile_other.xml", LLMenuButton::MP_BOTTOM_RIGHT); //} +// Remove the menu thingy and just have click picture to change +// if (own_profile) +// only if we are in opensim and opensim doesn't have the image upload cap +#ifdef OPENSIM + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if( own_profile && (!LLGridManager::instance().isInOpenSim() || !cap_url.empty() ) ) +#else if (own_profile) +#endif +// { mImageActionMenuButton->setVisible(TRUE); mImageActionMenuButton->setMenu("menu_fs_profile_image_actions.xml", LLMenuButton::MP_BOTTOM_RIGHT); @@ -1051,6 +1091,9 @@ void LLPanelProfileSecondLife::onOpen(const LLSD& key) // Display agent ID getChild("user_key")->setValue(avatar_id.asString()); + // Allow proper texture swatch handling + mSecondLifePic->setEnabled(own_profile); + mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLPanelProfileSecondLife::onAvatarNameCache, this, _1, _2)); } @@ -1069,6 +1112,15 @@ void LLPanelProfileSecondLife::updateData() } else { + // restore UDP profiles for opensim that does not support the cap +#ifdef OPENSIM + if (LLGridManager::instance().isInOpenSim() && !(getSelfProfile() /* TODO(Beq):No longer neeed? && !getEmbedded()*/)) + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarGroupsRequest(avatar_id); + } + else +#endif + // LL_WARNS() << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -1082,6 +1134,43 @@ void LLPanelProfileSecondLife::refreshName() } } +// Restore UDP profiles +void LLPanelProfileSecondLife::apply(LLAvatarData* data) +{ +#ifdef OPENSIM + if (LLGridManager::instance().isInOpenSim() && getIsLoaded() && getSelfProfile()) + { + data->image_id = mImageId; + data->about_text = mDescriptionEdit->getValue().asString(); + data->allow_publish = mShowInSearchCheckbox->getValue(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(data); + } +#endif +} + +void LLPanelProfileSecondLife::processProperties(void* data, EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + const LLAvatarData* avatar_data = static_cast(data); + if(avatar_data && getAvatarId() == avatar_data->avatar_id) + { + processProfileProperties(avatar_data); + setLoaded(); + } + } + else if (APT_GROUPS == type) + { + LLAvatarGroups* avatar_groups = static_cast(data); + if(avatar_groups && getAvatarId() == avatar_groups->avatar_id) + { + processGroupProperties(avatar_groups); + } + } +} +// + void LLPanelProfileSecondLife::resetData() { resetLoading(); @@ -1122,7 +1211,8 @@ void LLPanelProfileSecondLife::resetData() // Fix LL UI/UX design accident //childSetVisible("partner_layout", FALSE); - mStatusText->setVisible(FALSE); + // Always show the online status text, just set it to "offline" when a friend is hiding + // mStatusText->setVisible(FALSE); mCopyMenuButton->setVisible(FALSE); mGroupInviteButton->setVisible(!own_profile); if (own_profile && LLAvatarName::useDisplayNames()) @@ -1135,6 +1225,7 @@ void LLPanelProfileSecondLife::resetData() mTeleportButton->setVisible(!own_profile); mIMButton->setVisible(!own_profile); mAddFriendButton->setVisible(!own_profile); + mRemoveFriendButton->setVisible(!own_profile); // Add "Remove Friend" button to profile mBlockButton->setVisible(!own_profile); mUnblockButton->setVisible(!own_profile); mGroupList->setShowNone(!own_profile); @@ -1157,12 +1248,40 @@ void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avat gAgent.isGodlike() || relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS), (avatar_data->flags & AVATAR_ONLINE)); } + // FIRE-32184: Online/Offline status not working for non-friends + else if (avatar_data->flags & AVATAR_ONLINE_UNDEFINED) + { + // being a friend who doesn't show online status and appears online can't happen + // so this is our marker for "undefined" + processOnlineStatus(true, false, true); + } + // fillCommonData(avatar_data); fillPartnerData(avatar_data); fillAccountStatus(avatar_data); +// Restore UDP profiles +#ifdef OPENSIM + if (LLGridManager::instance().isInOpenSim()) + { + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", avatar_id)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + LLPanel *panel = floater_profile->findChild(PANEL_PROFILE_VIEW, TRUE); + auto *panel_profile = dynamic_cast(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + } + panel_profile->setAvatarData(avatar_data); + } +#endif +// setLoaded(); @@ -1480,7 +1599,7 @@ void LLPanelProfileSecondLife::fillAgeData(const LLDate &born_on) std::string register_date = getString("age_format"); LLSD args_age; // Fix LL UI/UX design accident - std::string birth_date = LLTrans::getString("AvatarBirthDateFormat"); + std::string birth_date = LLTrans::getString(!gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP).empty() ? "AvatarBirthDateFormat" : "AvatarBirthDateFormat_legacy"); LLStringUtil::format(birth_date, LLSD().with("datetime", (S32)born_on.secondsSinceEpoch())); args_age["[REG_DATE]"] = birth_date; // @@ -1569,7 +1688,7 @@ void LLPanelProfileSecondLife::setAvatarId(const LLUUID& avatar_id) LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this); } - LLPanelProfileTab::setAvatarId(avatar_id); + LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); // Change ancestry to restore UDP profiles if (LLAvatarActions::isFriend(getAvatarId())) { @@ -1601,11 +1720,28 @@ void LLPanelProfileSecondLife::updateOnlineStatus() void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online) { + // FIRE-32184: Online/Offline status not working for non-friends + // being a friend who doesn't show online status and appears online can't happen + // so this is our marker for "undefined" + if (is_friend && !show_online && online) + { + mStatusText->setValue(getString("status_unknown")); + mStatusText->setColor(LLUIColorTable::getInstance()->getColor("StatusUserUnknown")); + + mPropertiesObserver.mPanelProfile = this; + mPropertiesObserver.mRequester = gAgentID; + LLAvatarPropertiesProcessor::getInstance()->addObserver(getAvatarId(), &mPropertiesObserver); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(getAvatarId()); + + return; + } + // // Fix LL UI/UX design accident //childSetVisible("frind_layout", is_friend); //childSetVisible("online_layout", online && show_online); //childSetVisible("offline_layout", !online && show_online); - mStatusText->setVisible(show_online); + // Always show the online status text, just set it to "offline" when a friend is hiding + // mStatusText->setVisible(show_online); std::string status = getString(online ? "status_online" : "status_offline"); @@ -1656,7 +1792,11 @@ void LLPanelProfileSecondLife::updateButtons() mTeleportButton->setEnabled(is_buddy_online && can_offer_tp); // //Disable "Add Friend" button for friends. - mAddFriendButton->setEnabled(false); + // Add "Remove Friend" button to profile + // mAddFriendButton->setEnabled(false); + mAddFriendButton->setVisible(false); + mRemoveFriendButton->setVisible(true); + // } else { @@ -1666,7 +1806,11 @@ void LLPanelProfileSecondLife::updateButtons() gRlvHandler.isException(RLV_BHVR_TPLURE, av_id, ERlvExceptionCheck::Permissive)); mTeleportButton->setEnabled(can_offer_tp); // - mAddFriendButton->setEnabled(true); + // Add "Remove Friend" button to profile + // mAddFriendButton->setEnabled(true); + mAddFriendButton->setVisible(true); + mRemoveFriendButton->setVisible(false); + // } // RLVa support @@ -1816,7 +1960,12 @@ void LLPanelProfileSecondLife::onCommitMenu(const LLSD& userdata) } else if (item_name == "toggle_block_agent") { - LLAvatarActions::toggleBlock(agent_id); + // Swap block/unblock buttons properly + // LLAvatarActions::toggleBlock(agent_id); + bool is_blocked = LLAvatarActions::toggleBlock(agent_id); + mBlockButton->setVisible(!is_blocked); + mUnblockButton->setVisible(is_blocked); + // } else if (item_name == "copy_user_id") { @@ -2081,6 +2230,39 @@ void LLPanelProfileSecondLife::onSaveDescriptionChanges() LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("sl_about_text", mDescriptionText))); } +// Restore UDP profiles +#ifdef OPENSIM + else if(LLGridManager::getInstance()->isInOpenSim()) + { + if (getIsLoaded() && getSelfProfile()) + { + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", gAgentID)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + LLPanel *panel = floater_profile->findChild(PANEL_PROFILE_VIEW, TRUE); + auto *panel_profile = dynamic_cast(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + } + else + { + auto avatar_data = panel_profile->getAvatarData(); + avatar_data.agent_id = gAgentID; + avatar_data.avatar_id = gAgentID; + avatar_data.image_id = mImageId; + avatar_data.about_text = mDescriptionEdit->getValue().asString(); + avatar_data.allow_publish = mShowInSearchCheckbox->getValue(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&avatar_data); + } + } + } +#endif +// else { LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; @@ -2230,6 +2412,13 @@ void LLPanelProfileSecondLife::onShowTexturePicker() } } +// Allow proper texture swatch handling +void LLPanelProfileSecondLife::onSecondLifePicChanged() +{ + onCommitProfileImage(mSecondLifePic->getImageAssetID()); +} +// + void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) { if (mImageId == id) @@ -2289,6 +2478,21 @@ void LLPanelProfileSecondLife::onCommitProfileImage(const LLUUID& id) } else { +// Make OpenSim profiles work again +#ifdef OPENSIM + if(LLGridManager::getInstance()->isInOpenSim()) + { + mImageId = id; + // save immediately only if description changes are not pending. + if(!mHasUnsavedDescriptionChanges) + { + onSaveDescriptionChanges(); + } + } + else +#endif +// + LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -2357,6 +2561,14 @@ void LLPanelProfileWeb::updateData() } } +// Restore UDP profiles +#ifdef OPENSIM +void LLPanelProfileWeb::apply(LLAvatarData* data) +{ + data->profile_url = mURLHome; +} +#endif +// void LLPanelProfileWeb::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { mAvatarNameCacheConnection.disconnect(); @@ -2446,7 +2658,7 @@ void LLPanelProfileWeb::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e ////////////////////////////////////////////////////////////////////////// LLPanelProfileFirstLife::LLPanelProfileFirstLife() - : LLPanelProfileTab() + : LLPanelProfilePropertiesProcessorTab() // alter ancestry to re-enable UDP , mHasUnsavedChanges(false) { } @@ -2458,7 +2670,10 @@ LLPanelProfileFirstLife::~LLPanelProfileFirstLife() BOOL LLPanelProfileFirstLife::postBuild() { mDescriptionEdit = getChild("fl_description_edit"); - mPicture = getChild("real_world_pic"); + // Allow proper texture swatch handling + // mPicture = getChild("real_world_pic"); + mPicture = getChild("real_world_pic"); + // mUploadPhoto = getChild("fl_upload_image"); mChangePhoto = getChild("fl_change_image"); @@ -2472,14 +2687,14 @@ BOOL LLPanelProfileFirstLife::postBuild() mSaveChanges->setCommitCallback([this](LLUICtrl*, void*) { onSaveDescriptionChanges(); }, nullptr); mDiscardChanges->setCommitCallback([this](LLUICtrl*, void*) { onDiscardDescriptionChanges(); }, nullptr); mDescriptionEdit->setKeystrokeCallback([this](LLTextEditor* caller) { onSetDescriptionDirty(); }); - mPicture->setMouseUpCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onShowPhoto(); }); // Make "first life" picture clickable + mPicture->setCommitCallback(boost::bind(&LLPanelProfileFirstLife::onFirstLifePicChanged, this)); // Allow proper texture swatch handling return TRUE; } void LLPanelProfileFirstLife::onOpen(const LLSD& key) { - LLPanelProfileTab::onOpen(key); + LLPanelProfilePropertiesProcessorTab::onOpen(key); // alter ancestry to re-enable UDP if (!getSelfProfile()) { @@ -2487,6 +2702,9 @@ void LLPanelProfileFirstLife::onOpen(const LLSD& key) mDescriptionEdit->setTabStop(FALSE); } + // Allow proper texture swatch handling + mPicture->setEnabled(getSelfProfile()); + resetData(); } @@ -2513,22 +2731,6 @@ void LLPanelProfileFirstLife::setProfileImageUploaded(const LLUUID &image_asset_ mPicture->setValue(image_asset_id); mImageId = image_asset_id; - // Make "first life" picture clickable - LLFloater *floater = mFloaterProfileTextureHandle.get(); - if (floater) - { - LLFloaterProfileTexture * texture_view = dynamic_cast(floater); - if (mImageId.notNull()) - { - texture_view->loadAsset(mImageId); - } - else - { - texture_view->resetAsset(); - } - } - // Make "first life" picture clickable - setProfileImageUploading(false); } @@ -2627,51 +2829,12 @@ void LLPanelProfileFirstLife::onRemovePhoto() } } -// Make "first life" picture clickable -void LLPanelProfileFirstLife::onShowPhoto() +// Allow proper texture swatch handling +void LLPanelProfileFirstLife::onFirstLifePicChanged() { - if (!getIsLoaded()) - { - return; - } - - LLFloater *floater = mFloaterProfileTextureHandle.get(); - if (!floater) - { - LLFloater* parent_floater = gFloaterView->getParentFloater(this); - if (parent_floater) - { - LLFloaterProfileTexture * texture_view = new LLFloaterProfileTexture(parent_floater); - mFloaterProfileTextureHandle = texture_view->getHandle(); - if (mImageId.notNull()) - { - texture_view->loadAsset(mImageId); - } - else - { - texture_view->resetAsset(); - } - texture_view->openFloater(); - texture_view->setVisibleAndFrontmost(TRUE); - parent_floater->addDependentFloater(mFloaterProfileTextureHandle); - } - } - else // already open - { - LLFloaterProfileTexture * texture_view = dynamic_cast(floater); - texture_view->setMinimized(FALSE); - texture_view->setVisibleAndFrontmost(TRUE); - if (mImageId.notNull()) - { - texture_view->loadAsset(mImageId); - } - else - { - texture_view->resetAsset(); - } - } + onCommitPhoto(mPicture->getImageAssetID()); } -// Make "first life" picture clickable +// void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) { @@ -2698,26 +2861,25 @@ void LLPanelProfileFirstLife::onCommitPhoto(const LLUUID& id) mPicture->setValue("Generic_Person_Large"); } - // Make "first life" picture clickable - LLFloater *floater = mFloaterProfileTextureHandle.get(); - if (floater) - { - LLFloaterProfileTexture * texture_view = dynamic_cast(floater); - if (mImageId == LLUUID::null) - { - texture_view->resetAsset(); - } - else - { - texture_view->loadAsset(mImageId); - } - } - // Make "first life" picture clickable - mRemovePhoto->setEnabled(mImageId.notNull()); } else { +// Make OpenSim profiles work again +#ifdef OPENSIM + if(LLGridManager::getInstance()->isInOpenSim()) + { + mImageId = id; + mImageId = id; + // save immediately only if description changes are not pending. + if(!mHasUnsavedChanges) + { + onSaveDescriptionChanges(); + } + } + else +#endif +// LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; } } @@ -2748,6 +2910,38 @@ void LLPanelProfileFirstLife::onSaveDescriptionChanges() LLCoros::instance().launch("putAgentUserInfoCoro", boost::bind(put_avatar_properties_coro, cap_url, getAvatarId(), LLSD().with("fl_about_text", mCurrentDescription))); } +// Restore UDP profiles +#ifdef OPENSIM + else if(LLGridManager::getInstance()->isInOpenSim()) + { + if (getIsLoaded() && getSelfProfile()) + { + LLFloater* floater_profile = LLFloaterReg::findInstance("profile", LLSD().with("id", gAgentID)); + if (!floater_profile) + { + // floater is dead, so panels are dead as well + return; + } + LLPanel *panel = floater_profile->findChild(PANEL_PROFILE_VIEW, TRUE); + auto *panel_profile = dynamic_cast(panel); + if (!panel_profile) + { + LL_WARNS() << PANEL_PROFILE_VIEW << " not found" << LL_ENDL; + } + else + { + auto avatar_data = panel_profile->getAvatarData(); + avatar_data.agent_id = gAgentID; + avatar_data.avatar_id = gAgentID; + avatar_data.fl_image_id = mImageId; + avatar_data.fl_about_text = mDescriptionEdit->getValue().asString(); + + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesUpdate(&avatar_data); + } + } + } +#endif +// else { LL_WARNS("AvatarProperties") << "Failed to update profile data, no cap found" << LL_ENDL; @@ -2763,6 +2957,20 @@ void LLPanelProfileFirstLife::onDiscardDescriptionChanges() setDescriptionText(mCurrentDescription); } +// Restore UDP profiles +void LLPanelProfileFirstLife::processProperties(void * data, EAvatarProcessorType type) +{ + if (APT_PROPERTIES == type) + { + const LLAvatarData* avatar_data = static_cast(data); + if (avatar_data && getAvatarId() == avatar_data->avatar_id) + { + processProperties(avatar_data); + } + } +} +// + void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) { setDescriptionText(avatar_data->fl_about_text); @@ -2781,15 +2989,38 @@ void LLPanelProfileFirstLife::processProperties(const LLAvatarData* avatar_data) setLoaded(); } +// Restore UDP profiles +#ifdef OPENSIM +void LLPanelProfileFirstLife::apply(LLAvatarData* data) +{ + data->fl_image_id = mImageId; + data->fl_about_text = mDescriptionEdit->getValue().asString(); +} +#endif +// + void LLPanelProfileFirstLife::resetData() { setDescriptionText(std::string()); mPicture->setValue("Generic_Person_Large"); mImageId = LLUUID::null; - mUploadPhoto->setVisible(getSelfProfile()); - mChangePhoto->setVisible(getSelfProfile()); - mRemovePhoto->setVisible(getSelfProfile()); +// remove the buttons and just have click image to update profile +// mUploadPhoto->setVisible(getSelfProfile()); +// mChangePhoto->setVisible(getSelfProfile()); +// mRemovePhoto->setVisible(getSelfProfile()); + auto show_image_buttons = getSelfProfile(); +#ifdef OPENSIM + std::string cap_url = gAgent.getRegionCapability(PROFILE_IMAGE_UPLOAD_CAP); + if( cap_url.empty() && LLGridManager::instance().isInOpenSim() ) + { + show_image_buttons = false; + } +#endif + mUploadPhoto->setVisible(show_image_buttons); + mChangePhoto->setVisible(show_image_buttons); + mRemovePhoto->setVisible(show_image_buttons); +// mSaveChanges->setVisible(getSelfProfile()); mDiscardChanges->setVisible(getSelfProfile()); } @@ -2811,7 +3042,7 @@ void LLPanelProfileFirstLife::setLoaded() ////////////////////////////////////////////////////////////////////////// LLPanelProfileNotes::LLPanelProfileNotes() -: LLPanelProfileTab() +: LLPanelProfilePropertiesProcessorTab() // alter ancestry to re-enable UDP , mHasUnsavedChanges(false) { @@ -2834,6 +3065,14 @@ void LLPanelProfileNotes::updateData() LLCoros::instance().launch("requestAgentUserInfoCoro", boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); } +// Restore UDO profiles +#ifdef OPENSIM + else + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarNotesRequest(avatar_id); + } +#endif +// } } @@ -2912,6 +3151,19 @@ void LLPanelProfileNotes::processProperties(LLAvatarNotes* avatar_notes) mNotesEditor->setEnabled(TRUE); setLoaded(); } +// Restore UDP profiles +void LLPanelProfileNotes::processProperties(void * data, EAvatarProcessorType type) +{ + if (APT_NOTES == type) + { + LLAvatarNotes* avatar_notes = static_cast(data); + if (avatar_notes && getAvatarId() == avatar_notes->target_id) + { + processProperties(avatar_notes); + } + } +} +// void LLPanelProfileNotes::resetData() { @@ -2923,7 +3175,7 @@ void LLPanelProfileNotes::setAvatarId(const LLUUID& avatar_id) { if (avatar_id.notNull()) { - LLPanelProfileTab::setAvatarId(avatar_id); + LLPanelProfilePropertiesProcessorTab::setAvatarId(avatar_id); // alter ancestry to re-enable UDP } } @@ -2997,18 +3249,30 @@ void LLPanelProfile::updateData() if (!getStarted() && avatar_id.notNull()) { setIsLoading(); - mPanelSecondlife->setIsLoading(); mPanelPicks->setIsLoading(); mPanelFirstlife->setIsLoading(); mPanelNotes->setIsLoading(); - +// Restore UDP profiles +#ifdef OPENSIM + mPanelSecondlife->updateData(); + mPanelPicks->updateData(); + mPanelFirstlife->updateData(); + mPanelNotes->updateData(); +#endif +// std::string cap_url = gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP); if (!cap_url.empty()) { LLCoros::instance().launch("requestAgentUserInfoCoro", boost::bind(request_avatar_properties_coro, cap_url, avatar_id)); } +// Restore UDP profiles + else + { + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(avatar_id); + } +// } } @@ -3063,8 +3327,26 @@ void LLPanelProfile::commitUnsavedChanges() mPanelClassifieds->commitUnsavedChanges(); mPanelFirstlife->commitUnsavedChanges(); mPanelNotes->commitUnsavedChanges(); + // restore UDP - this is effectvely the apply() method from the previous incarnation +#ifdef OPENSIM + if ( (gAgent.getRegionCapability(PROFILE_PROPERTIES_CAP).empty()) && getSelfProfile() ) + { + //KC - Avatar data is spread over 3 different panels + // collect data from the last 2 and give to the first to save + LLAvatarData data = mAvatarData; + data.avatar_id = gAgentID; + // these three collate data so need to be called in sequence. + mPanelFirstlife->apply(&data); + mPanelWeb->apply(&data); + mPanelSecondlife->apply(&data); + // These three triggered above + // mPanelInterests->apply(); + // mPanelPicks->apply(); + // mPanelNotes->apply(); + } +#endif + // } - void LLPanelProfile::showClassified(const LLUUID& classified_id, bool edit) { if (classified_id.notNull()) @@ -3080,3 +3362,17 @@ void LLPanelProfile::createClassified() mTabContainer->selectTabPanel(mPanelClassifieds); } +// FIRE-32184: Online/Offline status not working for non-friends +FSPanelPropertiesObserver::FSPanelPropertiesObserver() : LLAvatarPropertiesObserver(), + mPanelProfile(nullptr) +{ +} + +void FSPanelPropertiesObserver::processProperties(void* data, EAvatarProcessorType type) +{ + if (type == APT_PROPERTIES && mPanelProfile) + { + mPanelProfile->onAvatarProperties(static_cast(data)); + } +} +// diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h index 790ac18ae4..8b097ead19 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -63,12 +63,26 @@ class LLPanelProfileClassifieds; class LLPanelProfilePicks; class LLViewerFetchedTexture; +// FIRE-32184: Online/Offline status not working for non-friends +class LLPanelProfileSecondLife; + +class FSPanelPropertiesObserver : public LLAvatarPropertiesObserver +{ +public: + FSPanelPropertiesObserver(); + + virtual void processProperties(void* data, EAvatarProcessorType type); + + LLUUID mRequester; + LLPanelProfileSecondLife* mPanelProfile; +}; +// /** * Panel for displaying Avatar's second life related info. */ class LLPanelProfileSecondLife - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab , public LLFriendObserver , public LLVoiceClientStatusObserver { @@ -96,6 +110,8 @@ public: /** * Sends update data request to server. */ + void apply(LLAvatarData* data); + void processProperties(void* data, EAvatarProcessorType type) override; void updateData() override; void refreshName(); @@ -109,6 +125,9 @@ public: friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); + // FIRE-32184: Online/Offline status not working for non-friends + void onAvatarProperties(const LLAvatarData* d); + protected: /** * Process profile related data received from server. @@ -184,6 +203,7 @@ private: void onShowAgentPermissionsDialog(); void onShowAgentProfileTexture(); void onShowTexturePicker(); + void onSecondLifePicChanged(); // Allow proper texture swatch handling void onCommitProfileImage(const LLUUID& id); // Fix LL UI/UX design accident @@ -200,7 +220,10 @@ private: //LLComboBox* mShowInSearchCombo; LLCheckBoxCtrl* mShowInSearchCheckbox; // - LLIconCtrl* mSecondLifePic; + // Allow proper texture swatch handling + // LLIconCtrl* mSecondLifePic; + LLTextureCtrl* mSecondLifePic; + // LLPanel* mSecondLifePicLayout; LLTextEditor* mDescriptionEdit; //LLMenuButton* mAgentActionMenuButton; // Fix LL UI/UX design accident @@ -222,6 +245,7 @@ private: LLButton* mBlockButton; LLButton* mUnblockButton; LLButton* mAddFriendButton; + LLButton* mRemoveFriendButton; // Add "Remove Friend" button to profile LLButton* mPayButton; LLButton* mIMButton; LLMenuButton* mOverflowButton; @@ -244,6 +268,9 @@ private: boost::signals2::connection mRlvBehaviorCallbackConnection; void updateRlvRestrictions(ERlvBehaviour behavior); // + + // FIRE-32184: Online/Offline status not working for non-friends + FSPanelPropertiesObserver mPropertiesObserver; }; @@ -268,6 +295,7 @@ public: * Loads web profile. */ void updateData() override; + void apply(LLAvatarData* data); void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) override; @@ -293,7 +321,7 @@ private: * Panel for displaying Avatar's first life related info. */ class LLPanelProfileFirstLife - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfileFirstLife(); @@ -304,7 +332,8 @@ public: BOOL postBuild() override; void processProperties(const LLAvatarData* avatar_data); - + void processProperties(void * data, EAvatarProcessorType type) override; + void apply(LLAvatarData* data); void resetData() override; void setProfileImageUploading(bool loading); @@ -321,6 +350,7 @@ protected: void onUploadPhoto(); void onChangePhoto(); void onRemovePhoto(); + void onFirstLifePicChanged(); // Allow proper texture swatch handling void onCommitPhoto(const LLUUID& id); void setDescriptionText(const std::string &text); void onSetDescriptionDirty(); @@ -328,7 +358,10 @@ protected: void onDiscardDescriptionChanges(); LLTextEditor* mDescriptionEdit; - LLIconCtrl* mPicture; + // Allow proper texture swatch handling + // LLIconCtrl* mPicture; + LLTextureCtrl* mPicture; + // LLButton* mUploadPhoto; LLButton* mChangePhoto; LLButton* mRemovePhoto; @@ -340,20 +373,13 @@ protected: std::string mCurrentDescription; LLUUID mImageId; bool mHasUnsavedChanges; - -// Make "first life" picture clickable -private: - LLHandle mFloaterProfileTextureHandle; - void onShowPhoto(); -// Make "first life" picture clickable - }; /** * Panel for displaying Avatar's notes and modifying friend's rights. */ class LLPanelProfileNotes - : public LLPanelProfileTab + : public LLPanelProfilePropertiesProcessorTab { public: LLPanelProfileNotes(); @@ -366,7 +392,7 @@ public: BOOL postBuild() override; void processProperties(LLAvatarNotes* avatar_notes); - + void processProperties(void * data, EAvatarProcessorType type) override; void resetData() override; void updateData() override; @@ -418,6 +444,7 @@ public: void createClassified(); LLAvatarData getAvatarData() { return mAvatarData; }; + void setAvatarData(const LLAvatarData* avatar_data){ mAvatarData = *avatar_data; }; friend void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id); diff --git a/indra/newview/llpanelprofileclassifieds.cpp b/indra/newview/llpanelprofileclassifieds.cpp index aa58ba08d9..e05bf6993e 100644 --- a/indra/newview/llpanelprofileclassifieds.cpp +++ b/indra/newview/llpanelprofileclassifieds.cpp @@ -218,6 +218,8 @@ LLPanelProfileClassifieds::~LLPanelProfileClassifieds() void LLPanelProfileClassifieds::onOpen(const LLSD& key) { + LL_INFOS("profiles") << "Inside onOpen classifieds panel" << LL_ENDL; + LLPanelProfilePropertiesProcessorTab::onOpen(key); resetData(); diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 80a76ac95b..f5ef2ca7a0 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -140,6 +140,8 @@ LLPanelProfilePicks::~LLPanelProfilePicks() void LLPanelProfilePicks::onOpen(const LLSD& key) { + LL_INFOS("profiles") << "Inside onOpen picks panel" << LL_ENDL; + LLPanelProfilePropertiesProcessorTab::onOpen(key); resetData(); @@ -227,7 +229,6 @@ BOOL LLPanelProfilePicks::postBuild() LLTextBox* intro_txt = getChild("header_text"); intro_txt->setTextArg("[GRID]", LLTrans::getString("SECOND_LIFE")); // - return TRUE; } diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 676f79f3a5..1a4d8dd476 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -30,7 +30,7 @@ /* static */ // FIRE-23053 - analysed mesh physics is not correctly displayed for thin meshes -//void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ) +//void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut) void LLPhysicsShapeBuilderUtil::determinePhysicsShape(const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, bool hasDecomp, PhysicsShapeSpecification& specOut) // { @@ -194,6 +194,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape(const LLPhysicsVolumeParam if ( volume_params.shouldForceConvex() ) { + // Server distinguishes between convex of a prim vs isSculpt, but we don't care. specOut.mType = PhysicsShapeSpecification::USER_CONVEX; } // Make a simpler convex shape if we can. @@ -202,6 +203,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape(const LLPhysicsVolumeParam { specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; } + else if (volume_params.isMeshSculpt() && + // Check overall dimensions, not individual triangles. + (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + ) ) + { + // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) { // [BUG-134006] Viewer code is not aligned to server code when calculating physics shape for thin objects. diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h index 59375b866e..b44c51c04b 100644 --- a/indra/newview/llphysicsshapebuilderutil.h +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f; const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f; const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE; const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE; +const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f; class LLPhysicsVolumeParams : public LLVolumeParams { diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp index 5a7ab9e07c..800b5b34db 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -110,6 +110,7 @@ void LLPresetsManager::createCameraDefaultPresets() bool is_default_created = createDefaultCameraPreset(PRESETS_REAR_VIEW); is_default_created |= createDefaultCameraPreset(PRESETS_FRONT_VIEW); is_default_created |= createDefaultCameraPreset(PRESETS_SIDE_VIEW); + is_default_created |= createDefaultCameraPreset(PRESETS_TPP_VIEW); // Third Person Perspective camera if (is_default_created) { @@ -236,6 +237,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& subdirectory, p mPresetNames.push_back(PRESETS_FRONT_VIEW); mPresetNames.push_back(PRESETS_REAR_VIEW); mPresetNames.push_back(PRESETS_SIDE_VIEW); + mPresetNames.push_back(PRESETS_TPP_VIEW); // Third Person Perspective camera } } @@ -405,6 +407,12 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n { new_camera_preset = CAMERA_PRESET_FRONT_VIEW; } + // Third Person Perspective camera + else if (PRESETS_TPP_VIEW == name) + { + new_camera_preset = CAMERA_PRESET_TPP_VIEW; + } + // } else { @@ -606,12 +614,18 @@ bool LLPresetsManager::deletePreset(const std::string& subdirectory, std::string bool LLPresetsManager::isDefaultCameraPreset(std::string preset_name) { - return (preset_name == PRESETS_REAR_VIEW || preset_name == PRESETS_SIDE_VIEW || preset_name == PRESETS_FRONT_VIEW); + // Third Person Perspective camera + // return (preset_name == PRESETS_REAR_VIEW || preset_name == PRESETS_SIDE_VIEW || preset_name == PRESETS_FRONT_VIEW); + return (preset_name == PRESETS_REAR_VIEW || preset_name == PRESETS_SIDE_VIEW || preset_name == PRESETS_FRONT_VIEW || preset_name == PRESETS_TPP_VIEW); + // } bool LLPresetsManager::isTemplateCameraPreset(std::string preset_name) { - return (preset_name == PRESETS_REAR || preset_name == PRESETS_SIDE || preset_name == PRESETS_FRONT); + // Third Person Perspective camera + // return (preset_name == PRESETS_REAR || preset_name == PRESETS_SIDE || preset_name == PRESETS_FRONT); + return (preset_name == PRESETS_REAR || preset_name == PRESETS_SIDE || preset_name == PRESETS_FRONT || preset_name == PRESETS_TPP); + // } void LLPresetsManager::resetCameraPreset(std::string preset_name) diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h index 244e76e339..133ee46331 100644 --- a/indra/newview/llpresetsmanager.h +++ b/indra/newview/llpresetsmanager.h @@ -45,6 +45,11 @@ static const std::string PRESETS_REAR_VIEW = PRESETS_REAR + PRESETS_VIEW_SUFFIX; static const std::string PRESETS_FRONT_VIEW = PRESETS_FRONT + PRESETS_VIEW_SUFFIX; static const std::string PRESETS_SIDE_VIEW = PRESETS_SIDE + PRESETS_VIEW_SUFFIX; +// Third Person Perspective camera +static const std::string PRESETS_TPP = "TPP"; +static const std::string PRESETS_TPP_VIEW = PRESETS_TPP + PRESETS_VIEW_SUFFIX; +// + enum EDefaultOptions { DEFAULT_SHOW, diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 9b81c75fff..f2c3df36dc 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1590,6 +1590,62 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) } } +// return false if drawable is rigged and: +// - a linked rigged drawable has a different spatial group +// - a linked rigged drawable face has the wrong draw order index +bool check_rigged_group(LLDrawable* drawable) +{ + if (drawable->isState(LLDrawable::RIGGED)) + { + LLSpatialGroup* group = drawable->getSpatialGroup(); + LLDrawable* root = drawable->getRoot(); + + if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group) + { + llassert(false); + return false; + } + + S32 last_draw_index = -1; + if (root->isState(LLDrawable::RIGGED)) + { + for (auto& face : root->getFaces()) + { + if ((S32) face->getDrawOrderIndex() <= last_draw_index) + { + llassert(false); + return false; + } + last_draw_index = face->getDrawOrderIndex(); + } + } + + for (auto& child : root->getVObj()->getChildren()) + { + if (child->mDrawable->isState(LLDrawable::RIGGED)) + { + for (auto& face : child->mDrawable->getFaces()) + { + if ((S32) face->getDrawOrderIndex() <= last_draw_index) + { + llassert(false); + return false; + } + last_draw_index = face->getDrawOrderIndex(); + } + } + + if (child->mDrawable->getSpatialGroup() != group) + { + llassert(false); + return false; + } + } + } + + return true; +} + void renderOctree(LLSpatialGroup* group) { //render solid object bounding box, color @@ -1634,6 +1690,9 @@ void renderOctree(LLSpatialGroup* group) { continue; } + + llassert(check_rigged_group(drawable)); + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); @@ -3089,7 +3148,7 @@ public: } - void visit(const LLOctreeNode* branch) + void visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); @@ -3131,7 +3190,7 @@ public: } gGL.begin(LLRender::TRIANGLES); - for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); + for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { @@ -3229,14 +3288,14 @@ void renderRaycast(LLDrawable* drawablep) { F32 t = 1.f; - if (!face.mOctree) + if (!face.getOctree()) { ((LLVolumeFace*) &face)->createOctree(); } LLRenderOctreeRaycast render(start, dir, &t); - render.traverse(face.mOctree); + render.traverse(face.getOctree()); } gGL.popMatrix(); @@ -3854,9 +3913,9 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) // Class to watch for any octree changes while iterating. Will catch child insertion/removal as well as data insertion/removal. // Template so it can be used for than LLOctreeNode< LLDrawable > if needed -template< typename T > class ndOctreeListener: public LLOctreeListener< T > +template< typename T, typename T_PTR > class ndOctreeListener: public LLOctreeListener< T, T_PTR > { - typedef LLOctreeNode< T > tNode; + typedef LLOctreeNode< T, T_PTR > tNode; typedef std::vector< LLPointer< LLTreeListener< T > > > tListener; tNode *mNode; @@ -3928,13 +3987,13 @@ public: } }; -typedef ndOctreeListener< LLViewerOctreeEntry > ndDrawableOctreeListener; +typedef ndOctreeListener< LLViewerOctreeEntry, LLPointer > ndDrawableOctreeListener; typedef LLPointer< ndDrawableOctreeListener > ndDrawableOctreeListenerPtr; // LL_ALIGN_PREFIX(16) -class LLOctreeIntersect : public LLOctreeTraveler +class LLOctreeIntersect : public LLOctreeTraveler> { public: LL_ALIGN_16(LLVector4a mStart); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index d0c67fdb0a..f8426b9f00 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -275,6 +275,8 @@ public: return lhs->mAvatarp < rhs->mAvatarp; } + // BUG-232794: Restore old rigged mesh draw order + //return lhs->mRenderOrder < rhs->mRenderOrder; return lhs->mRenderOrder > rhs->mRenderOrder; } }; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 36e28f12cb..ff0c4f3681 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1024,7 +1024,7 @@ bool idle_startup() #else void* window_handle = NULL; #endif - bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle()); + bool init = gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle()); if(init) { // Output device selection diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index a4fa362d7d..26a70697c6 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1043,7 +1043,8 @@ void LLTextureCache::setReadOnly(BOOL read_only) mReadOnly = read_only ; } -//called in the main thread. +// Called in the main thread. +// Returns the unused amount of max_size if any S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch) { llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index f73410499d..f79d9b1488 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1389,7 +1389,7 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) // Mask texture if desired mIsMasked(FALSE) { - + mCaptionHeight = p.show_caption ? BTN_HEIGHT_SMALL : 0; // leave some room underneath the image for the caption // Default of defaults is white image for diff tex // LLUUID whiteImage( gSavedSettings.getString( "UIImgWhiteUUID" ) ); @@ -1408,7 +1408,9 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) addChild( mCaption ); S32 image_top = getRect().getHeight(); - S32 image_bottom = BTN_HEIGHT_SMALL; + // leave some room underneath the image for the caption + // S32 image_bottom = BTN_HEIGHT_SMALL; + S32 image_bottom = mCaptionHeight; S32 image_middle = (image_top + image_bottom) / 2; S32 line_height = LLFontGL::getFontSansSerifSmall()->getLineHeight(); @@ -1427,7 +1429,9 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) addChild( mTentativeLabel ); LLRect border_rect = getLocalRect(); - border_rect.mBottom += BTN_HEIGHT_SMALL; + // leave some room underneath the image for the caption + // border_rect.mBottom += BTN_HEIGHT_SMALL; + border_rect.mBottom += mCaptionHeight; LLViewBorder::Params vbparams(p.border); vbparams.name("border"); vbparams.rect(border_rect); @@ -1893,7 +1897,9 @@ void LLTextureCtrl::draw() } // Border - LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); + // leave some room underneath the image for the caption + // LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL ); + LLRect border( 0, getRect().getHeight(), getRect().getWidth(), mCaptionHeight ); gl_rect_2d( border, mBorderColor.get(), FALSE ); // Interior diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index e3a9b5c1e0..c4334f4ce9 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -98,6 +98,7 @@ public: caption_text; Optional border; + Optional show_caption; // leave some room underneath the image for the caption Params() : image_id("image"), @@ -110,6 +111,7 @@ public: border_color("border_color"), fallback_image("fallback_image"), multiselect_text("multiselect_text"), + show_caption("show_caption", true), // leave some room underneath the image for the caption caption_text("caption_text"), border("border") {} @@ -241,6 +243,7 @@ private: LLHandle mFloaterHandle; LLTextBox* mTentativeLabel; LLTextBox* mCaption; + S32 mCaptionHeight; // leave some room underneath the image for the caption std::string mLabel; BOOL mAllowNoTexture; // If true, the user can select "none" as an option BOOL mAllowLocalTexture; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 61f03dd631..72a217c1dd 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -60,6 +60,7 @@ #include "llvoavatarself.h" #include "llworld.h" #include "llpanelface.h" +#include "lluiusage.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) #include "rlvactions.h" #include "rlvhandler.h" @@ -1323,10 +1324,12 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, LLMessageSystem* msg = gMessageSystem; if (mSource == SOURCE_NOTECARD) { + LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard"); msg->newMessageFast(_PREHASH_RezObjectFromNotecard); } else { + LLUIUsage::instance().logCommand("Object.RezObject"); msg->newMessageFast(_PREHASH_RezObject); } msg->nextBlockFast(_PREHASH_AgentData); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 14ace2ac63..d85f2caa44 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -74,6 +74,7 @@ #include "llui.h" #include "llweb.h" #include "pipeline.h" // setHighlightObject +#include "lluiusage.h" // [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) #include "rlvactions.h" #include "rlvhandler.h" @@ -647,6 +648,8 @@ bool LLToolPie::walkToClickedLocation() return false; } + LLUIUsage::instance().logCommand("Agent.WalkToClickedLocation"); + LLPickInfo saved_pick = mPick; if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) { diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index c16e630f42..5943d7de1f 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -66,6 +66,7 @@ #include "llprimitive.h" #include "llwindow.h" // incBusyCount() #include "material_codes.h" +#include "lluiusage.h" // [RLVa:KB] - Checked: 2010-03-23 (RLVa-1.2.0a) #include "rlvhandler.h" @@ -301,6 +302,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); } + LLUIUsage::instance().logCommand("Build.ObjectAdd"); gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 8dec9193c0..bbae79bd24 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -50,6 +50,10 @@ #include "llpreviewnotecard.h" #include "llpreviewgesture.h" #include "llcoproceduremanager.h" +#include "llthread.h" +#include "llkeyframemotion.h" +#include "lldatapacker.h" +#include "llvoavatarself.h" #include "llviewernetwork.h" #include "llviewercontrol.h" @@ -473,9 +477,62 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() errorLabel = "DoNotSupportBulkAnimationUpload"; error = true; } - else if (assetType == LLAssetType::AT_ANIMATION) + else if (exten == "anim") { - filename = getFileName(); + // Default unless everything succeeds + errorLabel = "ProblemWithFile"; + error = true; + + // read from getFileName() + LLAPRFile infile; + infile.open(getFileName(),LL_APR_RB); + if (!infile.getFileHandle()) + { + LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL; + errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str()); + } + else + { + S32 size = LLAPRFile::size(getFileName()); + U8* buffer = new U8[size]; + S32 size_read = infile.read(buffer,size); + if (size_read != size) + { + errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read); + } + else + { + LLDataPackerBinaryBuffer dp(buffer, size); + LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId()); + motionp->setCharacter(gAgentAvatarp); + if (motionp->deserialize(dp, getAssetId(), false)) + { + // write to temp file + bool succ = motionp->dumpToFile(filename); + if (succ) + { + assetType = LLAssetType::AT_ANIMATION; + errorLabel = ""; + error = false; + } + else + { + errorMessage = "Failed saving temporary animation file"; + } + } + else + { + errorMessage = "Failed reading animation file"; + } + } + } + } + else + { + // Unknown extension + errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); + errorLabel = "ErrorMessage"; + error = TRUE;; } if (error) @@ -919,6 +976,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res { args["FILE"] = uploadInfo->getDisplayName(); args["REASON"] = reason; + args["ERROR"] = reason; } LLNotificationsUtil::add(label, args); diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h index 782285ce36..febae36ae8 100644 --- a/indra/newview/llvieweraudio.h +++ b/indra/newview/llvieweraudio.h @@ -33,8 +33,6 @@ // comment out to turn off wind #define kAUDIO_ENABLE_WIND //#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water -#define kAUDIO_NUM_BUFFERS 30 -#define kAUDIO_NUM_SOURCES 30 void init_audio(); void audio_update_volume(bool force_update = true); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4a27a83eb9..91f212850f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -32,6 +32,12 @@ // Library includes #include "llwindow.h" // getGamma() +// Handle IME text input getting enabled or disabled +#if LL_SDL2 +#include "llwindowsdl2.h" +#endif +// + // For Listeners #include "llaudioengine.h" #include "llagent.h" @@ -98,7 +104,6 @@ #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llhudtext.h" -#include "llnetmap.h" #include "llnotificationsutil.h" #include "llpanelplaces.h" #include "llstatusbar.h" @@ -794,13 +799,6 @@ static void handleAutohideChatbarChanged(const LLSD& new_value) } // -// Synchronize tooltips throughout instances -static void handleNetMapDoubleClickActionChanged() -{ - LLNetMap::updateToolTipMsg(); -} -// Synchronize tooltips throughout instances - // Clear places / teleport history search filter static void handleUseStandaloneTeleportHistoryFloaterChanged() { @@ -1137,275 +1135,321 @@ void handleFPSTuningStrategyChanged(const LLSD& newValue) const auto newval = gSavedSettings.getU32("FSTuningFPSStrategy"); FSPerfStats::tunables.userFPSTuningStrategy = newval; } - // +// FIRE-6809: Quickly moving the bandwidth slider has no effect +void handleBandwidthChanged(const LLSD& newValue) +{ + sBandwidthUpdater.update(newValue); +} +// + +// Handle IME text input getting enabled or disabled +#if LL_SDL2 +static bool handleSDL2IMEEnabledChanged(const LLSD& newvalue) +{ + ((LLWindowSDL*)gViewerWindow->getWindow())->enableIME(newvalue.asBoolean()); + + return true; +} +#endif +// + //////////////////////////////////////////////////////////////////////////// +LLPointer setting_get_control(LLControlGroup& group, const std::string& setting) +{ + LLPointer cntrl_ptr = group.getControl(setting); + if (cntrl_ptr.isNull()) + { + LL_ERRS() << "Unable to set up setting listener for " << setting + << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } + return cntrl_ptr; +} + +void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function callback) +{ + setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) + { + callback(new_val); + }); +} + +void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function callback) +{ + setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) + { + callback(); + }); +} + void settings_setup_listeners() { - gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2)); - gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2)); - gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2)); - gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2)); - gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2)); - gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleShadowsResized, _2)); - gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2)); - gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2)); - gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2)); - gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2)); - gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2)); - gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2)); - gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2)); - gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2)); - gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2)); - gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2)); - gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2)); - gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2)); - gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2)); - gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2)); - gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); + setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); + setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged); + setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); + setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged); + setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged); + setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged); + setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged); // [SL:KB] - Patch: Settings-RenderResolutionMultiplier | Checked: Catznip-5.4 - gSavedSettings.getControl("RenderResolutionMultiplier")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "RenderResolutionMultiplier", handleRenderResolutionDivisorChanged); // [/SL:KB] - gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2)); - gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2)); - gSavedSettings.getControl("RenderHiDPI")->getSignal()->connect(boost::bind(&handleRenderHiDPIChanged, _2)); - gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2)); - gSavedSettings.getControl("ChatConsoleFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); - gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2)); - gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2)); - gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2)); - gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2)); - gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); - gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2)); - gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2)); - gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2)); - gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2)); - gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2)); - gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus)); - gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus)); - gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2)); + setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged); + setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); + setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged); + setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); + setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); + setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged); + setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged); + setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged); + setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged); + setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged); + setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged); + setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate); + setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus); + setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus); + setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause); // Is done inside XUI now, using visibility_control - // gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2)); + // setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel); // // We don't have the mini location bar - // gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2)); + // setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel); // - gSavedSettings.getControl("ShowMenuBarLocation")->getSignal()->connect(boost::bind(&toggle_show_menubar_location_panel, _2)); - gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2)); - gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); - gSavedSettings.getControl("ShowStartLocation")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); // Show start location setting has no effect on login - gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2)); - gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); - gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); - gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); - gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2)); - gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2)); - gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "ShowMenuBarLocation", toggle_show_menubar_location_panel); + setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost); + setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid); + // Show start location setting has no effect on login + setting_setup_signal_listener(gSavedSettings, "ShowStartLocation", handleForceShowGrid); + setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged); + setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged); + setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged); + setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged); + setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged); + + setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged); // [RLVa:KB] - Checked: 2015-12-27 (RLVa-1.5.0) - gSavedSettings.getControl(RlvSettingNames::Main)->getSignal()->connect(boost::bind(&RlvSettings::onChangedSettingMain, _2)); + setting_setup_signal_listener(gSavedSettings, RlvSettingNames::Main, RlvSettings::onChangedSettingMain); // [/RLVa:KB] - // Is done inside XUI now, using visibility_control - // gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2)); - // // NaCl - Antispam Registry - gSavedSettings.getControl("_NACL_AntiSpamGlobalQueue")->getSignal()->connect(boost::bind(&handleNaclAntiSpamGlobalQueueChanged, _2)); - gSavedSettings.getControl("_NACL_AntiSpamTime")->getSignal()->connect(boost::bind(&handleNaclAntiSpamTimeChanged, _2)); - gSavedSettings.getControl("_NACL_AntiSpamAmount")->getSignal()->connect(boost::bind(&handleNaclAntiSpamAmountChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "_NACL_AntiSpamGlobalQueue", handleNaclAntiSpamGlobalQueueChanged); + setting_setup_signal_listener(gSavedSettings, "_NACL_AntiSpamTime", handleNaclAntiSpamTimeChanged); + setting_setup_signal_listener(gSavedSettings, "_NACL_AntiSpamAmount", handleNaclAntiSpamAmountChanged); // NaCl End - gSavedSettings.getControl("AutohideChatBar")->getSignal()->connect(boost::bind(&handleAutohideChatbarChanged, _2)); - - // Synchronize tooltips throughout instances - gSavedSettings.getControl("FSNetMapDoubleClickAction")->getSignal()->connect(boost::bind(&handleNetMapDoubleClickActionChanged)); + setting_setup_signal_listener(gSavedSettings, "AutohideChatBar", handleAutohideChatbarChanged); // Clear places / teleport history search filter - gSavedSettings.getControl("FSUseStandaloneTeleportHistoryFloater")->getSignal()->connect(boost::bind(&handleUseStandaloneTeleportHistoryFloaterChanged)); - - // Pose stand ground lock - gSavedSettings.getControl("FSPoseStandLock")->getSignal()->connect(boost::bind(&handleSetPoseStandLock, _2)); + setting_setup_signal_listener(gSavedSettings, "FSUseStandaloneTeleportHistoryFloater", handleUseStandaloneTeleportHistoryFloaterChanged); - gSavedPerAccountSettings.getControl("UseLSLFlightAssist")->getCommitSignal()->connect(boost::bind(&handleFlightAssistOptionChanged, _2)); - gSavedPerAccountSettings.getControl("UseMoveLock")->getCommitSignal()->connect(boost::bind(&handleMovelockOptionChanged, _2)); - gSavedPerAccountSettings.getControl("RelockMoveLockAfterMovement")->getCommitSignal()->connect(boost::bind(&handleMovelockAfterMoveOptionChanged, _2)); - gSavedSettings.getControl("FSBuildToolDecimalPrecision")->getCommitSignal()->connect(boost::bind(&handleDecimalPrecisionChanged, _2)); + // Pose stand ground lock + setting_setup_signal_listener(gSavedSettings, "FSPoseStandLock", handleSetPoseStandLock); + + setting_setup_signal_listener(gSavedPerAccountSettings, "UseLSLFlightAssist", handleFlightAssistOptionChanged); + setting_setup_signal_listener(gSavedPerAccountSettings, "UseMoveLock", handleMovelockOptionChanged); + setting_setup_signal_listener(gSavedPerAccountSettings, "RelockMoveLockAfterMovement", handleMovelockAfterMoveOptionChanged); + setting_setup_signal_listener(gSavedSettings, "FSBuildToolDecimalPrecision", handleDecimalPrecisionChanged); // External integrations (OC, LM etc.) for Bridge - gSavedPerAccountSettings.getControl("BridgeIntegrationOC")->getCommitSignal()->connect(boost::bind(&handleExternalIntegrationsOptionChanged)); - gSavedPerAccountSettings.getControl("BridgeIntegrationLM")->getCommitSignal()->connect(boost::bind(&handleExternalIntegrationsOptionChanged)); + setting_setup_signal_listener(gSavedPerAccountSettings, "BridgeIntegrationOC", handleExternalIntegrationsOptionChanged); + setting_setup_signal_listener(gSavedPerAccountSettings, "BridgeIntegrationLM", handleExternalIntegrationsOptionChanged); - gSavedSettings.getControl("FSNameTagShowLegacyUsernames")->getCommitSignal()->connect(boost::bind(&handleUsernameFormatOptionChanged, _2)); - gSavedSettings.getControl("FSTrimLegacyNames")->getCommitSignal()->connect(boost::bind(&handleLegacyTrimOptionChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSNameTagShowLegacyUsernames", handleUsernameFormatOptionChanged); + setting_setup_signal_listener(gSavedSettings, "FSTrimLegacyNames", handleLegacyTrimOptionChanged); // [FS communication UI] - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterIM::processChatHistoryStyleUpdate, _2)); - gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&FSFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&FSFloaterIM::processChatHistoryStyleUpdate, _2)); - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&FSFloaterNearbyChat::processChatHistoryStyleUpdate, _2)); - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged)); + setting_setup_signal_listener(gSavedSettings, "PlainTextChatHistory", FSFloaterIM::processChatHistoryStyleUpdate); + setting_setup_signal_listener(gSavedSettings, "PlainTextChatHistory", FSFloaterNearbyChat::processChatHistoryStyleUpdate); + setting_setup_signal_listener(gSavedSettings, "ChatFontSize", FSFloaterIM::processChatHistoryStyleUpdate); + setting_setup_signal_listener(gSavedSettings, "ChatFontSize", FSFloaterNearbyChat::processChatHistoryStyleUpdate); + setting_setup_signal_listener(gSavedSettings, "ChatFontSize", LLViewerChat::signalChatFontChanged); // [FS communication UI] - gSavedPerAccountSettings.getControl("GlobalOnlineStatusToggle")->getSignal()->connect(boost::bind(&handleGlobalOnlineStatusChanged, _2)); + setting_setup_signal_listener(gSavedPerAccountSettings, "GlobalOnlineStatusToggle", handleGlobalOnlineStatusChanged); // FIRE-17393: Control HUD text fading by options - gSavedSettings.getControl("FSHudTextFadeDistance")->getSignal()->connect(boost::bind(&LLHUDText::onFadeSettingsChanged)); - gSavedSettings.getControl("FSHudTextFadeRange")->getSignal()->connect(boost::bind(&LLHUDText::onFadeSettingsChanged)); + setting_setup_signal_listener(gSavedSettings, "FSHudTextFadeDistance", LLHUDText::onFadeSettingsChanged); + setting_setup_signal_listener(gSavedSettings, "FSHudTextFadeRange", LLHUDText::onFadeSettingsChanged); // FIRE-6340, FIRE-6567, FIRE-6809 - Setting Bandwidth issues - gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&BandwidthUpdater::update, sBandwidthUpdater, _2)); - gSavedSettings.getControl("FSContactListShowSearch")->getSignal()->connect(boost::bind(&handleContactListShowSearchChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "ThrottleBandwidthKBPS", handleBandwidthChanged); + setting_setup_signal_listener(gSavedSettings, "FSContactListShowSearch", handleContactListShowSearchChanged); // Debug setting to disable log throttle - gSavedSettings.getControl("FSEnableLogThrottle")->getSignal()->connect(boost::bind(&handleLogThrottleChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSEnableLogThrottle", handleLogThrottleChanged); // FIRE-18250: Option to disable default eye movement - gSavedSettings.getControl("FSStaticEyesUUID")->getSignal()->connect(boost::bind(&handleStaticEyesChanged)); - gSavedPerAccountSettings.getControl("FSStaticEyes")->getSignal()->connect(boost::bind(&handleStaticEyesChanged)); + setting_setup_signal_listener(gSavedSettings, "FSStaticEyesUUID", handleStaticEyesChanged); + setting_setup_signal_listener(gSavedPerAccountSettings, "FSStaticEyes", handleStaticEyesChanged); // // FIRE-20288: Option to render friends only - gSavedPerAccountSettings.getControl("FSRenderFriendsOnly")->getSignal()->connect(boost::bind(&handleRenderFriendsOnlyChanged, _2)); + setting_setup_signal_listener(gSavedPerAccountSettings, "FSRenderFriendsOnly", handleRenderFriendsOnlyChanged); // Notification not showing if hiding the UI - gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&handleNavbarSettingsChanged)); - gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&handleNavbarSettingsChanged)); + setting_setup_signal_listener(gSavedSettings, "ShowNavbarFavoritesPanel", handleNavbarSettingsChanged); + setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", handleNavbarSettingsChanged); // // Add ability for the statistics window to not be able to receive focus - gSavedSettings.getControl("FSStatisticsNoFocus")->getSignal()->connect(boost::bind(&handleFSStatisticsNoFocusChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSStatisticsNoFocus", handleFSStatisticsNoFocusChanged); // // Output device selection - gSavedSettings.getControl("FSOutputDeviceUUID")->getSignal()->connect(boost::bind(&handleOutputDeviceChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSOutputDeviceUUID", handleOutputDeviceChanged); // Dynamic texture memory calculation - gSavedSettings.getControl("FSDynamicTextureMemory")->getSignal()->connect(boost::bind(&handleDynamicTextureMemoryChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSDynamicTextureMemory", handleDynamicTextureMemoryChanged); // Optional small camera floater - gSavedSettings.getControl("FSUseSmallCameraFloater")->getSignal()->connect(boost::bind(&handleSmallCameraFloaterChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSUseSmallCameraFloater", handleSmallCameraFloaterChanged); // FIRE-20390, FIRE-4269 - Option for 12/24 hour clock and seconds display - gSavedSettings.getControl("FSStatusBarTimeFormat")->getSignal()->connect(boost::bind(&handleStatusbarTimeformatChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSStatusBarTimeFormat", handleStatusbarTimeformatChanged); // Run Prio 0 default bento pose in the background to fix splayed hands, open mouths, etc. - gSavedSettings.getControl("FSPlayDefaultBentoAnimation")->getSignal()->connect(boost::bind(&handlePlayBentoIdleAnimationChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSPlayDefaultBentoAnimation", handlePlayBentoIdleAnimationChanged); // Better asset cache size control - gSavedSettings.getControl("FSDiskCacheSize")->getSignal()->connect(boost::bind(&handleDiskCacheSizeChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSDiskCacheSize", handleDiskCacheSizeChanged); // perf floater controls - gSavedSettings.getControl("FSTargetFPS")->getSignal()->connect(boost::bind(&handleTargetFPSChanged, _2)); - gSavedSettings.getControl("FSAutoTuneFPS")->getSignal()->connect(boost::bind(&handleAutoTuneFPSChanged, _2)); - gSavedSettings.getControl("FSAutoTuneLock")->getSignal()->connect(boost::bind(&handleAutoTuneLockChanged, _2)); - gSavedSettings.getControl("FSRenderAvatarMaxART")->getSignal()->connect(boost::bind(&handleRenderAvatarMaxARTChanged, _2)); - gSavedSettings.getControl("FSPerfStatsCaptureEnabled")->getSignal()->connect(boost::bind(&handlePerformanceStatsEnabledChanged, _2)); - gSavedSettings.getControl("FSUserTargetReflections")->getSignal()->connect(boost::bind(&handleUserTargetReflectionsChanged, _2)); - gSavedSettings.getControl("FSAutoTuneRenderFarClipTarget")->getSignal()->connect(boost::bind(&handleUserTargetDrawDistanceChanged, _2)); - gSavedSettings.getControl("FSAutoTuneImpostorFarAwayDistance")->getSignal()->connect(boost::bind(&handleUserImpostorDistanceChanged, _2)); - gSavedSettings.getControl("FSAutoTuneImpostorByDistEnabled")->getSignal()->connect(boost::bind(&handleUserImpostorByDistEnabledChanged, _2)); - gSavedSettings.getControl("FSTuningFPSStrategy")->getSignal()->connect(boost::bind(&handleFPSTuningStrategyChanged, _2)); + setting_setup_signal_listener(gSavedSettings, "FSTargetFPS", handleTargetFPSChanged); + setting_setup_signal_listener(gSavedSettings, "FSAutoTuneFPS", handleAutoTuneFPSChanged); + setting_setup_signal_listener(gSavedSettings, "FSAutoTuneLock", handleAutoTuneLockChanged); + setting_setup_signal_listener(gSavedSettings, "FSRenderAvatarMaxART", handleRenderAvatarMaxARTChanged); + setting_setup_signal_listener(gSavedSettings, "FSPerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged); + setting_setup_signal_listener(gSavedSettings, "FSUserTargetReflections", handleUserTargetReflectionsChanged); + setting_setup_signal_listener(gSavedSettings, "FSAutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged); + setting_setup_signal_listener(gSavedSettings, "FSAutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged); + setting_setup_signal_listener(gSavedSettings, "FSAutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged); + setting_setup_signal_listener(gSavedSettings, "FSTuningFPSStrategy", handleFPSTuningStrategyChanged); // + + // Handle IME text input getting enabled or disabled +#if LL_SDL2 + gSavedSettings.getControl("SDL2IMEEnabled")->getSignal()->connect(boost::bind(&handleSDL2IMEEnabledChanged, _2)); +#endif + // } #if TEST_CACHED_CONTROL diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 096da38de2..0dd0e201bb 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3950,7 +3950,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const // bool LLViewerMediaImpl::isObscured() const { - if (getUsedInUI() || isParcelMedia()) return false; + if (getUsedInUI() || isParcelMedia() || isAttachedToHUD()) return false; LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!agent_parcel) @@ -3966,6 +3966,20 @@ bool LLViewerMediaImpl::isObscured() const return false; } +bool LLViewerMediaImpl::isAttachedToHUD() const +{ + std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); + std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); + for ( ; iter != end; iter++) + { + if ((*iter)->isHUDAttachment()) + { + return true; + } + } + return false; +} + ////////////////////////////////////////////////////////////////////////////////////////// // bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index b95cfd4c68..f1f42afd81 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -411,6 +411,8 @@ public: void cancelMimeTypeProbe(); + bool isAttachedToHUD() const; + // Is this media attached to an avatar *not* self bool isAttachedToAnotherAvatar() const; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9d82741c52..c908da3d7e 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -58,6 +58,7 @@ #include "llcompilequeue.h" #include "llconsole.h" #include "lldebugview.h" +#include "lldiskcache.h" #include "llenvironment.h" #include "llfilepicker.h" #include "llfirstuse.h" @@ -2414,6 +2415,32 @@ class LLAdvancedDropPacket : public view_listener_t } }; +////////////////////// +// PURGE DISK CACHE // +////////////////////// + + +class LLAdvancedPurgeDiskCache : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + llassert_always(main_queue); + llassert_always(general_queue); + main_queue->postTo( + general_queue, + []() // Work done on general queue + { + LLDiskCache::getInstance()->purge(); + // Nothing needed to return + }, + [](){}); // Callback to main thread is empty as there is nothing left to do + + return true; + } +}; + //////////////////// // EVENT Recorder // @@ -2637,18 +2664,6 @@ class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t } }; -///////////////////////////////////// -// Enable Framebuffer Objects /// -///////////////////////////////////// -class LLAdvancedEnableRenderFBO: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject; - return new_value; - } -}; - ///////////////////////////////////// // Enable Advanced Lighting Model /// ///////////////////////////////////// @@ -2656,7 +2671,7 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && + bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; return new_value; } @@ -2669,7 +2684,7 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && + bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred"); return new_value; } @@ -6737,6 +6752,16 @@ class LLToolsSelectNextPartFace : public view_listener_t bool ifwd = (userdata.asString() == "includenext"); bool iprev = (userdata.asString() == "includeprevious"); + // Make shift+click on forward/back buttons work like includenext/previous + if (gKeyboard->currentMask(false) & MASK_SHIFT) + { + ifwd = fwd; + iprev = prev; + fwd = false; + prev = false; + } + // + LLViewerObject* to_select = NULL; bool restart_face_on_part = !cycle_faces; S32 new_te = 0; @@ -6754,6 +6779,30 @@ class LLToolsSelectNextPartFace : public view_listener_t if (fwd || ifwd) { + // FIRE-32282: fix face selection cycle starting at face 1 instead of face 0 + // is more than one face selected in the whole set? + if (LLSelectMgr::getInstance()->getSelection()->getTECount() > 1) + { + // count the number of selected faces on the current link + S32 count = 0; + S32 num_tes = to_select->getNumTEs(); + for (S32 te = 0; te < num_tes; te++) + { + if (nodep->isTESelected(te)) + { + ++count; + } + } + + // if all faces of the current link are selected, set a flag to make sure the + // next selected face will be face 0 + if (count == num_tes) + { + selected_te = -1; + } + } + // + if (selected_te < 0) { new_te = 0; @@ -6862,6 +6911,10 @@ class LLToolsSelectNextPartFace : public view_listener_t } } LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te); + + // Add this back in additionally to selectObjectOnly() to get the lastOperadedTE() + // function back working to properly shift+cycle through faces + LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, false); } else { @@ -10947,6 +11000,26 @@ class LLViewCheckHighlightTransparent : public view_listener_t return new_value; } }; +// FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled +class LLViewHighlightTransparentRigged : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LLDrawPoolAlpha::sShowDebugAlphaRigged = !LLDrawPoolAlpha::sShowDebugAlphaRigged; + gPipeline.resetVertexBuffers(); + return true; + } +}; + +class LLViewCheckHighlightTransparentRigged : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool new_value = LLDrawPoolAlpha::sShowDebugAlphaRigged; + return new_value; + } +}; +// class LLViewBeaconWidth : public view_listener_t { @@ -11969,6 +12042,7 @@ void initialize_menus() view_listener_t::addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter"); view_listener_t::addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips"); view_listener_t::addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent"); + view_listener_t::addMenu(new LLViewHighlightTransparentRigged(), "View.HighlightTransparentRigged"); // FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled view_listener_t::addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType"); view_listener_t::addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments"); view_listener_t::addMenu(new LLZoomer(1.2f), "View.ZoomOut"); @@ -11985,6 +12059,7 @@ void initialize_menus() view_listener_t::addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam"); view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips"); view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent"); + view_listener_t::addMenu(new LLViewCheckHighlightTransparentRigged(), "View.CheckHighlightTransparentRigged");// FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType"); view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway"); view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb"); @@ -12136,7 +12211,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); // Develop > Render view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); - view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO"); view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred"); view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions"); view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); @@ -12249,6 +12323,9 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog"); view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket"); + // Advanced > Cache + view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache"); + // Advanced > Recorder view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot"); view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 048bc10a1b..94b07bda62 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -33,6 +33,7 @@ #include "llavataractions.h" #include "llavatarnamecache.h" // IDEVO HACK #include "lleventtimer.h" +#include "llfloatercreatelandmark.h" #include "llfloaterreg.h" #include "llfolderview.h" #include "llfollowcamparams.h" @@ -133,6 +134,7 @@ #include "llexperiencecache.h" #include "llexperiencecache.h" +#include "lluiusage.h" // Firestorm includes #include @@ -321,6 +323,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) { case 0: { + LLUIUsage::instance().logCommand("Agent.AcceptFriendship"); // accept LLAvatarTracker::formFriendship(payload["from_id"]); @@ -369,6 +372,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) // fall-through case 2: // Send IM - decline and start IM session { + LLUIUsage::instance().logCommand("Agent.DeclineFriendship"); // decline // We no longer notify other viewers, but we DO still send // the rejection to the simulator to delete the pending userop. @@ -916,6 +920,11 @@ void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accep EInstantMessage type = accept_invite ? IM_GROUP_INVITATION_ACCEPT : IM_GROUP_INVITATION_DECLINE; + if (accept_invite) + { + LLUIUsage::instance().logCommand("Group.Join"); + } + send_improved_im(group_id, std::string("name"), std::string("message"), @@ -1727,6 +1736,17 @@ bool highlight_offered_object(const LLUUID& obj_id) } } + if (obj->getType() == LLAssetType::AT_LANDMARK) + { + LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance("add_landmark"); + if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id) + { + // LLFloaterCreateLandmark is supposed to handle this, + // keep landmark creation floater at the front + return false; + } + } + return true; } diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index e6974b0f84..7666062f99 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -45,11 +45,11 @@ class LLViewerOctreeGroup; class LLViewerOctreeEntry; class LLViewerOctreePartition; -typedef LLOctreeListener OctreeListener; -typedef LLTreeNode TreeNode; -typedef LLOctreeNode OctreeNode; -typedef LLOctreeRoot OctreeRoot; -typedef LLOctreeTraveler OctreeTraveler; +typedef LLOctreeListener> OctreeListener; +typedef LLTreeNode TreeNode; +typedef LLOctreeNode> OctreeNode; +typedef LLOctreeRoot> OctreeRoot; +typedef LLOctreeTraveler> OctreeTraveler; #if LL_OCTREE_PARANOIA_CHECK #define assert_octree_valid(x) x->validate() @@ -179,7 +179,7 @@ protected: //defines an octree group for an octree node, which contains multiple entries. //LL_ALIGN_PREFIX(16) class LLViewerOctreeGroup -: public LLOctreeListener +: public OctreeListener { LL_ALIGN_NEW friend class LLViewerOctreeCull; @@ -198,8 +198,8 @@ public: }; public: - typedef LLOctreeNode::element_iter element_iter; - typedef LLOctreeNode::element_list element_list; + typedef OctreeNode::element_iter element_iter; + typedef OctreeNode::element_list element_list; LLViewerOctreeGroup(OctreeNode* node); LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs) @@ -245,7 +245,6 @@ public: const LLVector4a* getObjectExtents() const {return mObjectExtents;} //octree wrappers to make code more readable - element_list& getData() { return mOctreeNode->getData(); } element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 6b6c512d0c..d322951c15 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1665,6 +1665,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID) { // new agent parcel + // *TODO: Does it really make sense to set the agent parcel to this + // parcel if the client doesn't know what kind of parcel data this is? parcel_mgr.mAgentParcelSequenceID = sequence_id; parcel = parcel_mgr.mAgentParcel; } @@ -1972,8 +1974,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // Check for video - LLViewerParcelMedia::getInstance()->update(parcel); + if (gNonInteractive) + { + return; + } + + // Check for video + LLViewerParcelMedia::getInstance()->update(parcel); // Then check for music if (gAudiop) diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 846f58f479..f0ce9dfd61 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -271,7 +271,7 @@ BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const { S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS); S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS); - return PARCEL_SOUND_LOCAL & mOwnership[row * mParcelGridsPerEdge + column]; + return parcelFlags(row, column, PARCEL_SOUND_LOCAL); } U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const @@ -285,12 +285,19 @@ U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const { S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS); S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS); - return parcelLineFlags(row, column); + return parcelFlags(row, column, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE); } U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const { - U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE; - if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge) + return parcelFlags(row, col, PARCEL_WEST_LINE | PARCEL_SOUTH_LINE); +} + +U8 LLViewerParcelOverlay::parcelFlags(S32 row, S32 col, U8 flags) const +{ + if (row >= mParcelGridsPerEdge + || col >= mParcelGridsPerEdge + || row < 0 + || col < 0) { LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL; return flags; @@ -932,8 +939,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines () // Always fudge a little vertically. pull_toward_camera.mV[VZ] += 0.01f; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); // Move to appropriate region coords LLVector3 origin = mRegion->getOriginAgent(); @@ -1038,11 +1045,70 @@ S32 LLViewerParcelOverlay::renderPropertyLines () } - gGL.popMatrix(); + gGL.popMatrix(); return drawn; } +// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top +void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom) +{ + gGL.begin(LLRender::LINES); + + if (has_left) + { + gGL.vertex2f(left, bottom); + gGL.vertex2f(left, top); + } + if (has_bottom) + { + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + } + + gGL.end(); +} + +void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ + if (!mOwnership) + { + return; + } + if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines")) + { + return; + } + + LLVector3 origin_agent = mRegion->getOriginAgent(); + LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); + F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter; + F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter; + F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter; + const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + glLineWidth(1.0f); + gGL.color4fv(parcel_outline_color); + for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++) + { + const F32 bottom = region_bottom + (i * map_parcel_width); + const F32 top = bottom + map_parcel_width; + for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++) + { + const F32 left = region_left + (j * map_parcel_width); + const F32 right = left + map_parcel_width; + const bool is_region_boundary = i == GRIDS_PER_EDGE || j == GRIDS_PER_EDGE; + const U8 overlay = is_region_boundary ? 0 : mOwnership[(i * GRIDS_PER_EDGE) + j]; + // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a + // 2D map + const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE)); + const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE)); + grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom); + } + } +} + // [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3) boost::signals2::connection LLViewerParcelOverlay::setUpdateCallback(const update_signal_t::slot_type& cb) { diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 2132ea6318..0e30b05dab 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -72,6 +72,7 @@ public: // Returns the number of vertices drawn S32 renderPropertyLines(); + void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); U8 ownership( const LLVector3& pos) const; U8 parcelLineFlags( const LLVector3& pos) const; @@ -85,7 +86,7 @@ public: void idleUpdate(bool update_now = false); void updateGL(); - + // [SL:KB] - Patch: World-MinimapOverlay | Checked: 2012-06-20 (Catznip-3.3) typedef boost::signals2::signal update_signal_t; static boost::signals2::connection setUpdateCallback(const update_signal_t::slot_type & cb); @@ -95,7 +96,9 @@ private: // This is in parcel rows and columns, not grid rows and columns // Stored in bottom three bits. U8 ownership(S32 row, S32 col) const - { return 0x7 & mOwnership[row * mParcelGridsPerEdge + col]; } + { return parcelFlags(row, col, (U8)0x7); } + + U8 parcelFlags(S32 row, S32 col, U8 flags) const; void addPropertyLine(std::vector& vertex_array, std::vector& color_array, diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp old mode 100644 new mode 100755 index 891654c4ff..7eaf23cb03 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -331,6 +331,24 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) return; } + if (!LLWorld::instanceExists()) + { + LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL; + return; + } + + regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle); + if (!regionp) //region was removed + { + LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL; + return; // this error condition is not recoverable. + } + + impl = regionp->getRegionImplNC(); + + // Fix seed cap retry count + //++(impl->mSeedCapAttempts); + if (!result.isMap() || result.has("error")) { LL_WARNS("AppInit", "Capabilities") << "Malformed response" << LL_ENDL; @@ -350,24 +368,6 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle) // remove the http_result from the llsd result.erase("http_result"); - if (!LLWorld::instanceExists()) - { - LL_WARNS("AppInit", "Capabilities") << "Received capabilities, but world no longer exists!" << LL_ENDL; - return; - } - - regionp = LLWorld::getInstance()->getRegionFromHandle(regionHandle); - if (!regionp) //region was removed - { - LL_WARNS("AppInit", "Capabilities") << "Received capabilities for region that no longer exists!" << LL_ENDL; - return; // this error condition is not recoverable. - } - - impl = regionp->getRegionImplNC(); - - // Fix seed cap retry count - //++(impl->mSeedCapAttempts); - if (id != impl->mHttpResponderID) // region is no longer referring to this request { LL_WARNS("AppInit", "Capabilities") << "Received results for a stale capabilities request!" << LL_ENDL; @@ -1153,6 +1153,15 @@ S32 LLViewerRegion::renderPropertyLines() } } +void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ + if (mParcelOverlay) + { + mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color); + } +} + + // This gets called when the height field changes. void LLViewerRegion::dirtyHeights() { diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b0445c32e4..312b792b4f 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -166,6 +166,8 @@ public: // Draw lines in the dirt showing ownership. Return number of // vertices drawn. S32 renderPropertyLines(); + void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); + // Call this whenever you change the height data in the region. // (Automatically called by LLSurfacePatch's update routine) diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 271cc1ff84..5c24a07201 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -563,15 +563,14 @@ void LLViewerShaderMgr::setShaders() mShaderLevel[SHADER_DEFERRED] = deferred_class; mShaderLevel[SHADER_TRANSFORM] = transform_class; - BOOL loaded = loadBasicShaders(); - if (loaded) + std::string shader_name = loadBasicShaders(); + if (shader_name.empty()) { LL_INFOS() << "Loaded basic shaders." << LL_ENDL; } else { - LL_ERRS() << "Unable to load basic shaders, verify graphics driver installed and current." << LL_ENDL; - llassert(loaded); + LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL; reentrance = false; // For hygiene only, re-try probably helps nothing return; } @@ -579,7 +578,7 @@ void LLViewerShaderMgr::setShaders() gPipeline.mShadersLoaded = true; // Load all shaders to set max levels - loaded = loadShadersEnvironment(); + BOOL loaded = loadShadersEnvironment(); if (loaded) { @@ -867,7 +866,7 @@ void LLViewerShaderMgr::unloadShaders() gPipeline.mShadersLoaded = false; } -BOOL LLViewerShaderMgr::loadBasicShaders() +std::string LLViewerShaderMgr::loadBasicShaders() { // Load basic dependency shaders first // All of these have to load for any shaders to function @@ -953,8 +952,8 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // Note usage of GL_VERTEX_SHADER_ARB if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0) { - LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; - return FALSE; + LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; } } @@ -1013,12 +1012,12 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // Note usage of GL_FRAGMENT_SHADER_ARB if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0) { - LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; - return FALSE; + LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; } } - return TRUE; + return std::string(); } BOOL LLViewerShaderMgr::loadShadersEnvironment() @@ -1505,6 +1504,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + if (alpha_mode != 0) + { + gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true; + gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1"); + } + if (use_sun_shadow) { gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); @@ -1563,6 +1568,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + if (alpha_mode != 0) + { + gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true; + gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1"); + } + if (use_sun_shadow) { gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 11c2fc8574..2f22b3dbf8 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -49,7 +49,11 @@ public: void setShaders(); void unloadShaders(); S32 getShaderLevel(S32 type); - BOOL loadBasicShaders(); + + // loadBasicShaders in case of a failure returns + // name of a file error happened at, otherwise + // returns an empty string + std::string loadBasicShaders(); BOOL loadShadersEffects(); BOOL loadShadersDeferred(); BOOL loadShadersObject(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d060715e26..520064b933 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -835,6 +835,13 @@ public: ypos += y_inc; } + // FIRE-32311 - Only show particle text when showing render debug info (relocate pre-existing change by Liny) + if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES)) + { + addText(xpos, ypos, particle_hiding); + ypos += y_inc; + } + // LLVertexBuffer::sBindCount = LLImageGL::sBindCount = LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; @@ -932,14 +939,6 @@ public: } // - // pull the text saying if particles are hidden out from beacons - if (LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES)) - { - addText(xpos, ypos, particle_hiding); - ypos += y_inc; - } - // - // only display these messages if we are actually rendering beacons at this moment // Always show the beacon text regardless if the floater is visible // ...and if we want to see it @@ -2812,10 +2811,11 @@ void LLViewerWindow::reshape(S32 width, S32 height) //glViewport(0, 0, width, height ); - if (height > 0) + LLViewerCamera * camera = LLViewerCamera::getInstance(); // simpleton, might not exist + if (height > 0 && camera) { - LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); - LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() ); + camera->setViewHeightInPixels( mWorldViewRectRaw.getHeight() ); + camera->setAspect( getWorldViewAspectRatio() ); } calcDisplayScale(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3924c47227..3e795d846e 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6938,8 +6938,22 @@ LLJoint *LLVOAvatar::getJoint( const JointKey &name ) //if( iter == mJointMap.end() || iter->second == NULL ) //{ //search for joint and cache found joint in lookup table - // jointp = mRoot->findJoint( name ); - // mJointMap[ name ] = jointp; + // if (mJointAliasMap.empty()) + // { + // getJointAliases(); + // } + // joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); + // std::string canonical_name; + // if (alias_iter != mJointAliasMap.end()) + // { + // canonical_name = alias_iter->second; + // } + // else + // { + // canonical_name = name; + // } + // jointp = mRoot->findJoint(canonical_name); + // mJointMap[name] = jointp; //} //else //{ //return cached pointer @@ -6952,8 +6966,22 @@ LLJoint *LLVOAvatar::getJoint( const JointKey &name ) if (iter == mJointMap.end() || iter->second == NULL) { //search for joint and cache found joint in lookup table - jointp = mRoot->findJoint( name.mName ); - mJointMap[ name.mKey ] = jointp; + if (mJointAliasMap.empty()) + { + getJointAliases(); + } + joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name.mName); + std::string canonical_name; + if (alias_iter != mJointAliasMap.end()) + { + canonical_name = alias_iter->second; + } + else + { + canonical_name = name.mName; + } + jointp = mRoot->findJoint(canonical_name); + mJointMap[name.mKey] = jointp; } else { //return cached pointer diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 3503eb28e5..5b57c7c4bc 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -67,6 +67,7 @@ #include "llsdserialize.h" #include "llcallstack.h" #include "llcorehttputil.h" +#include "lluiusage.h" // Firestorm includes #include "fslslbridge.h" @@ -3242,6 +3243,7 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch) { if (isAgentAvatarValid()) { + LLUIUsage::instance().logCommand("Avatar.CustomizeStart"); if (!gAgentAvatarp->mEndCustomizeCallback.get()) { gAgentAvatarp->mEndCustomizeCallback = new LLUpdateAppearanceOnDestroy; diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 3dbc1e5396..2a2bbd09a9 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -366,15 +366,6 @@ void LLVOCacheEntry::updateDebugSettings() } timer.reset(); - //the number of frames invisible objects stay in memory - static LLCachedControl inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); - sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum - - //min radius: all objects within this radius remain loaded in memory - static LLCachedControl min_radius(gSavedSettings,"SceneLoadMinRadius"); - sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance - sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m - //objects within the view frustum whose visible area is greater than this threshold will be loaded static LLCachedControl front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold"); sFrontPixelThreshold = front_pixel_threshold; @@ -384,29 +375,38 @@ void LLVOCacheEntry::updateDebugSettings() sRearPixelThreshold = rear_pixel_threshold; sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold. - // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold - static LLCachedControl rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); - sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m - sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius". - sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance. - - //make the above parameters adaptive to memory usage + //make parameters adaptive to memory usage //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB static LLCachedControl low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound"); static LLCachedControl high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound"); LLMemory::updateMemoryInfo() ; U32 allocated_mem = LLMemory::getAllocatedMemKB().value(); - allocated_mem /= 1024; //convert to MB. - if(allocated_mem < low_mem_bound_MB) - { - return; - } - F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB)); + static const F32 KB_to_MB = 1.f / 1024.f; + U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB); + const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB; + const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1] - sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f] - sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64] - sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f); + //min radius: all objects within this radius remain loaded in memory + static LLCachedControl min_radius(gSavedSettings,"SceneLoadMinRadius"); + static const F32 MIN_RADIUS = 1.0f; + const F32 draw_radius = gAgentCamera.mDrawDistance; + const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance] + sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor); + + // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold + static LLCachedControl rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); + const F32 min_radius_plus_one = sNearRadius + 1.f; + const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance; + const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance] + sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor); + + //the number of frames invisible objects stay in memory + static LLCachedControl inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); + static const U32 MIN_FRAMES = 10; + static const U32 MAX_FRAMES = 64; + const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64 + sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor); } //static diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 2b357eaada..42ff94f839 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -37,6 +37,7 @@ #include "llui.h" #include "llkeyboard.h" #include "llagent.h" +#include "lluiusage.h" const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f; @@ -619,6 +620,10 @@ void LLVoiceClient::setMuteMic(bool muted) void LLVoiceClient::setUserPTTState(bool ptt) { + if (ptt) + { + LLUIUsage::instance().logCommand("Agent.EnableMicrophone"); + } mUserPTTState = ptt; updateMicMuteLogic(); mMicroChangedSignal(); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index acf638ea8a..939481dfdf 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1726,13 +1726,33 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() } else { - LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL; - + LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel(); + if (channel != NULL) + { + if (channel->getSessionName().empty() && channel->getSessionID().isNull()) + { + if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) + { + LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL; + } + } + else + { + LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL; + } + } } } else { - LL_WARNS("Voice") << "No voice credentials" << LL_ENDL; + if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) + { + LL_WARNS("Voice") << "No voice credentials" << LL_ENDL; + } + else + { + LL_DEBUGS("Voice") << "No voice credentials" << LL_ENDL; + } } // set the spatial channel. If no voice credentials or uri are diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ac95d29e21..2d714e7c8b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1899,7 +1899,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global, BOOL should_update_octree_bounds) // updates needed, set REBUILD_RIGGED accordingly. // Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about. - updateRiggedVolume(); + updateRiggedVolume(false); } LLVolume* volume = mRiggedVolume; @@ -2198,7 +2198,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) { - updateRiggedVolume(); + updateRiggedVolume(false); genBBoxes(FALSE); mDrawable->clearState(LLDrawable::REBUILD_RIGGED); } @@ -4860,7 +4860,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) { - updateRiggedVolume(true); + updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); volume = mRiggedVolume; transform = false; } @@ -4935,6 +4935,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } + // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. + // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. + updateRiggedVolume(true, i, false); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -5058,13 +5061,13 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update) +void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. - if ((!force_update) && (!treatAsRigged())) + if ((!force_treat_as_rigged) && (!treatAsRigged())) { clearRiggedVolume(); @@ -5093,10 +5096,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update) updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume); + mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; @@ -5127,7 +5130,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (is_paused) { S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); - if (frames_paused > 2) + if (frames_paused > 1) { return; } @@ -5146,7 +5149,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons S32 rigged_vert_count = 0; S32 rigged_face_count = 0; LLVector4a box_min, box_max; - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + S32 face_begin; + S32 face_end; + if (face_index == DO_NOT_UPDATE_FACES) + { + face_begin = 0; + face_end = 0; + } + else if (face_index == UPDATE_ALL_FACES) + { + face_begin = 0; + face_end = volume->getNumVolumeFaces(); + } + else + { + face_begin = face_index; + face_end = face_begin + 1; + } + for (S32 i = face_begin; i < face_end; ++i) { const LLVolumeFace& vol_face = volume->getVolumeFace(i); @@ -5234,27 +5254,18 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } - // Crashfix if mExtents is 0 - if( dst_face.mExtents ) - // - + if (rebuild_face_octrees) { - delete dst_face.mOctree; - dst_face.mOctree = NULL; - - LLVector4a size; - size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); - size.splat(size.getLength3().getF32()*0.5f); - + dst_face.destroyOctree(); // Create a debug log for octree insertions if requested. static LLCachedControl debugOctree(gSavedSettings,"FSCreateOctreeLog"); bool _debugOT( debugOctree ); if( _debugOT ) nd::octree::debug::gOctreeDebug += 1; // - - dst_face.createOctree(1.f); - + + dst_face.createOctree(); + // Reset octree log if( _debugOT ) nd::octree::debug::gOctreeDebug -= 1; @@ -5789,7 +5800,7 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[1] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[1]); + face->setDrawOrderIndex(count[1]); // BUG-232794: Restore old rigged mesh draw order list[1][count[1]++] = face; } } @@ -5797,15 +5808,42 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[0] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[0]); + face->setDrawOrderIndex(count[0]); // BUG-232794: Restore old rigged mesh draw order list[0][count[0]++] = face; } } } +// BUG-232794: Restore old rigged mesh draw order +// return index into linkset for given object (0 for root prim) +//U32 get_linkset_index(LLVOVolume* vobj) +//{ +// LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; +// if (vobj->isRootEdit()) +// { +// return 0; +// } +// +// LLViewerObject* root = vobj->getRootEdit(); +// U32 idx = 1; +// for (const auto& child : root->getChildren()) +// { +// if (child == vobj) +// { +// return idx; +// } +// ++idx; +// } +// +// llassert(false); +// return idx; //should never get here +//} +// + void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -6010,6 +6048,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) avatar->addAttachmentOverridesForObject(vobj, NULL, false); } + // BUG-232794: Restore old rigged mesh draw order + //U32 linkset_index = get_linkset_index(vobj); + // Standard rigged mesh attachments: bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); // Animated objects. Have to check for isRiggedMesh() to @@ -6029,6 +6070,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // order by linkset index first and face index second + // BUG-232794: Restore old rigged mesh draw order + //facep->setDrawOrderIndex(linkset_index * 100 + i); + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group facep->setVertexBuffer(NULL); @@ -6053,11 +6098,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->isState(LLFace::RIGGED)) { //face is not rigged but used to be, remove from rigged face pool - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); + // BUG-232794: Restore old rigged mesh draw order + LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); if (pool) { pool->removeFace(facep); } + // facep->clearState(LLFace::RIGGED); facep->mAvatar = NULL; facep->mSkinInfo = NULL; @@ -6248,7 +6295,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else { drawablep->clearState(LLDrawable::RIGGED); - vobj->updateRiggedVolume(); + vobj->updateRiggedVolume(false); } } } @@ -6359,7 +6406,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) ) + if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL)) { LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("Rebuild all non-Rigged"); LLVOVolume* vobj = drawablep->getVOVolume(); @@ -6404,8 +6451,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LLVertexBuffer* buff = face->getVertexBuffer(); if (buff) { - llassert(!face->isState(LLFace::RIGGED)); - if (!face->getGeometryVolume(*volume, face->getTEOffset(), vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex())) { //something's gone wrong with the vertex buffer accounting, rebuild this group @@ -6534,6 +6579,15 @@ struct CompareBatchBreakerRigged } }; +// BUG-232794: Restore old rigged mesh draw order +//struct CompareDrawOrder +//{ +// bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) +// { +// return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); +// } +//}; +// U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged) { @@ -6578,6 +6632,13 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); } + // BUG-232794: Restore old rigged mesh draw order + //else + //{ + // // preserve legacy draw order for rigged faces + // std::sort(faces, faces + face_count, CompareDrawOrder()); + //} + // } else if (!distance_sort) { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index d1a4c69b6a..46b38ba68a 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -67,7 +67,10 @@ public: { } - void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); + using FaceIndex = S32; + static const FaceIndex UPDATE_ALL_FACES = -1; + static const FaceIndex DO_NOT_UPDATE_FACES = -2; + void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES, bool rebuild_face_octrees = true); std::string mExtraDebugText; }; @@ -369,8 +372,9 @@ public: S32 getMDCImplCount() { return mMDCImplCount; } - //rigged volume update (for raycasting) - void updateRiggedVolume(bool force_update = false); + // Rigged volume update (for raycasting) + // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting + void updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true); LLRiggedVolume* getRiggedVolume(); //returns true if volume should be treated as a rigged volume diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 70e1638d52..797ec88050 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -68,9 +68,15 @@ #include "llglheaders.h" +// # Constants +static const F32 MAP_DEFAULT_SCALE = 128.f; +static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f; +static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f; +static const F32 MAP_ZOOM_MAX_INTERP = 0.5f; +static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f; + // Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py // Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...) -// # Constants // OCEAN_COLOR = "#1D475F" const F32 OCEAN_RED = (F32)(0x1D)/255.f; const F32 OCEAN_GREEN = (F32)(0x47)/255.f; @@ -102,14 +108,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL; -F32 LLWorldMapView::sPanX = 0.f; -F32 LLWorldMapView::sPanY = 0.f; -F32 LLWorldMapView::sTargetPanX = 0.f; -F32 LLWorldMapView::sTargetPanY = 0.f; S32 LLWorldMapView::sTrackingArrowX = 0; S32 LLWorldMapView::sTrackingArrowY = 0; bool LLWorldMapView::sVisibleTilesLoaded = false; -F32 LLWorldMapView::sMapScale = 128.f; +F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE; +LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f); +LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer(); std::map LLWorldMapView::sStringsMap; @@ -181,20 +185,27 @@ void LLWorldMapView::cleanupClass() sForSaleAdultImage = NULL; } -LLWorldMapView::LLWorldMapView() -: LLPanel(), - mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ), - mItemPicked(FALSE), - mPanning( FALSE ), - mMouseDownPanX( 0 ), - mMouseDownPanY( 0 ), - mMouseDownX( 0 ), - mMouseDownY( 0 ), - mSelectIDStart(0) +LLWorldMapView::LLWorldMapView() : + LLPanel(), + mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)), + mItemPicked(FALSE), + mPanX(0.f), + mPanY(0.f), + mTargetPanX(0.f), + mTargetPanY(0.f), + mPanning(FALSE), + mMouseDownPanX(0), + mMouseDownPanY(0), + mMouseDownX(0), + mMouseDownY(0), + mSelectIDStart(0), + mMapScale(0.f), + mTargetMapScale(0.f), + mMapIterpTime(MAP_ITERP_TIME_CONSTANT) { - //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; + // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; - clearLastClick(); + clearLastClick(); } BOOL LLWorldMapView::postBuild() @@ -225,6 +236,9 @@ BOOL LLWorldMapView::postBuild() mTextBoxNorthEast ->reshapeToFitText(); mTextBoxSouthWest->reshapeToFitText(); mTextBoxNorthWest ->reshapeToFitText(); + + sZoomTimer.stop(); + setScale(sMapScaleSetting, true); return true; } @@ -242,58 +256,110 @@ void LLWorldMapView::cleanupTextures() { } +void LLWorldMapView::zoom(F32 zoom) +{ + mTargetMapScale = scaleFromZoom(zoom); + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) + { + sZoomPivot = LLVector2(0, 0); + sZoomTimer.start(); + } +} + +void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y) +{ + mTargetMapScale = scaleFromZoom(zoom); + sZoomPivot = LLVector2(x, y); + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) + { + sZoomTimer.start(); + } +} + +F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); } + +F32 LLWorldMapView::getScale() { return mMapScale; } // static -void LLWorldMapView::setScale( F32 scale ) +void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; } + +// static +F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; } + +void LLWorldMapView::setScale(F32 scale, bool snap) { - if (scale != sMapScale) - { - F32 old_scale = sMapScale; + if (scale != mMapScale) + { + F32 old_scale = mMapScale; - sMapScale = scale; - if (sMapScale <= 0.f) - { - sMapScale = 0.1f; - } + mMapScale = scale; + // Set the scale used when saving the setting + sMapScaleSetting = scale; + if (mMapScale <= 0.f) + { + mMapScale = 0.1f; + } + mMapIterpTime = MAP_ITERP_TIME_CONSTANT; + F32 ratio = (scale / old_scale); + mPanX *= ratio; + mPanY *= ratio; + mTargetPanX = mPanX; + mTargetPanY = mPanY; + sVisibleTilesLoaded = false; - F32 ratio = (scale / old_scale); - sPanX *= ratio; - sPanY *= ratio; - sTargetPanX = sPanX; - sTargetPanY = sPanY; - sVisibleTilesLoaded = false; - } + // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here + if (!sZoomPivot.isExactlyZero()) + { + LLVector2 relative_pivot; + relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0); + relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0); + LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale); + mPanX += zoom_pan_offset.mV[VX]; + mPanY += zoom_pan_offset.mV[VY]; + mTargetPanX += zoom_pan_offset.mV[VX]; + mTargetPanY += zoom_pan_offset.mV[VY]; + } + } + + if (snap) + { + mTargetMapScale = scale; + } +} + +// static +void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y) +{ + mPanX += delta_x; + mPanY += delta_y; + mTargetPanX = mPanX; + mTargetPanY = mPanY; + sVisibleTilesLoaded = false; } // static -void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y ) +void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap) { - sPanX += delta_x; - sPanY += delta_y; - sTargetPanX = sPanX; - sTargetPanY = sPanY; - sVisibleTilesLoaded = false; + mMapIterpTime = MAP_ITERP_TIME_CONSTANT; + mTargetPanX = (F32) x; + mTargetPanY = (F32) y; + if (snap) + { + mPanX = mTargetPanX; + mPanY = mTargetPanY; + } + sVisibleTilesLoaded = false; } - // static -void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) +void LLWorldMapView::setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time) { - sTargetPanX = (F32)x; - sTargetPanY = (F32)y; - if (snap) - { - sPanX = sTargetPanX; - sPanY = sTargetPanY; - } - sVisibleTilesLoaded = false; + setPan(x, y, snap); + mMapIterpTime = interp_time; } -bool LLWorldMapView::showRegionInfo() -{ - return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); -} +bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); } /////////////////////////////////////////////////////////////////////////////////// // HELPERS @@ -326,9 +392,28 @@ void LLWorldMapView::draw() mVisibleRegions.clear(); - // animate pan if necessary - sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f)); - sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f)); + // animate pan if necessary + mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(mMapIterpTime)); + mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(mMapIterpTime)); + + //RN: snaps to zoom value because interpolation caused jitter in the text rendering + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) + { + sZoomTimer.start(); + } + bool snap_scale = false; + F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME); + F32 current_zoom_val = zoomFromScale(mMapScale); + F32 target_zoom_val = zoomFromScale(mTargetMapScale); + F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp); + if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD) + { + sZoomTimer.stop(); + snap_scale = true; + new_zoom_val = target_zoom_val; + } + F32 map_scale = scaleFromZoom(new_zoom_val); + setScale(map_scale, snap_scale); const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); @@ -336,7 +421,7 @@ void LLWorldMapView::draw() const F32 half_height = F32(height) / 2.0f; LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); LLLocalClipRect clip(getLocalRect()); { @@ -387,18 +472,18 @@ void LLWorldMapView::draw() // Find x and y position relative to camera's center. LLVector3d rel_region_pos = origin_global - camera_global; - F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; - F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; + F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale; + F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale; // Coordinates of the sim in pixels in the UI panel // When the view isn't panned, 0,0 = center of rectangle - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; + F32 bottom = mPanY + half_height + relative_y; + F32 left = mPanX + half_width + relative_x; // Aurora Sim - //F32 top = bottom + sMapScale ; - //F32 right = left + sMapScale ; - F32 top = bottom+ (sMapScale * (info->mSizeY / REGION_WIDTH_METERS)); - F32 right = left + (sMapScale * (info->mSizeX / REGION_WIDTH_METERS)); + //F32 top = bottom + mMapScale ; + //F32 right = left + mMapScale ; + F32 top = bottom+ (mMapScale * (info->mSizeY / REGION_WIDTH_METERS)); + F32 right = left + (mMapScale * (info->mSizeX / REGION_WIDTH_METERS)); // Aurora Sim // Discard if region is outside the screen rectangle (not visible on screen) @@ -479,10 +564,10 @@ void LLWorldMapView::draw() { // Inform the fetch mechanism of the size we need // Aurora Sim - //S32 draw_size = ll_round(sMapScale); + //S32 draw_size = ll_round(mMapScale); //overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY])); - S32 x_draw_size = ll_round(sMapScale); - S32 y_draw_size = ll_round(sMapScale); + S32 x_draw_size = ll_round(mMapScale); + S32 y_draw_size = ll_round(mMapScale); x_draw_size *= (info->mSizeX / REGION_WIDTH_METERS); y_draw_size *= (info->mSizeY / REGION_WIDTH_METERS); @@ -533,7 +618,7 @@ void LLWorldMapView::draw() } // Draw the region name in the lower left corner - if (sMapScale >= DRAW_TEXT_THRESHOLD) + if (mMapScale >= DRAW_TEXT_THRESHOLD) { LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD)); std::string mesg; @@ -552,7 +637,7 @@ void LLWorldMapView::draw() LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, S32_MAX, //max_chars - sMapScale, //max_pixels + mMapScale, //max_pixels NULL, TRUE); //use ellipses @@ -583,7 +668,7 @@ void LLWorldMapView::draw() LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, S32_MAX, //max_chars - sMapScale, //max_pixels + mMapScale, //max_pixels NULL, TRUE); //use ellipses } @@ -721,7 +806,7 @@ void LLWorldMapView::setVisible(BOOL visible) void LLWorldMapView::drawMipmap(S32 width, S32 height) { // Compute the level of the mipmap to use for the current scale level - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); // Set the tile boost level so that unused tiles get to 0 LLWorldMap::getInstance()->equalizeBoostLevels(); @@ -1046,7 +1131,7 @@ void LLWorldMapView::drawAgents() void LLWorldMapView::drawFrustum() { // Draw frustum - F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; + F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS; F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); @@ -1056,8 +1141,8 @@ void LLWorldMapView::drawFrustum() F32 half_width_pixels = half_width_meters * meters_to_pixels; // Compute the frustum coordinates. Take the UI scale into account. - F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]); - F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]); + F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]); + F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -1114,13 +1199,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos ) LLVector3 pos_local; pos_local.setVec(relative_pos_global); // convert to floats from doubles - pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS; - pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS; + pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS; + pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS; // leave Z component in meters - pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX; - pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY; + pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX; + pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY; return pos_local; } @@ -1195,12 +1280,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& // If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y ) { - x -= llfloor((getRect().getWidth() / 2 + sPanX)); - y -= llfloor((getRect().getHeight() / 2 + sPanY)); + x -= llfloor((getRect().getWidth() / 2 + mPanX)); + y -= llfloor((getRect().getHeight() / 2 + mPanY)); LLVector3 pos_local( (F32)x, (F32)y, 0.f ); - pos_local *= ( REGION_WIDTH_METERS / sMapScale ); + pos_local *= ( REGION_WIDTH_METERS / mMapScale ); LLVector3d pos_global; pos_global.setVec( pos_local ); @@ -1662,7 +1747,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, LLWorldMap::getInstance()->cancelTracking(); - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); // If the zoom level is not too far out already, test hits if (level <= DRAW_SIMINFO_THRESHOLD) { @@ -1779,8 +1864,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask ) { gFocusMgr.setMouseCapture( this ); - mMouseDownPanX = ll_round(sPanX); - mMouseDownPanY = ll_round(sPanY); + mMouseDownPanX = ll_round(mPanX); + mMouseDownPanY = ll_round(mPanY); mMouseDownX = x; mMouseDownY = y; sHandledLastClick = TRUE; @@ -1795,8 +1880,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) { // restore mouse cursor S32 local_x, local_y; - local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX); - local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY); + local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX); + local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY); LLRect clip_rect = getRect(); clip_rect.stretch(-8); clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y); @@ -1824,7 +1909,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) void LLWorldMapView::updateVisibleBlocks() { - if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD) + if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD) { // If we're zoomed out too much, we just don't load all those sim info: too much! return; @@ -1840,16 +1925,16 @@ void LLWorldMapView::updateVisibleBlocks() const F32 half_height = F32(height) / 2.0f; // Compute center into sim grid coordinates - S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); - S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); + S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); + S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); // Compute the boundaries into sim grid coordinates - S32 world_left = world_center_x - S32(half_width / sMapScale) - 1; - S32 world_right = world_center_x + S32(half_width / sMapScale) + 1; - S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1; - S32 world_top = world_center_y + S32(half_height / sMapScale) + 1; + S32 world_left = world_center_x - S32(half_width / mMapScale) - 1; + S32 world_right = world_center_x + S32(half_width / mMapScale) + 1; + S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1; + S32 world_top = world_center_y + S32(half_height / mMapScale) + 1; - //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; + //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top); } @@ -1870,10 +1955,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask ) F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY()); // Set pan to value at start of drag + offset - sPanX += delta_x; - sPanY += delta_y; - sTargetPanX = sPanX; - sTargetPanY = sPanY; + mPanX += delta_x; + mPanY += delta_y; + mTargetPanX = mPanX; + mTargetPanY = mPanY; gViewerWindow->moveCursorToCenter(); } @@ -1976,4 +2061,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) return FALSE; } +// static +F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; } +// static +F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); } diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index a2a6dc53fb..ce8af76a82 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -67,12 +67,22 @@ public: bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track); void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id); - // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered) - static void setScale( F32 scale ); - static void translatePan( S32 delta_x, S32 delta_y ); - static void setPan( S32 x, S32 y, BOOL snap = TRUE ); + // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered) + // Zoom is used for UI and will interpolate the map scale over multiple frames. + void zoom(F32 zoom); + void zoomWithPivot(F32 zoom, S32 x, S32 y); + F32 getZoom(); + // Scale is a linear scaling factor of in-world coordinates + F32 getScale(); + // setScaleSetting/getScaleSetting are for the default map setting on login + static void setScaleSetting(F32 scaleSetting); + static F32 getScaleSetting(); + // Pan is in pixels relative to the center of the map. + void translatePan( S32 delta_x, S32 delta_y ); + void setPan( S32 x, S32 y, BOOL snap = TRUE ); + void setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time); // Return true if the current scale level is above the threshold for accessing region info - static bool showRegionInfo(); + bool showRegionInfo(); LLVector3 globalPosToView(const LLVector3d& global_pos); LLVector3d viewPosToGlobal(S32 x,S32 y); @@ -153,14 +163,12 @@ public: static LLUIImagePtr sForSaleImage; static LLUIImagePtr sForSaleAdultImage; - static F32 sMapScale; // scale = size of a region in pixels - BOOL mItemPicked; - static F32 sPanX; // in pixels - static F32 sPanY; // in pixels - static F32 sTargetPanX; // in pixels - static F32 sTargetPanY; // in pixels + F32 mPanX; // in pixels + F32 mPanY; // in pixels + F32 mTargetPanX; // in pixels + F32 mTargetPanY; // in pixels static S32 sTrackingArrowX; static S32 sTrackingArrowY; static bool sVisibleTilesLoaded; @@ -194,6 +202,19 @@ public: private: void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right); + + void setScale(F32 scale, bool snap = true); + + static F32 scaleFromZoom(F32 zoom); + static F32 zoomFromScale(F32 scale); + + F32 mMapScale; + F32 mTargetMapScale; + static F32 sMapScaleSetting; + static LLVector2 sZoomPivot; + static LLFrameTimer sZoomTimer; + + F32 mMapIterpTime; }; #endif diff --git a/indra/newview/quickprefs.cpp b/indra/newview/quickprefs.cpp index 723610abb9..8cd211e4ee 100644 --- a/indra/newview/quickprefs.cpp +++ b/indra/newview/quickprefs.cpp @@ -1066,7 +1066,6 @@ void FloaterQuickPrefs::refreshSettings() BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && bumpshiny && shaders && - gGLManager.mHasFramebufferObject && (mCtrlWindLight->get()) ? TRUE : FALSE; mCtrlDeferred->setEnabled(enabled); @@ -1106,8 +1105,7 @@ void FloaterQuickPrefs::refreshSettings() } // disabled deferred - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") || - !gGLManager.mHasFramebufferObject) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) { mCtrlShadowDetail->setEnabled(FALSE); mCtrlShadowDetail->setValue(0); diff --git a/indra/newview/skins/ansastorm/colors.xml b/indra/newview/skins/ansastorm/colors.xml index 4d42f48471..70634c08d7 100644 --- a/indra/newview/skins/ansastorm/colors.xml +++ b/indra/newview/skins/ansastorm/colors.xml @@ -837,10 +837,10 @@ - + name="MapParcelOutlineColor" + value="1 1 1 1" /> + @@ -894,9 +894,6 @@ name="ModelUploaderLabels" value="1 0.6 0 1" /> - + + - + name="MapParcelOutlineColor" + value="1 1 1 1" /> + @@ -891,9 +891,6 @@ name="ModelUploaderLabels" value="1 0.6 0 1" /> - - + + name="MapParcelOutlineColor" + value="1 1 1 1" /> + @@ -834,9 +835,6 @@ name="ModelUploaderLabels" value="1 0.6 0 1" /> - + + - - [REGION](Dobbeltklik for at åbne kort, klik-og-træk for at panorere) - - - [REGION](Dobbeltklik for at teleportere, træk for at panorere) - MINIKORT diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 0842f0b52a..57e5aee6cd 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -4049,6 +4049,9 @@ Krænkelsesanmeldelse Kvinde - Wow + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] diff --git a/indra/newview/skins/default/xui/de/floater_map.xml b/indra/newview/skins/default/xui/de/floater_map.xml index d0a6c54246..d68c4b2000 100644 --- a/indra/newview/skins/default/xui/de/floater_map.xml +++ b/indra/newview/skins/default/xui/de/floater_map.xml @@ -1,10 +1,22 @@ - - [AGENT][REGION](Doppelklicken, um Karte zu öffnen; Umschalt-Taste gedrückt halten und ziehen, um zu schwenken) + + Preis: [PRICE] L$ ([PRICE_PER_SQM] L$/m²) - - [REGION](Doppelklicken, um zu teleportieren; Umschalt-Taste gedrückt halten und ziehen, um zu schwenken) + + Fläche: [AREA]m² + + + Eigentümer: [PARCEL_OWNER] + + + Region: [REGION_NAME] + + + Doppelklicken, um Karte zu öffnen + + + Doppelklicken, um zu teleportieren Minikarte diff --git a/indra/newview/skins/default/xui/de/floater_model_preview.xml b/indra/newview/skins/default/xui/de/floater_model_preview.xml index 474f09a594..50e358e923 100644 --- a/indra/newview/skins/default/xui/de/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/de/floater_model_preview.xml @@ -258,6 +258,9 @@ Niedrigste + + Bounding Box + Würfel diff --git a/indra/newview/skins/default/xui/de/floater_vj_local_mesh.xml b/indra/newview/skins/default/xui/de/floater_vj_local_mesh.xml new file mode 100644 index 0000000000..9557b17a71 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_vj_local_mesh.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + LOD-Suffixe: + + + Aktuell + SL-Standard + Spiele-Engine-Standard + LOD Namen + + + Niedrigstes: + + + + Niedrid: + + + + Medium: + + + + Hoch: + + + + Physik: + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/de/menu_attachment_self.xml b/indra/newview/skins/default/xui/de/menu_attachment_self.xml index 79c7b2234c..2173a5b838 100644 --- a/indra/newview/skins/default/xui/de/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/de/menu_attachment_self.xml @@ -10,11 +10,16 @@ - - - - - + + + + + + + + + + @@ -35,12 +40,11 @@ - - - - - - + + + + + diff --git a/indra/newview/skins/default/xui/de/menu_avatar_self.xml b/indra/newview/skins/default/xui/de/menu_avatar_self.xml index 95221055a3..81e3185b0b 100644 --- a/indra/newview/skins/default/xui/de/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/de/menu_avatar_self.xml @@ -22,17 +22,21 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/de/menu_inventory.xml b/indra/newview/skins/default/xui/de/menu_inventory.xml index ddfd6a1cf1..63e222e311 100644 --- a/indra/newview/skins/default/xui/de/menu_inventory.xml +++ b/indra/newview/skins/default/xui/de/menu_inventory.xml @@ -121,6 +121,7 @@ + diff --git a/indra/newview/skins/default/xui/de/menu_mini_map.xml b/indra/newview/skins/default/xui/de/menu_mini_map.xml index a38e8c4f87..2b9e01a7fe 100644 --- a/indra/newview/skins/default/xui/de/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/de/menu_mini_map.xml @@ -40,10 +40,10 @@ - - - - + + + + @@ -55,15 +55,18 @@ - - - + + + + + + diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml index 52058b5f18..586c9d1eda 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -247,6 +247,7 @@ + @@ -320,6 +321,7 @@ + @@ -532,6 +534,9 @@ + + + diff --git a/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml index dd56494069..1603b39cbc 100644 --- a/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml @@ -29,5 +29,5 @@ - + diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml index c00a6deaef..b7d45b03aa 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml @@ -20,6 +20,7 @@ (Erfordert Neustart) + Auf Inhalte mit folgender Einstufung zugreifen: diff --git a/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml index 5586075b28..28f7b3abdd 100644 --- a/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/de/panel_profile_secondlife.xml @@ -6,6 +6,9 @@ Offline + + Unbekannt + http://www.secondlife.com/account/billing.php?lang=de @@ -69,6 +72,7 @@ + diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 078c85ddae..d0c3eb8dd2 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -5360,6 +5360,9 @@ Missbrauchsbericht Tanzen8 + [day,datetime,utc].[mthnum,datetime,utc].[year,datetime,utc] + + [day,datetime,slt].[mthnum,datetime,slt].[year,datetime,slt] @@ -6603,18 +6606,7 @@ Support-Bereich der Website Secondlife.com und melden Sie das Problem. Maximale Bandbreite gesetzt auf: [VALUE] kbit/s. - - - - [AGENT][REGION](Doppelklicken, um Karte zu öffnen; Umschalt-Taste gedrückt halten und ziehen, um zu schwenken) - - - [REGION](Doppelklicken, um zu teleportieren; Umschalt-Taste gedrückt halten und ziehen, um zu schwenken) - - - [REGION] - - + [NAME] hat Sie gestoßen. diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml index b938f6af3c..a730f9a6a7 100644 --- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml +++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml @@ -87,6 +87,7 @@ spellcheck="true" text_readonly_color="white" text_type="ascii_with_newline" + commit_on_focus_lost="true" top_pad="5" width="290" wrap="true" /> diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index 35e90a0556..6b914668d4 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -20,14 +20,38 @@ - [AGENT][REGION](Double-click to open Map, shift-drag to pan) + [AGENT][PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG] - - [REGION](Double-click to teleport, shift-drag to pan) - - - Mini-map + + [PARCEL_NAME] + + + Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + + + Area: [AREA]m² + + + Owner: [PARCEL_OWNER] + + + Region: [REGION_NAME] + + + Double-click to open map + + + Double-click to teleport + + + Mini-map + text_color="1 1 1 0.7"> N + text_color="1 1 1 0.7"> E + text_color="1 1 1 0.7"> W + text_color="1 1 1 0.7"> S + text_color="1 1 1 0.7"> SE + text_color="1 1 1 0.7"> NE + text_color="1 1 1 0.7"> SW + text_color="1 1 1 0.7"> NW diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 49dce0598a..e81fb96942 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -854,6 +854,7 @@ Cube Hexagon User Defined + Bounding Box From file - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + function="Tools.StopAllAnimations" /> - - - - - - - - - - - - - - - - - - - + name="CommunitySubmenu"> + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml index 40d993cc8d..0db4e7434f 100644 --- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml @@ -204,90 +204,101 @@ function="Self.EnableRemoveAllAttachments" /> - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + name="CommunitySubmenu"> + + + + + + + + + + - @@ -311,7 +322,7 @@ function="Avatar.TexRefresh" /> diff --git a/indra/newview/skins/default/xui/en/menu_fs_profile_overflow.xml b/indra/newview/skins/default/xui/en/menu_fs_profile_overflow.xml index 63f496fcc3..0f9fad7da8 100644 --- a/indra/newview/skins/default/xui/en/menu_fs_profile_overflow.xml +++ b/indra/newview/skins/default/xui/en/menu_fs_profile_overflow.xml @@ -71,7 +71,7 @@ name="copy_name_to_clipboard"> + parameter="copy_username"/> + + + + - + + + + - + - - - + + + - - + + - + - - - - - + + + parameter="MiniMapShowPropertyLines" /> + control="MiniMapShowPropertyLines" /> + control="MiniMapShowPropertyLines" /> + label="North at top" + name="North at top"> + function="Minimap.MapOrientation.Check" + parameter="north_at_top" /> + function="Minimap.MapOrientation.Set" + parameter="north_at_top" /> + label="Camera at top" + name="Camera at top"> + + + + + + + @@ -455,6 +484,12 @@ + + + diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index d4eb777c28..40e637c5d6 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2971,6 +2971,16 @@ + + + + @@ -4618,6 +4628,18 @@ function="Advanced.DropPacket" /> + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_ao.xml b/indra/newview/skins/default/xui/en/panel_ao.xml index 0d8f50183d..8d93ff1ed4 100644 --- a/indra/newview/skins/default/xui/en/panel_ao.xml +++ b/indra/newview/skins/default/xui/en/panel_ao.xml @@ -31,6 +31,7 @@ allow_text_entry="true" max_chars="256" follows="left|right|top" + force_disable_fulltext_search="true" layout="topleft" /> diff --git a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml index 3f7e3290a7..57cb4990e4 100644 --- a/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml +++ b/indra/newview/skins/default/xui/en/panel_fs_search_legacy_events.xml @@ -87,6 +87,7 @@ + diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml index 4541f0228d..6ae637916e 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -114,6 +114,17 @@ width="130"> (Requires restart) + - Offline + + Unknown + @@ -346,15 +351,15 @@ height="158" auto_resize="false" user_resize="false"> - + show_caption="false" + layout="topleft" /> + dance8 - [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] none/none Can't load images larger than [WIDTH]*[HEIGHT] @@ -2866,11 +2867,6 @@ name="Command_360_Capture_Tooltip">Capture a 360° equirectangular image(unknown region) (unknown position) - - [AGENT][REGION](Double-click to open Map, shift-drag to pan) - [REGION](Double-click to teleport, shift-drag to pan) - [REGION] - [NAME] bumped you. [NAME] pushed you with a script. diff --git a/indra/newview/skins/default/xui/es/floater_map.xml b/indra/newview/skins/default/xui/es/floater_map.xml index 53057a28ef..1a2b72cf86 100644 --- a/indra/newview/skins/default/xui/es/floater_map.xml +++ b/indra/newview/skins/default/xui/es/floater_map.xml @@ -1,11 +1,5 @@ - - [AGENT][REGION](Doble clic para abrir el Mapa, mayús. y arrastrar para obtener panorámica) - - - [REGION](Doble clic para teleportarte, mayús. y arrastrar para obtener panorámica) - Minimapa diff --git a/indra/newview/skins/default/xui/es/menu_attachment_self.xml b/indra/newview/skins/default/xui/es/menu_attachment_self.xml index 37588e43fb..c25e3c19b7 100644 --- a/indra/newview/skins/default/xui/es/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/es/menu_attachment_self.xml @@ -9,15 +9,19 @@ - - - - - - - - - + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/es/menu_avatar_self.xml b/indra/newview/skins/default/xui/es/menu_avatar_self.xml index 6912527132..dede4f18f1 100644 --- a/indra/newview/skins/default/xui/es/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/es/menu_avatar_self.xml @@ -22,16 +22,20 @@ - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/es/panel_profile_picks.xml b/indra/newview/skins/default/xui/es/panel_profile_picks.xml index 50d40b97b7..48bcfdee77 100644 --- a/indra/newview/skins/default/xui/es/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/es/panel_profile_picks.xml @@ -1,12 +1,18 @@ - - Cuéntale a todos sobre tus lugares favoritos de [GRID]. - - - - - Cargando... - + + + + Cuéntale a todos sobre tus lugares favoritos de [GRID]. + + + + + + + Cargando... + + + diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index e7bec9f86e..f12e1004f5 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -5039,6 +5039,9 @@ Denuncia de infracción baile8 + [day,datetime,utc]/[mthnum,datetime,utc]/[year,datetime,utc] + + [day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt] diff --git a/indra/newview/skins/default/xui/fr/floater_about_land.xml b/indra/newview/skins/default/xui/fr/floater_about_land.xml index 15e28f0fbe..ec9cbe19aa 100644 --- a/indra/newview/skins/default/xui/fr/floater_about_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_about_land.xml @@ -412,6 +412,9 @@ texture : URL de la musique : + + + Son : @@ -427,6 +430,10 @@ musique : + + Média: + + diff --git a/indra/newview/skins/default/xui/fr/floater_add_payment_method.xml b/indra/newview/skins/default/xui/fr/floater_add_payment_method.xml new file mode 100644 index 0000000000..bd0550f2b4 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_add_payment_method.xml @@ -0,0 +1,19 @@ + + + + + Ajouter un moyen de paiement pour acheter des Lindens et mieux profiter de Second Life. + + + + + Créez l'avatar que vous aimez. Faites votre choix parmi des millions d'articles dans les boutiques et sur la place du marché de Second Life. Votre style est ici. + + + Soutenez vos artistes et animateurs préférés. Vous les aiderez à créer de grandes expériences. + + + Créez la maison de vos rêves. Les millions d'articles disponibles à l'achat peuvent rendre votre foyer unique. + + + \ No newline at end of file diff --git a/indra/newview/skins/default/xui/fr/floater_classified.xml b/indra/newview/skins/default/xui/fr/floater_classified.xml new file mode 100644 index 0000000000..73177f21b1 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_classified.xml @@ -0,0 +1,2 @@ + + diff --git a/indra/newview/skins/default/xui/fr/floater_display_name.xml b/indra/newview/skins/default/xui/fr/floater_display_name.xml index 18207f0356..203d5996fd 100644 --- a/indra/newview/skins/default/xui/fr/floater_display_name.xml +++ b/indra/newview/skins/default/xui/fr/floater_display_name.xml @@ -3,7 +3,7 @@ Le nom que vous choisissez d'utiliser pour votre avatar est appelé le nom d'affichage. Vous pouvez le changer une fois par semaine. Vous ne pouvez changer votre nom avant le [TIME]. Nouveau nom : - Ressaisissez votre nouveau nom : + Réécrivez le nom : diff --git a/indra/newview/skins/default/xui/fr/floater_forget_user.xml b/indra/newview/skins/default/xui/fr/floater_forget_user.xml new file mode 100644 index 0000000000..d7001dc05b --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_forget_user.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_fs_avatar_render_settings.xml b/indra/newview/skins/default/xui/fr/floater_fs_avatar_render_settings.xml new file mode 100644 index 0000000000..d1b2899f22 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_fs_avatar_render_settings.xml @@ -0,0 +1,16 @@ + + + + Jamais + + + Toujours + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_fs_camera_small.xml b/indra/newview/skins/default/xui/fr/floater_fs_camera_small.xml new file mode 100644 index 0000000000..7cc629b60a --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_fs_camera_small.xml @@ -0,0 +1,35 @@ + + + + Faites pivoter la caméra autour du sujet + + + Zoomez sur le sujet + + + Déplacez la caméra vers le haut, le bas, la gauche et la droite. + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_fs_protectedfolders.xml b/indra/newview/skins/default/xui/fr/floater_fs_protectedfolders.xml new file mode 100644 index 0000000000..9f914c55c9 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_fs_protectedfolders.xml @@ -0,0 +1,15 @@ + + + + (dossier inconnu) + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_fs_wearable_favorites.xml b/indra/newview/skins/default/xui/fr/floater_fs_wearable_favorites.xml new file mode 100644 index 0000000000..4a6de75f89 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_fs_wearable_favorites.xml @@ -0,0 +1,14 @@ + + + + Faites glisser les objets ici pour les ajouter à la liste. + + + Aucun élément ne correspond. + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_god_tools.xml b/indra/newview/skins/default/xui/fr/floater_god_tools.xml new file mode 100644 index 0000000000..660e6b1c3b --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_god_tools.xml @@ -0,0 +1,93 @@ + + + + + + + + + Nom région : + + + + + + + + + + + + + + ID de la région : + + + ID du parent : + + + + Pos. sur la grille : + + + + + Redir. vers grille : + + + Taux de paiement : + + + L$/m² : + + + + + + + + + (pas de cible) + + + Nom région : + + + + + + + + (pas de cible) + + + + + + + + + + + Destination : + + + + + + + Requête : + + + + + + + + + Paramètre : + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_map.xml b/indra/newview/skins/default/xui/fr/floater_map.xml index 37d43afcea..1e14a07271 100644 --- a/indra/newview/skins/default/xui/fr/floater_map.xml +++ b/indra/newview/skins/default/xui/fr/floater_map.xml @@ -1,8 +1,8 @@ - [AGENT][REGION](Double-clic pour ouvrir la carte, maintenez shift pour une vue panoramique) - [REGION](Double -clic pour vous téléporter, maintenez shift pour une vue panoramique) - Mini-carte + + Mini-carte + N diff --git a/indra/newview/skins/default/xui/fr/floater_outfit_photo_preview.xml b/indra/newview/skins/default/xui/fr/floater_outfit_photo_preview.xml new file mode 100644 index 0000000000..7901b00486 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_outfit_photo_preview.xml @@ -0,0 +1,13 @@ + + + + Photo : [NAME] + + + La taille max. des photos d'une tenue est [MAX_WIDTH]*[MAX_HEIGHT]. Prenez une autre photo. + + + Définir cette photo pour la tenue [OUTFIT] ? + + + diff --git a/indra/newview/skins/default/xui/fr/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/fr/floater_outfit_snapshot.xml new file mode 100644 index 0000000000..67fc17d8d6 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_outfit_snapshot.xml @@ -0,0 +1,61 @@ + + + + inconnu + + + Enregistrement dans l'inventaire + + + Enregistré dans l'inventaire !! + + + Échec de l'enregistrement. + + + + + + Capture : + + + + + + + + + + + + + Filtre : + + + + + + + + Succés + + + + + Échec + + + + Je travaille + + + Actualisez pour enregistrer. + + + + [WIDTH]px (largeur) x [HEIGHT]px (hauteur) + + + [SIZE] Ko + + diff --git a/indra/newview/skins/default/xui/fr/floater_particle_editor.xml b/indra/newview/skins/default/xui/fr/floater_particle_editor.xml new file mode 100644 index 0000000000..c0aa6b934f --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_particle_editor.xml @@ -0,0 +1,116 @@ + + + + + + Modèle : + + + + + + + + + + Texture : + + + Vit. d'impulsion : + + + Nbre d'impulsions : + + + Rayon éclatement : + + + Angle de départ : + + + Le plus lent : + + + Angle de fin : + + + Le plus rapide: + + + Âge max. source : + + + Alpha de départ : + + + Âge max. particules: + + + Alpha final : + + + Lueur initiale : + + + + + + + + + + + + + Lueur de fin : + + + + + + + + + + + + + Échelle départ : + + + Fin : + + + + + + + + + + + + + + + + + + + Clé de la cible : + + + + + Accélération : + + + Rotation : + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml index b5865cb2d6..6e78ff3006 100644 --- a/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/fr/floater_preferences_graphics_advanced.xml @@ -12,7 +12,7 @@ Faible - + Avatar diff --git a/indra/newview/skins/default/xui/fr/floater_preview_trash.xml b/indra/newview/skins/default/xui/fr/floater_preview_trash.xml new file mode 100644 index 0000000000..3fff219a8f --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_preview_trash.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_profile_permissions.xml b/indra/newview/skins/default/xui/fr/floater_profile_permissions.xml new file mode 100644 index 0000000000..66bec71e1a --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_profile_permissions.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_profile_texture.xml b/indra/newview/skins/default/xui/fr/floater_profile_texture.xml new file mode 100644 index 0000000000..e5629e27cd --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_profile_texture.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_report_abuse.xml b/indra/newview/skins/default/xui/fr/floater_report_abuse.xml index 14fdc99709..988c42a9e8 100644 --- a/indra/newview/skins/default/xui/fr/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/fr/floater_report_abuse.xml @@ -1,6 +1,10 @@ Capture d'écran + +Heure : [MSG_TIME] +Texte : [MSG_DESCRIPTION] + Signaleur : @@ -34,7 +38,7 @@ Nom du contrevenant : - Emplacement de l'abus : + Emplacement de l'infraction : Résumé : Détails : Veuillez être aussi précis que possible diff --git a/indra/newview/skins/default/xui/fr/floater_rlv_console.xml b/indra/newview/skins/default/xui/fr/floater_rlv_console.xml new file mode 100644 index 0000000000..2d6af885ab --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_rlv_console.xml @@ -0,0 +1,2 @@ + + diff --git a/indra/newview/skins/default/xui/fr/floater_save_camera_preset.xml b/indra/newview/skins/default/xui/fr/floater_save_camera_preset.xml new file mode 100644 index 0000000000..a0ed253e0b --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_save_camera_preset.xml @@ -0,0 +1,15 @@ + + + + Enregistrer + + + Remplacer + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_script_ed_prefs.xml b/indra/newview/skins/default/xui/fr/floater_script_ed_prefs.xml new file mode 100644 index 0000000000..1f5d4ca600 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_script_ed_prefs.xml @@ -0,0 +1,72 @@ + + + + Sélectionnez les couleurs souhaitées : + + + Texte + + + Curseur + + + Arrière plan + + + Sections + + + Types de données + + + Événements + + + Commentaires + + + Fonction + + + Littéraux de chaîne + + + Constante + + + Entiers + + + Chaînes de caract. + + + Nombres flottants. + + + Struct. complexes + + + Flux de contrôle. + + + Préprocesseur + + + Options de l'éditeur de script : + + + + + + + + + Chemin d'inclusion du préprocesseur : + + + + Options avancées : + + + + diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml index 434bb1317f..e27c5796c1 100644 --- a/indra/newview/skins/default/xui/fr/floater_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_tools.xml @@ -392,7 +392,7 @@ Coller rotation - Informations sur le maillage : + Info maillage : @@ -409,18 +409,18 @@ Le plus bas: - + - - + + Paramètres par défaut du visualiseur de Linden Lab Second Life ([FACTOR]) Paramètres par défaut de [APP_NAME] ([FACTOR]) Haut ↔ Moy. Moy. ↔ Bas -Bas ↔ Plus bas +Bas ↔ + bas Ce tableau indique les limites de changement de niveau de détail en mètres à partir de la caméra. diff --git a/indra/newview/skins/default/xui/fr/floater_vj_local_mesh.xml b/indra/newview/skins/default/xui/fr/floater_vj_local_mesh.xml new file mode 100644 index 0000000000..8405d5c9ad --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_vj_local_mesh.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + Suffixes LOD : + + + Actuel + Standard SL + Standard de moteur de jeu + Noms LOD + + + Le plus bas : + + + + Bas : + + + + Moyen : + + + + Élevé : + + + + Physique : + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml index c4d2988b13..bcb3466b49 100644 --- a/indra/newview/skins/default/xui/fr/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/fr/menu_attachment_self.xml @@ -10,15 +10,19 @@ - - - - - - - - - + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml b/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml index 225f739486..08a2946efa 100644 --- a/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml +++ b/indra/newview/skins/default/xui/fr/menu_avatar_icon.xml @@ -18,6 +18,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml index 7023f8ddd7..3a83b662c0 100644 --- a/indra/newview/skins/default/xui/fr/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/fr/menu_avatar_self.xml @@ -22,15 +22,19 @@ - - - - - - - - - + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_conversation.xml b/indra/newview/skins/default/xui/fr/menu_conversation.xml index 53e8bc01be..3d5785e9bf 100644 --- a/indra/newview/skins/default/xui/fr/menu_conversation.xml +++ b/indra/newview/skins/default/xui/fr/menu_conversation.xml @@ -18,6 +18,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/menu_fs_asset_blacklist.xml b/indra/newview/skins/default/xui/fr/menu_fs_asset_blacklist.xml new file mode 100644 index 0000000000..dcfca675e0 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_fs_asset_blacklist.xml @@ -0,0 +1,4 @@ + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_fs_avatar_render_setting.xml b/indra/newview/skins/default/xui/fr/menu_fs_avatar_render_setting.xml new file mode 100644 index 0000000000..803a2b71b0 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_fs_avatar_render_setting.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_fs_inspect_options.xml b/indra/newview/skins/default/xui/fr/menu_fs_inspect_options.xml new file mode 100644 index 0000000000..6e86111ed9 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_fs_inspect_options.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_fs_wearable_favorites.xml b/indra/newview/skins/default/xui/fr/menu_fs_wearable_favorites.xml new file mode 100644 index 0000000000..bd50144a9c --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_fs_wearable_favorites.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/fr/menu_gallery_outfit_tab.xml new file mode 100644 index 0000000000..3254ccf27c --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_gallery_outfit_tab.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_im_conversation.xml b/indra/newview/skins/default/xui/fr/menu_im_conversation.xml index d7eca8036c..b530366f8d 100644 --- a/indra/newview/skins/default/xui/fr/menu_im_conversation.xml +++ b/indra/newview/skins/default/xui/fr/menu_im_conversation.xml @@ -10,6 +10,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/menu_inventory.xml b/indra/newview/skins/default/xui/fr/menu_inventory.xml index 8740dcb2b9..5c64ff7b15 100644 --- a/indra/newview/skins/default/xui/fr/menu_inventory.xml +++ b/indra/newview/skins/default/xui/fr/menu_inventory.xml @@ -47,7 +47,7 @@ - + @@ -84,6 +84,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/menu_perf_avatar_rendering_settings.xml b/indra/newview/skins/default/xui/fr/menu_perf_avatar_rendering_settings.xml new file mode 100644 index 0000000000..4e14bacab7 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_perf_avatar_rendering_settings.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_places_gear_sorting.xml b/indra/newview/skins/default/xui/fr/menu_places_gear_sorting.xml new file mode 100644 index 0000000000..745dc94387 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/menu_places_gear_sorting.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/indra/newview/skins/default/xui/fr/menu_url_agent.xml b/indra/newview/skins/default/xui/fr/menu_url_agent.xml index 746445d5c6..b006db24e0 100644 --- a/indra/newview/skins/default/xui/fr/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/fr/menu_url_agent.xml @@ -11,6 +11,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml index 058a299cb9..cefb4fe674 100644 --- a/indra/newview/skins/default/xui/fr/menu_viewer.xml +++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml @@ -236,6 +236,7 @@ + @@ -391,10 +392,11 @@ + - + diff --git a/indra/newview/skins/default/xui/fr/mime_types.xml b/indra/newview/skins/default/xui/fr/mime_types.xml new file mode 100644 index 0000000000..be36400ef5 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/mime_types.xml @@ -0,0 +1,228 @@ + + + + (Inconnu) + + + + Navigateur Web + + + Cet endroit proppose un navigateur Web + + + Afficher le contenu du navigateur web + + + + + Film + + + Cet endroit diffuse des films + + + Démarrer la lecture du film + + + + + Image + + + Ici, vous pouvez voir des images + + + Voir les images présentées ici + + + + + Son + + + Cet endroit proppose du contenu audio + + + Commencer à jouer l'audio + + + + + Aucun contenu + + + Aucun média + + + + + Flux en temps réel + + + + + Exemple de déclencheur + + + + + Médias pris en charge par LibVLC + + + + + - Aucun - + + + + + - Aucun - + + + + + Audio + + + + + Vidéo + + + + + Image + + + + + Film (QuickTime) + + + + + Son/Film Ogg + + + + + Document PDF + + + + + Document Postscript + + + + + Texte enrichi (RTF) + + + + + Langage d'intégration multimédia synchronisé (SMIL) + + + + + Site web (XHTML) + + + + + Audio (MIDI) + + + + + Audio (MP3) + + + + + Audio (AIFF) + + + + + Audio (WAV) + + + + + Image (BMP) + + + + + Image (GIF) + + + + + Image (JPEG) + + + + + Image (PNG) + + + + + Image (SVG) + + + + + Image (TIFF) + + + + + Site web + + + + + Texte + + + + + Film (MPEG) + + + + + Film (MP4) + + + + + Film + + + + + Film (QuickTime) + + + + + Film (Windows Media ASF) + + + + + Film (Windows Media WMV) + + + + + Film (AVI) + + + diff --git a/indra/newview/skins/default/xui/fr/mime_types_linux.xml b/indra/newview/skins/default/xui/fr/mime_types_linux.xml new file mode 100644 index 0000000000..5bdcd1e6f2 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/mime_types_linux.xml @@ -0,0 +1,218 @@ + + + + (Inconnu) + + + + Navigateur Web + + + Cet endroit proppose un navigateur Web + + + Afficher le contenu du navigateur web + + + + + Film + + + Cet endroit diffuse des films + + + Démarrer la lecture du film + + + + + Image + + + Ici, vous pouvez voir des images + + + Voir les images présentées ici + + + + + Audio + + + Cet endroit proppose du contenu audio + + + Commencer à jouer l'audio + + + + + Aucun contenu + + + Pas de média ici + + + + + Flux en temps réel + + + + + - Aucun - + + + + + - Aucun - + + + + + Audio + + + + + Vidéo + + + + + Image + + + + + Film (QuickTime) + + + + + Audio/Vidéo Ogg + + + + + Document PDF + + + + + Document Postscript + + + + + Texte enrichi (RTF) + + + + + Langage d'intégration multimédia synchronisé (SMIL) + + + + + Page Web (XHTML) + + + + + Audio (MIDI) + + + + + Audio (MP3) + + + + + Audio (AIFF) + + + + + Audio (WAV) + + + + + Image (BMP) + + + + + Image (GIF) + + + + + Image (JPEG) + + + + + Image (PNG) + + + + + Image (SVG) + + + + + Image (TIFF) + + + + + Page Web + + + + + Texte + + + + + Film (MPEG) + + + + + Film (MP4) + + + + + Film + + + + + Film (QuickTime) + + + + + Film (Windows Media ASF) + + + + + Film (Windows Media WMV) + + + + + Film (AVI) + + + diff --git a/indra/newview/skins/default/xui/fr/mime_types_mac.xml b/indra/newview/skins/default/xui/fr/mime_types_mac.xml new file mode 100644 index 0000000000..004018a943 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/mime_types_mac.xml @@ -0,0 +1,218 @@ + + + + (Inconnu) + + + + Navigateur Web + + + Cet endroit proppose un navigateur Web + + + Afficher le contenu du navigateur web + + + + + Film + + + Cet endroit diffuse des films + + + Démarrer la lecture du film + + + + + Image + + + Ici, vous pouvez voir des images + + + Voir les images présentées ici + + + + + Audio + + + Cet endroit proppose du contenu audio + + + Commencer à jouer l'audio + + + + + Aucun contenu + + + Aucun média ici + + + + + Flux en temps réel + + + + + - Aucun - + + + + + - Aucun - + + + + + Audio + + + + + Vidéo + + + + + Image + + + + + Film (QuickTime) + + + + + Audio/Vidéo Ogg + + + + + Document PDF + + + + + Document Postscript + + + + + Texte enrichi (RTF) + + + + + Langage d'intégration multimédia synchronisé (SMIL) + + + + + Page Web (XHTML) + + + + + Audio (MIDI) + + + + + Audio (MP3) + + + + + Audio (AIFF) + + + + + Audio (WAV) + + + + + Image (BMP) + + + + + Image (GIF) + + + + + Image (JPEG) + + + + + Image (PNG) + + + + + Image (SVG) + + + + + Image (TIFF) + + + + + Page Web + + + + + Texte + + + + + Film (MPEG) + + + + + Film (MP4) + + + + + Film + + + + + Film (QuickTime) + + + + + Film (Windows Media ASF) + + + + + Film (Windows Media WMV) + + + + + Film (AVI) + + + diff --git a/indra/newview/skins/default/xui/fr/panel_camera_preset_item.xml b/indra/newview/skins/default/xui/fr/panel_camera_preset_item.xml new file mode 100644 index 0000000000..5fb0b6d2d3 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_camera_preset_item.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/indra/newview/skins/default/xui/fr/panel_experience_log.xml b/indra/newview/skins/default/xui/fr/panel_experience_log.xml index ebb3f70dff..97d09f1427 100644 --- a/indra/newview/skins/default/xui/fr/panel_experience_log.xml +++ b/indra/newview/skins/default/xui/fr/panel_experience_log.xml @@ -13,7 +13,7 @@ - + diff --git a/indra/newview/skins/default/xui/fr/panel_fs_search_legacy_web.xml b/indra/newview/skins/default/xui/fr/panel_fs_search_legacy_web.xml new file mode 100644 index 0000000000..deac5d34f6 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_fs_search_legacy_web.xml @@ -0,0 +1,2 @@ + + diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml index 9cd45d3aae..63e5cdb708 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml @@ -12,6 +12,7 @@ (Redémarrage requis) + Accéder au contenu classé : diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml index a9b1d6e3b7..13bb250b19 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml @@ -68,7 +68,7 @@ - + diff --git a/indra/newview/skins/default/xui/fr/panel_presets_camera_pulldown.xml b/indra/newview/skins/default/xui/fr/panel_presets_camera_pulldown.xml new file mode 100644 index 0000000000..44b29cea2c --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_presets_camera_pulldown.xml @@ -0,0 +1,7 @@ + + + + Paramètres de la caméra + + + diff --git a/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml index f66aee3e23..f49b2e04b5 100644 --- a/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/fr/panel_prim_media_controls.xml @@ -9,9 +9,9 @@ - - - + + + @@ -27,7 +27,7 @@ - - + + diff --git a/indra/newview/skins/default/xui/fr/panel_profile_notes.xml b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml index ceabc57e0e..1efb56418d 100644 --- a/indra/newview/skins/default/xui/fr/panel_profile_notes.xml +++ b/indra/newview/skins/default/xui/fr/panel_profile_notes.xml @@ -1,6 +1,6 @@ - + diff --git a/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml index 7a78787082..1448cbd84a 100644 --- a/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/fr/panel_profile_secondlife.xml @@ -6,6 +6,9 @@ Déconnecté + + Inconnu + @@ -55,6 +58,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/panel_progress.xml b/indra/newview/skins/default/xui/fr/panel_progress.xml new file mode 100644 index 0000000000..fe3af2f92e --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_progress.xml @@ -0,0 +1,18 @@ + + + + + + + + + + [APP_NAME] utilise + + + + + + + + diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 86fef13dbe..b05c60718c 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -1701,6 +1701,14 @@ http://secondlife.com/support pour vous aider à résoudre ce problème. Une erreur est survenue lors de l’ouverture des annonces de la Place du marché. Si vous continuez de recevoir ce message, contactez l’assistance Second Life à http://support.secondlife.com pour obtenir de l’aide. + + + La connexion au listing de Marketplace a échoué. +Si vous continuez à recevoir ce message, veuillez contacter l'assistance de Second Life à l'adresse suivante http://support.secondlife.com + + + La connexion au listing de Marketplace a échoué. Raison :: [REASON] +Si vous continuez à recevoir ce message, veuillez contacter l'assistance de Second Life à l'adresse suivante http://support.secondlife.com Votre dossier Annonces de la Place du marché est vide. @@ -5270,6 +5278,9 @@ du rapport d'infraction danse8 + [day,datetime,utc]/[mthnum,datetime,utc]/[year,datetime,utc] + + [day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt] diff --git a/indra/newview/skins/default/xui/fr/widgets/density_ctrl.xml b/indra/newview/skins/default/xui/fr/widgets/density_ctrl.xml new file mode 100644 index 0000000000..a04cf5711a --- /dev/null +++ b/indra/newview/skins/default/xui/fr/widgets/density_ctrl.xml @@ -0,0 +1,21 @@ + + + + Période exponentielle + + + Facteur d'échelle exponentiel. + + + Période linéaire + + + Période constante + + + Hauteur maximale + + + Facteur d'anisotropie + + diff --git a/indra/newview/skins/default/xui/fr/widgets/flat_list_view.xml b/indra/newview/skins/default/xui/fr/widgets/flat_list_view.xml new file mode 100644 index 0000000000..e619b5d662 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/widgets/flat_list_view.xml @@ -0,0 +1,4 @@ + + + + diff --git a/indra/newview/skins/default/xui/fr/widgets/name_editor.xml b/indra/newview/skins/default/xui/fr/widgets/name_editor.xml new file mode 100644 index 0000000000..cc569fc05a --- /dev/null +++ b/indra/newview/skins/default/xui/fr/widgets/name_editor.xml @@ -0,0 +1,2 @@ + + diff --git a/indra/newview/skins/default/xui/fr/widgets/sun_moon_trackball.xml b/indra/newview/skins/default/xui/fr/widgets/sun_moon_trackball.xml new file mode 100644 index 0000000000..73968ff814 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/widgets/sun_moon_trackball.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/indra/newview/skins/default/xui/it/floater_map.xml b/indra/newview/skins/default/xui/it/floater_map.xml index b9a4f7103b..3a53c7769a 100644 --- a/indra/newview/skins/default/xui/it/floater_map.xml +++ b/indra/newview/skins/default/xui/it/floater_map.xml @@ -1,11 +1,5 @@ - - [AGENT][REGION](Fai doppio clic per aprire la mappa, premi il tasto Maiusc e trascina per la panoramica) - - - [REGION](Fai doppio clic per teleport, premi il tasto Maiusc e trascina per la panoramica) - Minimappa diff --git a/indra/newview/skins/default/xui/it/menu_attachment_self.xml b/indra/newview/skins/default/xui/it/menu_attachment_self.xml index 83dcb45ca2..36925a9251 100644 --- a/indra/newview/skins/default/xui/it/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/it/menu_attachment_self.xml @@ -9,16 +9,20 @@ - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/it/menu_avatar_self.xml b/indra/newview/skins/default/xui/it/menu_avatar_self.xml index 54423c1227..927d09e535 100644 --- a/indra/newview/skins/default/xui/it/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/it/menu_avatar_self.xml @@ -21,16 +21,20 @@ - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/it/panel_profile_picks.xml b/indra/newview/skins/default/xui/it/panel_profile_picks.xml index 41c19f4a4c..3cd3a71630 100644 --- a/indra/newview/skins/default/xui/it/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/it/panel_profile_picks.xml @@ -1,12 +1,18 @@ - - Comunica a tutti quali sono i tuoi posti preferiti in [GRID]. - - - - - Caricamento in corso... - + + + + Comunica a tutti quali sono i tuoi posti preferiti in [GRID]. + + + + + + + Caricamento in corso... + + + diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 87a3e8e851..f1cffee461 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -5125,6 +5125,9 @@ Segnala abuso Nuovo ambiente + [day,datetime,utc]/[mthnum,datetime,utc]/[year,datetime,utc] + + [day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt] diff --git a/indra/newview/skins/default/xui/ja/floater_map.xml b/indra/newview/skins/default/xui/ja/floater_map.xml index e4e01c23ce..d2f7d2ee86 100644 --- a/indra/newview/skins/default/xui/ja/floater_map.xml +++ b/indra/newview/skins/default/xui/ja/floater_map.xml @@ -1,11 +1,5 @@ - - [AGENT][REGION](ダブルクリックで地図を開く。Shift‐ドラッグで水平・垂直移動する) - - - [地域](ダブルクリックでテレポート。Shift‐ドラッグで水平・垂直移動する) - ミニマップ diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml index 9dc3e9ce54..bcf53ff8dc 100644 --- a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml @@ -9,11 +9,16 @@ - - - - - + + + + + + + + + + @@ -37,12 +42,11 @@ - - - - - - + + + + + diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml index 539a4d89bf..18f5d7a9b4 100644 --- a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml @@ -22,16 +22,20 @@ - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/ja/panel_profile_picks.xml b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml index 1e7226a8eb..ccb70b9a67 100644 --- a/indra/newview/skins/default/xui/ja/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/ja/panel_profile_picks.xml @@ -1,12 +1,18 @@ - - [GRID] のお気に入りの場所を紹介しましょう。 - - - - - ロード中... - + + + + [GRID] のお気に入りの場所を紹介しましょう。 + + + + + + + ロード中... + + + diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index e11e18b5e7..9520ef6430 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -5141,6 +5141,9 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ + [year,datetime,utc]/[mthnum,datetime,utc]/[day,datetime,utc] + + [year,datetime,slt]/[mthnum,datetime,slt]/[day,datetime,slt] diff --git a/indra/newview/skins/default/xui/pl/floater_map.xml b/indra/newview/skins/default/xui/pl/floater_map.xml index eabdeeb2c7..10d8964d12 100644 --- a/indra/newview/skins/default/xui/pl/floater_map.xml +++ b/indra/newview/skins/default/xui/pl/floater_map.xml @@ -1,10 +1,19 @@ - - [AGENT][REGION](Kliknij dwa razy by otworzyć Mapę, przeciągaj z shiftem by zmienić skalę) + + Cena: [PRICE]L$ ([PRICE_PER_SQM]L$/m²) - - [REGION](Kliknij dwa razy by teleportować, przeciągaj z shiftem by przesunąć) + + Obszar: [AREA]m² + + + Właściciel: [PARCEL_OWNER] + + + Podwójny klik by otworzyć mapę + + + Podwójny klik by teleportować Minimapa diff --git a/indra/newview/skins/default/xui/pl/floater_model_preview.xml b/indra/newview/skins/default/xui/pl/floater_model_preview.xml index f6ee346bb7..e3a335efe3 100644 --- a/indra/newview/skins/default/xui/pl/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/pl/floater_model_preview.xml @@ -131,6 +131,7 @@ Sześcian Heksagon Użytkownika + Bryła brzegowa Z pliku diff --git a/indra/newview/skins/default/xui/pl/menu_attachment_self.xml b/indra/newview/skins/default/xui/pl/menu_attachment_self.xml index 8cdc550655..843f866f07 100644 --- a/indra/newview/skins/default/xui/pl/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/pl/menu_attachment_self.xml @@ -10,11 +10,16 @@ - - - - - + + + + + + + + + + @@ -37,12 +42,11 @@ - - - - - - + + + + + diff --git a/indra/newview/skins/default/xui/pl/menu_avatar_self.xml b/indra/newview/skins/default/xui/pl/menu_avatar_self.xml index 98b207516c..d2b71ecf93 100644 --- a/indra/newview/skins/default/xui/pl/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/pl/menu_avatar_self.xml @@ -21,17 +21,21 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/menu_inventory.xml b/indra/newview/skins/default/xui/pl/menu_inventory.xml index a59f8c706b..c1fd1c0efb 100644 --- a/indra/newview/skins/default/xui/pl/menu_inventory.xml +++ b/indra/newview/skins/default/xui/pl/menu_inventory.xml @@ -86,6 +86,7 @@ + diff --git a/indra/newview/skins/default/xui/pl/menu_mini_map.xml b/indra/newview/skins/default/xui/pl/menu_mini_map.xml index 4c80d98ddf..ffee24fa35 100644 --- a/indra/newview/skins/default/xui/pl/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/pl/menu_mini_map.xml @@ -40,10 +40,10 @@ - - - - + + + + @@ -55,14 +55,17 @@ - - + + + + - - + + + diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index 9adc4d6674..8fddb23722 100644 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -337,6 +337,7 @@ + @@ -522,6 +523,9 @@ + + + diff --git a/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml index b8f4108c00..47ce41967a 100644 --- a/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/pl/panel_avatar_list_item.xml @@ -20,5 +20,5 @@ - + diff --git a/indra/newview/skins/default/xui/pl/panel_fs_search_legacy_events.xml b/indra/newview/skins/default/xui/pl/panel_fs_search_legacy_events.xml index f1ff847aef..c807fb0272 100644 --- a/indra/newview/skins/default/xui/pl/panel_fs_search_legacy_events.xml +++ b/indra/newview/skins/default/xui/pl/panel_fs_search_legacy_events.xml @@ -12,6 +12,7 @@ + diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml index d301e7ea49..353cd729e1 100644 --- a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml @@ -20,6 +20,7 @@ (Restart wymagany) + Chcę mieć dostęp do miejsc: diff --git a/indra/newview/skins/default/xui/pl/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/pl/panel_profile_secondlife.xml index 4179f8c189..59e836e021 100644 --- a/indra/newview/skins/default/xui/pl/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/pl/panel_profile_secondlife.xml @@ -1,5 +1,8 @@ + + Nieznane + @@ -48,6 +51,7 @@ + diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index e8b160abc6..e39b8eacd3 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -5047,6 +5047,9 @@ Raport o Nadużyciu Nowe otoczenie + [day,datetime,utc].[mthnum,datetime,utc].[year,datetime,utc] + + [day,datetime,slt].[mthnum,datetime,slt].[year,datetime,slt] @@ -5744,12 +5747,6 @@ Spróbuj załączyć ścieżkę do edytora w cytowaniu. (nieznana pozycja) - - [AGENT][REGION](Kliknij dwa razy by otworzyć Mapę, przeciągaj z shiftem by zmienić skalę) - - - [REGION](Kliknij dwa razy by teleportować, przeciągaj z shiftem by przesunąć) - [NAME] zderzył/a się z Tobą. diff --git a/indra/newview/skins/default/xui/pt/floater_map.xml b/indra/newview/skins/default/xui/pt/floater_map.xml index 8233f2a43f..0671161073 100644 --- a/indra/newview/skins/default/xui/pt/floater_map.xml +++ b/indra/newview/skins/default/xui/pt/floater_map.xml @@ -1,11 +1,5 @@ - - [REGION](Clique duas vezes para abrir o mapa, shift+arraste para a visão pan) - - - [REGION](Clique duas vezes para teletransportar, shift+arraste para a visão pan) - Mini Mapa diff --git a/indra/newview/skins/default/xui/pt/panel_profile_picks.xml b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml index e7d28706bd..6c19c9be81 100644 --- a/indra/newview/skins/default/xui/pt/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/pt/panel_profile_picks.xml @@ -1,12 +1,18 @@ - - Conte a todos sobre os seu lugares favoritos no [GRID]. - - - - - Carregando... - + + + + Conte a todos sobre os seu lugares favoritos no [GRID]. + + + + + + + Carregando... + + + diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 65579d994a..339f08788f 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -4827,6 +4827,9 @@ Denunciar abuso dança8 + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] diff --git a/indra/newview/skins/default/xui/ru/floater_map.xml b/indra/newview/skins/default/xui/ru/floater_map.xml index 0ce846b9ce..0c500e441b 100644 --- a/indra/newview/skins/default/xui/ru/floater_map.xml +++ b/indra/newview/skins/default/xui/ru/floater_map.xml @@ -1,11 +1,5 @@ - - [AGENT][REGION](Двойное нажатие, чтобы открыть карту, переместить мышку с Shift для изменения масштаба) - - - [REGION](Двойное нажатие, чтобы телепортироваться, переместить мышку с Shift для изменения масштаба) - Миникарта diff --git a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml index 47846fb01e..bbc2eb423f 100644 --- a/indra/newview/skins/default/xui/ru/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/ru/menu_attachment_self.xml @@ -10,11 +10,16 @@ - - - - - + + + + + + + + + + @@ -38,12 +43,11 @@ - - - - - - + + + + + diff --git a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml index 9434b38731..d4d69dbd97 100644 --- a/indra/newview/skins/default/xui/ru/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/ru/menu_avatar_self.xml @@ -22,17 +22,21 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/ru/menu_inventory.xml b/indra/newview/skins/default/xui/ru/menu_inventory.xml index 8e35680924..4cd4f6c7fd 100644 --- a/indra/newview/skins/default/xui/ru/menu_inventory.xml +++ b/indra/newview/skins/default/xui/ru/menu_inventory.xml @@ -86,6 +86,7 @@ + diff --git a/indra/newview/skins/default/xui/ru/panel_fs_search_legacy_events.xml b/indra/newview/skins/default/xui/ru/panel_fs_search_legacy_events.xml index 2c12cb0571..b7a4a9736b 100644 --- a/indra/newview/skins/default/xui/ru/panel_fs_search_legacy_events.xml +++ b/indra/newview/skins/default/xui/ru/panel_fs_search_legacy_events.xml @@ -12,6 +12,7 @@ + diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml index 86c87ed6cd..d49d03935f 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_general.xml @@ -20,6 +20,7 @@ (Необходим перезапуск) + Получить доступ к местам с рейтингом: diff --git a/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml index f7e0cc0c31..a17d3368b7 100644 --- a/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml +++ b/indra/newview/skins/default/xui/ru/panel_profile_secondlife.xml @@ -2,6 +2,7 @@ В сети Не в сети + Неизвестно @@ -49,6 +50,7 @@ + diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index c58053a6f1..dd85cc6f2d 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -5274,6 +5274,9 @@ https://www.firestormviewer.org/support за помощь в решении эт танец8 + [day,datetime,utc].[mthnum,datetime,utc].[year,datetime,utc] + + [day,datetime,slt].[mthnum,datetime,slt].[year,datetime,slt] diff --git a/indra/newview/skins/default/xui/tr/floater_map.xml b/indra/newview/skins/default/xui/tr/floater_map.xml index 7d6c314f04..ff8579a17f 100644 --- a/indra/newview/skins/default/xui/tr/floater_map.xml +++ b/indra/newview/skins/default/xui/tr/floater_map.xml @@ -1,11 +1,5 @@ - - [REGION](Haritayı açmak için çift tıkla, yatay hareket için shift çek) - - - [REGION](Işınlamak için çift tıkla, yatay hareket için shift çek) - Mini-harita diff --git a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml index fd166ddd68..a5c25f1e0b 100644 --- a/indra/newview/skins/default/xui/tr/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/tr/menu_attachment_self.xml @@ -5,15 +5,19 @@ - - - - - - - - - + + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/tr/panel_profile_picks.xml b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml index c99c17a672..093fe7312f 100644 --- a/indra/newview/skins/default/xui/tr/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/tr/panel_profile_picks.xml @@ -1,12 +1,18 @@ - - [GRID]'ta favori yerlerinizi herkese anlatın! - - - - - Yükleniyor... - + + + + [GRID]'ta favori yerlerinizi herkese anlatın! + + + + + + + Yükleniyor... + + + diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index fa40bf9980..775611a1aa 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -5027,6 +5027,9 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. dans8 + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] diff --git a/indra/newview/skins/default/xui/zh/floater_map.xml b/indra/newview/skins/default/xui/zh/floater_map.xml index 8a030b3b3f..8c4aceee09 100644 --- a/indra/newview/skins/default/xui/zh/floater_map.xml +++ b/indra/newview/skins/default/xui/zh/floater_map.xml @@ -1,11 +1,5 @@ - - [REGION](雙擊以開啟地圖,按下 shift 鍵拖曳來平移) - - - [REGION](雙擊以瞬間傳送,按下 shift 鍵拖曳來平移) - 迷你地圖 diff --git a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml index 040ec94aad..eb0d922d05 100644 --- a/indra/newview/skins/default/xui/zh/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/zh/menu_attachment_self.xml @@ -5,15 +5,18 @@ - - - - - - - - - + + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/zh/panel_profile_picks.xml b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml index 974e722d8d..b215df5e69 100644 --- a/indra/newview/skins/default/xui/zh/panel_profile_picks.xml +++ b/indra/newview/skins/default/xui/zh/panel_profile_picks.xml @@ -1,12 +1,18 @@ - - 告訴大家你在[GRID]中最愛的去處。 - - - - - 載入中… - + + + + 告訴大家你在[GRID]中最愛的去處。 + + + + + + + 載入中… + + + diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index d5bb247a0b..bde712a8b1 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -4941,6 +4941,9 @@ http://secondlife.com/support 求助解決問題。 跳舞8 + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] diff --git a/indra/newview/skins/starlight/textures/textures.xml b/indra/newview/skins/starlight/textures/textures.xml index 72e48bdd63..47b2314ab1 100755 --- a/indra/newview/skins/starlight/textures/textures.xml +++ b/indra/newview/skins/starlight/textures/textures.xml @@ -134,7 +134,7 @@ with the same filename but different name - + diff --git a/indra/newview/skins/starlight/xui/en/floater_map.xml b/indra/newview/skins/starlight/xui/en/floater_map.xml index b7ba4ccca7..6b49bb10b0 100644 --- a/indra/newview/skins/starlight/xui/en/floater_map.xml +++ b/indra/newview/skins/starlight/xui/en/floater_map.xml @@ -22,11 +22,35 @@ - [AGENT][REGION] (Double-click to open Map, shift-drag to pan) + [AGENT][PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG] + + + [PARCEL_NAME] + + + Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + + + Area: [AREA]m² + + + Owner: [PARCEL_OWNER] + + + Region: [REGION_NAME] - [REGION] (Double-click to teleport, shift-drag to pan) + name="ToolTipHintMsg"> + Double-click to open map + + + Double-click to teleport MINIMAP diff --git a/indra/newview/skins/starlightcui/textures/textures.xml b/indra/newview/skins/starlightcui/textures/textures.xml index 91ab1a6968..b20606cb1e 100755 --- a/indra/newview/skins/starlightcui/textures/textures.xml +++ b/indra/newview/skins/starlightcui/textures/textures.xml @@ -134,7 +134,7 @@ with the same filename but different name - + diff --git a/indra/newview/skins/starlightcui/themes/custom_dark/textures/toolbar_icons/environment.png b/indra/newview/skins/starlightcui/themes/custom_dark/textures/toolbar_icons/environments.png similarity index 100% rename from indra/newview/skins/starlightcui/themes/custom_dark/textures/toolbar_icons/environment.png rename to indra/newview/skins/starlightcui/themes/custom_dark/textures/toolbar_icons/environments.png diff --git a/indra/newview/skins/starlightcui/themes/custom_light/textures/toolbar_icons/environment.png b/indra/newview/skins/starlightcui/themes/custom_light/textures/toolbar_icons/environments.png similarity index 100% rename from indra/newview/skins/starlightcui/themes/custom_light/textures/toolbar_icons/environment.png rename to indra/newview/skins/starlightcui/themes/custom_light/textures/toolbar_icons/environments.png diff --git a/indra/newview/skins/starlightcui/xui/en/floater_map.xml b/indra/newview/skins/starlightcui/xui/en/floater_map.xml index 4fcb355201..0046276ed8 100644 --- a/indra/newview/skins/starlightcui/xui/en/floater_map.xml +++ b/indra/newview/skins/starlightcui/xui/en/floater_map.xml @@ -21,11 +21,35 @@ - [AGENT][REGION] (Double-click to open Map, shift-drag to pan) + [AGENT][PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG] + + + [PARCEL_NAME] + + + Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + + + Area: [AREA]m² + + + Owner: [PARCEL_OWNER] + + + Region: [REGION_NAME] - [REGION] (Double-click to teleport, shift-drag to pan) + name="ToolTipHintMsg"> + Double-click to open map + + + Double-click to teleport MINIMAP diff --git a/indra/newview/skins/vintage/colors.xml b/indra/newview/skins/vintage/colors.xml index 9040e40f01..b31a81fd6a 100644 --- a/indra/newview/skins/vintage/colors.xml +++ b/indra/newview/skins/vintage/colors.xml @@ -253,6 +253,10 @@ + + diff --git a/indra/newview/skins/vintage/xui/en/floater_map.xml b/indra/newview/skins/vintage/xui/en/floater_map.xml index 00bebc1839..9add735daf 100644 --- a/indra/newview/skins/vintage/xui/en/floater_map.xml +++ b/indra/newview/skins/vintage/xui/en/floater_map.xml @@ -21,14 +21,38 @@ - [AGENT][REGION](Double-click to open Map, shift-drag to pan) + [AGENT][PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG] + + + [PARCEL_NAME] + + + Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + + + Area: [AREA]m² + + + Owner: [PARCEL_OWNER] + + + Region: [REGION_NAME] - [REGION](Double-click to teleport, shift-drag to pan) + name="ToolTipHintMsg"> + Double-click to open map + + + Double-click to teleport - MINIMAP + Mini-map diff --git a/indra/newview/skins/vintage/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/vintage/xui/en/panel_profile_secondlife.xml index 8a82fbe3d4..8f573d24c9 100644 --- a/indra/newview/skins/vintage/xui/en/panel_profile_secondlife.xml +++ b/indra/newview/skins/vintage/xui/en/panel_profile_secondlife.xml @@ -16,6 +16,10 @@ name="status_offline"> Offline + + Unknown + [ACCTTYPE] @@ -227,15 +231,15 @@ auto_resize="false" user_resize="false"> - + show_caption="false" + layout="topleft" /> + + + + Nieznane + @@ -50,6 +53,7 @@ Urodziny: [REG_DATE] + diff --git a/indra/newview/skins/vintage/xui/ru/panel_profile_secondlife.xml b/indra/newview/skins/vintage/xui/ru/panel_profile_secondlife.xml index ddb470031f..4ff4ca0c89 100644 --- a/indra/newview/skins/vintage/xui/ru/panel_profile_secondlife.xml +++ b/indra/newview/skins/vintage/xui/ru/panel_profile_secondlife.xml @@ -2,6 +2,7 @@ В сети Не в сети + Неизвестно @@ -54,6 +55,7 @@ + diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f285eebdef..7ed172a8ba 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -684,6 +684,7 @@ class WindowsManifest(ViewerManifest): self.path(src="licenses-win32.txt", dst="licenses.txt") self.path("featuretable.txt") + self.path("cube.dae") with self.prefix(src=pkgdir): self.path("ca-bundle.crt") @@ -1382,6 +1383,8 @@ class DarwinManifest(ViewerManifest): self.path("licenses-mac.txt", dst="licenses.txt") self.path("featuretable_mac.txt") + self.path("cube.dae") + self.path("VivoxAUP.txt") self.path("LGPL-license.txt") with self.prefix(src=pkgdir,dst=""): @@ -2003,6 +2006,7 @@ class LinuxManifest(ViewerManifest): # print("Skipping llcommon.so (assuming llcommon was linked statically))" self.path("featuretable_linux.txt") + self.path("cube.dae") with self.prefix(src=pkgdir, dst="bin"): self.path("ca-bundle.crt") diff --git a/indra/newview/vjlocalmeshimportdae.cpp b/indra/newview/vjlocalmeshimportdae.cpp index f3c6680044..bbd97a2b8c 100644 --- a/indra/newview/vjlocalmeshimportdae.cpp +++ b/indra/newview/vjlocalmeshimportdae.cpp @@ -1009,7 +1009,7 @@ void LLLocalMeshImportDAE::processSkeletonJoint(domNode* current_node, std::map< workingTransform.mMatrix[i][j] = domArray[i + j * 4]; } } - LLVector3 trans = workingTransform.getTranslation(); + // LLVector3 trans = workingTransform.getTranslation(); joint_transforms[node_name] = workingTransform; } } diff --git a/scripts/configure_firestorm.sh b/scripts/configure_firestorm.sh index 0f98179ee3..5225ace8aa 100755 --- a/scripts/configure_firestorm.sh +++ b/scripts/configure_firestorm.sh @@ -363,6 +363,7 @@ then then export AUTOBUILD_EXEC=`which autobuild` fi + # load autobuild provided shell functions and variables eval "$("$AUTOBUILD_EXEC" source_environment)" # vsvars is needed for determing path to VS runtime redist files in Copy3rdPartyLibs.cmake @@ -540,6 +541,8 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then mkdir -p "logs" fi + CMAKE_ARCH="" + if [ $TARGET_PLATFORM == "darwin" ] ; then TARGET="Xcode" elif [ \( $TARGET_PLATFORM == "linux" \) ] ; then @@ -556,6 +559,10 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then fi elif [ \( $TARGET_PLATFORM == "windows" \) ] ; then TARGET="${AUTOBUILD_WIN_CMAKE_GEN}" + if [ $AUTOBUILD_ADDRSIZE == 32 ] + then + CMAKE_ARCH="-A Win32" + fi UNATTENDED="-DUNATTENDED=ON" fi @@ -579,7 +586,7 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then fi fi - cmake -G "$TARGET" ../indra $CHANNEL ${GITHASH} $FMODSTUDIO $OPENAL $KDU $OPENSIM $SINGLEGRID $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TRACY_PROFILER $TESTBUILD $PACKAGE \ + cmake -G "$TARGET" $CMAKE_ARCH ../indra $CHANNEL ${GITHASH} $FMODSTUDIO $OPENAL $KDU $OPENSIM $SINGLEGRID $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TRACY_PROFILER $TESTBUILD $PACKAGE \ $UNATTENDED -DLL_TESTS:BOOL=OFF -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DCMAKE_BUILD_TYPE:STRING=$BTYPE $CACHE_OPT \ $CRASH_REPORTING -DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" $LL_ARGS_PASSTHRU ${VSCODE_FLAGS:-} | tee $LOG @@ -601,6 +608,7 @@ if [ $WANTS_BUILD -eq $TRUE ] ; then elif [ $TARGET_PLATFORM == "linux" ] ; then if [ $JOBS == "0" ] ; then JOBS=`cat /proc/cpuinfo | grep processor | wc -l` + echo $JOBS fi if [ $WANTS_NINJA -eq $TRUE ] ; then ninja -j $JOBS | tee -a $LOG diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py index e7b86a88fa..4a0773951e 100644 --- a/scripts/content_tools/anim_tool.py +++ b/scripts/content_tools/anim_tool.py @@ -611,6 +611,7 @@ def main(*argv): parser = argparse.ArgumentParser(description="process SL animations") parser.add_argument("--verbose", help="verbose flag", action="store_true") parser.add_argument("--dump", help="dump to stdout", action="store_true") + parser.add_argument("--use_aliases", help="use alias names for bones", action="store_true") parser.add_argument("--rot", help="specify sequence of rotations", type=float_triple, nargs="+") parser.add_argument("--rand_pos", help="request NUM random positions (default %(default)s)", metavar="NUM", type=int, default=2) @@ -637,6 +638,7 @@ def main(*argv): parser.add_argument("--no_hud", help="omit hud joints from list of attachments", action="store_true") parser.add_argument("--base_priority", help="set base priority", type=int) parser.add_argument("--joint_priority", help="set joint priority for all joints", type=int) + parser.add_argument("--force_joints", help="don't check validity of joint names", action="store_true") parser.add_argument("infilename", help="name of a .anim file to input") parser.add_argument("outfilename", nargs="?", help="name of a .anim file to output") args = parser.parse_args(argv) @@ -661,7 +663,12 @@ def main(*argv): if lad_tree is None: raise Error("failed to parse " + args.lad) if args.joints: - joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.force_joints: + joints = args.joints + else: + joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.use_aliases: + joints = map(lambda name: "avatar_" + name, joints) if args.verbose: print("joints resolved to",joints) for name in joints: diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py index 449ecd6a6c..696e4e2923 100644 --- a/scripts/content_tools/skel_tool.py +++ b/scripts/content_tools/skel_tool.py @@ -72,6 +72,22 @@ def check_symmetry(name, field, vec1, vec2): if vec1[2] != vec2[2]: print(name,field,"z match fail") +def enforce_alias_rules(tree, element, fix=False): + if element.tag != "bone": + return + alias_lis = [] + aliases = element.get("aliases") + if aliases: + alias_lis = aliases.split(" ") + name = element.get("name") + if name: + std_alias = "avatar_" + name + if not std_alias in alias_lis: + print "missing expected alias",name,std_alias + for alias in alias_lis: + if alias.startswith("avatar_") and alias != std_alias: + print "invalid avatar_ alias",name,alias + def enforce_symmetry(tree, element, field, fix=False): name = element.get("name") if not name: @@ -209,6 +225,7 @@ def validate_skel_tree(tree, ogtree, reftree, fix=False): unfixable += 1 fix_name(element) + enforce_alias_rules(tree, element, fix) enforce_precision_rules(element) for field in ["pos","pivot"]: enforce_symmetry(tree, element, field, fix)
0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23