Ansariel 2022-10-21 12:34:53 +02:00
commit 8b0d341aca
170 changed files with 3279 additions and 1914 deletions

View File

@ -1876,7 +1876,7 @@
<key>libpng</key>
<map>
<key>copyright</key>
<string>Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson</string>
<string>Copyright (c) 1995-2022 The PNG Reference Library Authors.</string>
<key>description</key>
<string>PNG Reference library</string>
<key>license</key>
@ -1904,9 +1904,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>83ae55031f81dace9dcf688cc5510010</string>
<string>134089ec8c1eead9436b69c326790fc0</string>
<key>url</key>
<string>http://3p.firestormviewer.org/libpng-1.6.8.180841558-linux64-180841558.tar.bz2</string>
<string>http://3p.firestormviewer.org/libpng-1.6.38.222890126-linux64-222890126.tar.bz2</string>
</map>
<key>name</key>
<string>linux64</string>

View File

@ -407,6 +407,7 @@ Cinder Roxley
STORM-2136
STORM-2144
SL-3404
SL-17634
Clara Young
Coaldust Numbers
VWR-1095
@ -1129,6 +1130,7 @@ Nicky Dasmijn
SL-14541
SL-16438
SL-17218
SL-17585
Nicky Perian
OPEN-1
STORM-1087

View File

@ -954,6 +954,9 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
// initialize mJointAliasMap
getJointAliases();
// avatar_lad.xml : <skeleton>
if( !loadSkeletonNode() )
{
@ -1074,7 +1077,6 @@ BOOL LLAvatarAppearance::loadAvatar()
return FALSE;
}
}
return TRUE;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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<LLUUID> mDecodeQueue;
LLPointer<LLVorbisDecodeState> mCurrentDecodep;
void startMoreDecodes();
void enqueueFinishAudio(const LLUUID &decode_id, LLPointer<LLVorbisDecodeState>& decode_state);
void checkDecodesFinished();
protected:
std::deque<LLUUID> mDecodeQueue;
std::map<LLUUID, LLPointer<LLVorbisDecodeState>> 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<LLVorbisDecodeState> 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<LLVorbisDecodeState> 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<LLVorbisDecodeState>(NULL);
try
{
main_queue->postTo(
general_queue,
[decode_id]() // Work done on general queue
{
LLPointer<LLVorbisDecodeState> 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<LLVorbisDecodeState> 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);
// <FS:Ansariel> Sound cache
//d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
d_path = gDirUtilp->getExpandedFilename(LL_PATH_FS_SOUND_CACHE,uuid_str) + ".dsf";
// </FS:Ansariel>
// 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<LLVorbisDecodeState> beginDecodingAndWritingAudio(const LLUUID &decode_id)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
LL_DEBUGS() << "Decoding " << decode_id << " from audio queue!" << LL_ENDL;
// <FS:Ansariel> 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";
// </FS:Ansariel>
LLPointer<LLVorbisDecodeState> 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<LLVorbisDecodeState>& 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<LLVorbisDecodeState>& 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<LLVorbisDecodeState> 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)
{
// <FS:ND> 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;
// </FS:ND>

View File

@ -32,24 +32,23 @@
#include "llassettype.h"
#include "llframetimer.h"
#include "llsingleton.h"
template<class T> class LLPointer;
class LLVorbisDecodeState;
class LLAudioDecodeMgr
class LLAudioDecodeMgr : public LLSingleton<LLAudioDecodeMgr>
{
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

View File

@ -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;
// </FS>
// 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;
// <FS:ND> 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";
// </FS:Ansariel>
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);
}
// </FS:Ansariel>
@ -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)
{

View File

@ -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
// <FS:Ansariel> 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
// </FS:Ansariel>
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<LLAudioChannel*, LL_MAX_AUDIO_CHANNELS> 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<LLAudioBuffer*, LL_MAX_AUDIO_BUFFERS> 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
};

View File

@ -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<char*>(app_title.c_str()))) == FMOD_OK)
(result = mSystem->init(LL_MAX_AUDIO_CHANNELS + EXTRA_SOUND_CHANNELS, fmod_flags, const_cast<char*>(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"))
{

View File

@ -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();

View File

@ -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))
{

View File

@ -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();

View File

@ -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;
}
//-----------------------------------------------------------------------------

View File

@ -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

View File

@ -267,6 +267,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)
# <FS:Beq/> Tracy Profiler support
list(APPEND llcommon_SOURCE_FILES llprofiler.cpp)
@ -352,12 +357,6 @@ target_link_libraries(
${TRACY_LIBRARY}
)
if (DARWIN)
include(CMakeFindFrameworks)
find_library(CARBON_LIBRARY Carbon)
target_link_libraries(llcommon ${CARBON_LIBRARY})
endif (DARWIN)
add_dependencies(llcommon stage_third_party_libs)
if (LL_TESTS)

View File

@ -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
{

View File

@ -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)

View File

@ -64,6 +64,7 @@ using namespace llsd;
# include <psapi.h> // GetPerformanceInfo() et al.
# include <VersionHelpers.h>
#elif LL_DARWIN
# include "llsys_objc.h"
# include <errno.h>
# include <sys/sysctl.h>
# include <sys/utsname.h>
@ -74,12 +75,6 @@ using namespace llsd;
# include <mach/mach_host.h>
# include <mach/task.h>
# include <mach/task_info.h>
// 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 <errno.h>
# include <sys/utsname.h>
@ -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

View File

@ -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

View File

@ -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 <AppKit/AppKit.h>
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;
}

View File

@ -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)

View File

@ -22,8 +22,10 @@
namespace LL
{
class ThreadPool
class ThreadPool: public LLInstanceTracker<ThreadPool, std::string>
{
private:
using super = LLInstanceTracker<ThreadPool, std::string>;
public:
/**
* Pass ThreadPool a string name. This can be used to look up the

View File

@ -403,7 +403,7 @@ namespace LL
[result = std::forward<CALLABLE>(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();

View File

@ -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. Lets 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. Lets 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;
// <FS:Beq> Extra accounting to track the retention of static assets
//std::vector<bool> file_removed;
std::vector<S32> file_removed;
int keep{0};
int del{0};
int skip{0};
// </FS:Beq>
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;
// <FS> Make sure static assets are not eliminated
S32 action{ should_remove ? 0 : 1 };
if (should_remove)
{
action = "DELETE:";
// <FS:Beq> 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=" <<uuid_as_string<< LL_ENDL;
if (std::find(mSkipList.begin(), mSkipList.end(), uuid_as_string) != mSkipList.end())
{
// this is one of our protected items so no purging
action = "STATIC:";
skip++;
should_remove = false;
action = 2;
updateFileAccessTime(entry.second.second); // force these to the front of the list next time so that purge size works
}
else
{
del++; // Extra accounting to track the retention of static assets
// </FS:Beq>
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++; // <FS:Beq/> Extra accounting to track the retention of static assets
action = " KEEP:";
}
// </FS>
if (mEnableCacheDebugInfo)
{
// <FS> 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<std::chrono::milliseconds>(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];
// <FS> 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;
}
// </FS>
// 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<std::chrono::milliseconds>(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; // <FS:Beq/> Extra accounting to track the retention of static assets

View File

@ -50,52 +50,59 @@ extern float gOctreeMinSize;
#define LL_OCTREE_MAX_CAPACITY 128
#endif*/
template <class T> 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<T, LLPointer<T>> assumes ownership of inserted elements and
// deletes elements removed from the tree.
// LLOctreeNode<T, T*> 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 T, typename T_PTR> class LLOctreeNode;
template <class T>
template <class T, typename T_PTR>
class LLOctreeListener: public LLTreeListener<T>
{
public:
typedef LLTreeListener<T> BaseType;
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeNode<T, T_PTR> 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 <class T>
template <class T, typename T_PTR>
class LLOctreeTraveler
{
public:
virtual void traverse(const LLOctreeNode<T>* node);
virtual void visit(const LLOctreeNode<T>* branch) = 0;
virtual void traverse(const LLOctreeNode<T, T_PTR>* node);
virtual void visit(const LLOctreeNode<T, T_PTR>* branch) = 0;
};
template <class T>
class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T>
template <class T, typename T_PTR>
class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T, T_PTR>
{
public:
virtual void traverse(const LLOctreeNode<T>* node) override;
virtual void traverse(const LLOctreeNode<T, T_PTR>* node) override;
};
template <class T>
template <class T, typename T_PTR>
class alignas(16) LLOctreeNode : public LLTreeNode<T>
{
LL_ALIGN_NEW
public:
typedef LLOctreeTraveler<T> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
typedef std::vector< LLPointer<T> > element_list; // note: don't remove the whitespace between "> >"
typedef LLPointer<T>* element_iter;
typedef const LLPointer<T>* const_element_iter;
typedef LLOctreeTraveler<T, T_PTR> oct_traveler;
typedef LLTreeTraveler<T> tree_traveler;
typedef std::vector<T_PTR> element_list;
typedef typename element_list::iterator element_iter;
typedef typename element_list::const_iterator const_element_iter;
typedef typename std::vector<LLTreeListener<T>*>::iterator tree_listener_iter;
typedef LLOctreeNode<T>** child_list;
typedef LLOctreeNode<T>** child_iter;
typedef LLOctreeNode<T, T_PTR>** child_list;
typedef LLOctreeNode<T, T_PTR>** child_iter;
typedef LLTreeNode<T> BaseType;
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeListener<T> oct_listener;
typedef LLTreeNode<T> BaseType;
typedef LLOctreeNode<T, T_PTR> oct_node;
typedef LLOctreeListener<T, T_PTR> 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<T>* 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<T>* 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<T>*) 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<T>* 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<T>::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:
// </FS:ND>
{
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<T>(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<T>* child = (LLOctreeNode<T>*) getChild(i);
oct_node* child = (oct_node*) getChild(i);
child->removeByAddress(data);
}
}
@ -709,22 +698,20 @@ protected:
oct_node* mParent;
U8 mOctant;
LLOctreeNode<T>* 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 T>
class LLOctreeRoot : public LLOctreeNode<T>
template <class T, typename T_PTR>
class LLOctreeRoot : public LLOctreeNode<T, T_PTR>
{
public:
typedef LLOctreeNode<T> BaseType;
typedef LLOctreeNode<T> oct_node;
typedef LLOctreeNode<T, T_PTR> BaseType;
typedef LLOctreeNode<T, T_PTR> oct_node;
LLOctreeRoot(const LLVector4a& center,
const LLVector4a& size,
@ -805,7 +792,7 @@ public:
oct_node* node = this->getNodeAt(data);
if (node == this)
{
LLOctreeNode<T>::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<T>::pushCenter(center, size, data);
oct_node::pushCenter(center, size, data);
this->setCenter(center);
size.mul(2.f);
this->setSize(size);
this->updateMinMax();
}
LLOctreeNode<T>::insert(data);
oct_node::insert(data);
}
else
{
@ -843,7 +830,7 @@ public:
//expand this node
LLVector4a newcenter(center);
LLOctreeNode<T>::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<T>* newnode = new LLOctreeNode<T>(center, size, this);
oct_node* newnode = new oct_node(center, size, this);
for (U32 i = 0; i < this->getChildCount(); i++)
{
LLOctreeNode<T>* child = this->getChild(i);
oct_node* child = this->getChild(i);
newnode->addChild(child);
}
@ -883,8 +870,8 @@ public:
//========================
// LLOctreeTraveler
//========================
template <class T>
void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
template <class T, typename T_PTR>
void LLOctreeTraveler<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)
{
node->accept(this);
for (U32 i = 0; i < node->getChildCount(); i++)
@ -893,8 +880,8 @@ void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
}
}
template <class T>
void LLOctreeTravelerDepthFirst<T>::traverse(const LLOctreeNode<T>* node)
template <class T, typename T_PTR>
void LLOctreeTravelerDepthFirst<T, T_PTR>::traverse(const LLOctreeNode<T, T_PTR>* node)
{
for (U32 i = 0; i < node->getChildCount(); i++)
{

View File

@ -388,7 +388,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons
}
}
class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle>
class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst<LLVolumeTriangle, LLVolumeTriangle*>
{
public:
const LLVolumeFace* mFace;
@ -398,7 +398,7 @@ public:
mFace = face;
}
virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch)
virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* 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<LLVolumeTriangle>::const_element_iter iter =
branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
for (LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter)
{ //for each triangle in node
//stretch by triangles in node
@ -1642,9 +1641,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
//genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f);
genNGon(params, llfloor(MIN_DETAIL_FACES * detail));
F32 t = 0.f;
F32 tStep = 1.0f / mPath.size();
F32 toggle = 0.5f;
for (S32 i=0;i<(S32)mPath.size();i++)
{
@ -1653,7 +1649,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
toggle = -0.5f;
else
toggle = 0.5f;
t += tStep;
}
}
@ -2465,6 +2460,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)
@ -2480,8 +2482,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];
}
@ -3902,8 +3903,8 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &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];
@ -3921,7 +3922,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
continue;
}
if (nIndex >= (S32) count/3) {
if (nIndex >= (S32)tri_count) {
continue;
}
//get neighbor vertices
@ -4213,13 +4214,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;
@ -4774,6 +4775,7 @@ LLVolumeFace::LLVolumeFace() :
#endif
mWeightsScrubbed(FALSE),
mOctree(NULL),
mOctreeTriangles(NULL),
mOptimized(FALSE)
{
mExtents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*3);
@ -4803,8 +4805,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;
@ -4944,8 +4947,7 @@ void LLVolumeFace::freeData()
mJustWeights = NULL;
#endif
delete mOctree;
mOctree = NULL;
destroyOctree();
}
BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build)
@ -4953,8 +4955,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 ;
@ -5677,23 +5678,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<LLVolumeTriangle>(center, size, NULL);
mOctree = new LLOctreeRoot<LLVolumeTriangle, LLVolumeTriangle*>(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<LLVolumeTriangle> 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;
@ -5701,9 +5707,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;
@ -5728,7 +5734,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;
@ -5754,6 +5760,19 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe
}
}
void LLVolumeFace::destroyOctree()
{
delete mOctree;
mOctree = NULL;
delete[] mOctreeTriangles;
mOctreeTriangles = NULL;
}
const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* LLVolumeFace::getOctree() const
{
return mOctree;
}
void LLVolumeFace::swapData(LLVolumeFace& rhs)
{
@ -6625,6 +6644,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)
{

View File

@ -35,7 +35,8 @@ class LLVolumeParams;
class LLProfile;
class LLPath;
template <class T> class LLOctreeNode;
template<class T> class LLPointer;
template <class T, typename T_PTR> 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<LLVolumeTriangle, LLVolumeTriangle*>* 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<LLVolumeTriangle>* mOctree;
//whether or not face has been cache optimized
BOOL mOptimized;
private:
LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* 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);

View File

@ -75,7 +75,7 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c
}
LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node)
LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
node->addListener(this);
}
@ -85,13 +85,12 @@ LLVolumeOctreeListener::~LLVolumeOctreeListener()
}
void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
LLOctreeNode<LLVolumeTriangle>* child)
void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent,
LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* 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<LLVolumeTriangle>* node)
void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0);
@ -122,9 +121,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode<LLVolumeTriangle>
}
}
void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle>* node)
void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node)
{
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter =
for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::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<LLVolumeTriangle>* branch)
void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch)
{
LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0);
@ -256,7 +255,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
//children fit, check data
for (LLOctreeNode<LLVolumeTriangle>::const_element_iter iter = branch->getDataBegin();
for (typename LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>::const_element_iter iter = branch->getDataBegin();
iter != branch->getDataEnd(); ++iter)
{
const LLVolumeTriangle* tri = *iter;
@ -273,4 +272,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode<LLVolumeTriangle>* branch)
}
}

View File

@ -77,11 +77,11 @@ public:
};
class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle>
class alignas(16) LLVolumeOctreeListener : public LLOctreeListener<LLVolumeTriangle, LLVolumeTriangle*>
{
LL_ALIGN_NEW
public:
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle>* node);
LLVolumeOctreeListener(LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
~LLVolumeOctreeListener();
LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs)
@ -96,11 +96,9 @@ public:
}
//LISTENER FUNCTIONS
virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle>* parent,
LLOctreeNode<LLVolumeTriangle>* child);
virtual void handleChildAddition(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child);
virtual void handleStateChange(const LLTreeNode<LLVolumeTriangle>* node) { }
virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle>* parent,
const LLOctreeNode<LLVolumeTriangle>* child) { }
virtual void handleChildRemoval(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* parent, const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* child) { }
virtual void handleInsertion(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleRemoval(const LLTreeNode<LLVolumeTriangle>* node, LLVolumeTriangle* tri) { }
virtual void handleDestruction(const LLTreeNode<LLVolumeTriangle>* 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<LLVolumeTriangle>
class LLOctreeTriangleRayIntersect : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
{
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<LLVolumeTriangle>* node);
void traverse(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
virtual void visit(const LLOctreeNode<LLVolumeTriangle>* node);
virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* node);
};
class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle>
class LLVolumeOctreeValidate : public LLOctreeTraveler<LLVolumeTriangle, LLVolumeTriangle*>
{
virtual void visit(const LLOctreeNode<LLVolumeTriangle>* branch);
virtual void visit(const LLOctreeNode<LLVolumeTriangle, LLVolumeTriangle*>* branch);
};
#endif

View File

@ -126,13 +126,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name,
total_bits++;
}
S32 min_val;
U32 max_val;
if (is_signed)
{
min_val = 1 << int_bits;
min_val *= -1;
}
max_val = 1 << int_bits;
F32 fixed_val;

View File

@ -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";

View File

@ -374,7 +374,6 @@ BOOL LLThrottleGroup::dynamicAdjust()
}
mDynamicAdjustTime = mt_sec;
S32 total = 0;
// Update historical information
for (i = 0; i < TC_EOF; i++)
{
@ -391,7 +390,6 @@ BOOL LLThrottleGroup::dynamicAdjust()
}
mBitsSentThisPeriod[i] = 0;
total += ll_round(mBitsSentHistory[i]);
}
// Look for busy channels

View File

@ -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,8 +906,6 @@ LLSD LLModel::writeModel(
LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm)
{
U32 bytes = 0;
std::string::size_type cur_offset = 0;
LLSD header;
@ -927,7 +927,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header["skin"]["offset"] = (LLSD::Integer) cur_offset;
header["skin"]["size"] = (LLSD::Integer) size;
cur_offset += size;
bytes += size;
}
}
@ -943,7 +942,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
header["physics_convex"]["size"] = (LLSD::Integer) size;
cur_offset += size;
bytes += size;
}
}
@ -965,7 +963,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset;
header[model_names[i]]["size"] = (LLSD::Integer) size;
cur_offset += size;
bytes += size;
}
}

View File

@ -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
// <FS:CR> 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;
//}
// </FS:CR>
#endif
if (mHasFramebufferObject)
{

View File

@ -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)
{

View File

@ -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;
}

View File

@ -462,7 +462,6 @@ void LLLayoutStack::updateLayout()
space_to_distribute += panelp ? ll_round((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0;
S32 remaining_space = space_to_distribute;
F32 fraction_distributed = 0.f;
if (space_to_distribute > 0 && total_visible_fraction > 0.f)
{ // give space proportionally to visible auto resize panels
BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
@ -471,7 +470,6 @@ void LLLayoutStack::updateLayout()
{
F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction);
S32 delta = ll_round((F32)space_to_distribute * fraction_to_distribute);
fraction_distributed += fraction_to_distribute;
panelp->mTargetDim += delta;
remaining_space -= delta;
}

View File

@ -202,4 +202,10 @@ endif (llwindow_HEADER_FILES)
)
target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
if (DARWIN)
include(CMakeFindFrameworks)
find_library(CARBON_LIBRARY Carbon)
target_link_libraries(llwindow ${CARBON_LIBRARY})
endif (DARWIN)

View File

@ -630,8 +630,6 @@ void LLWindowMacOSX::getMouseDeltas(float* delta)
BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync)
{
BOOL glNeedsInit = FALSE;
mFullscreen = fullscreen;
if (mWindow == NULL)
@ -646,9 +644,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync);
mContext = getCGLContextObj(mGLView);
// Since we just created the context, it needs to be set up.
glNeedsInit = TRUE;
gGLManager.mVRAM = getVramSize(mGLView);
}
@ -1761,9 +1756,7 @@ void LLSplashScreenMacOSX::updateImpl(const std::string& mesg)
#if 0 // [FS:CR] This isn't used for anything at all...
if(mWindow != NULL)
{
CFStringRef string = NULL;
string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8);
}
#endif // [FS:CR]
}

View File

@ -1 +1 @@
6.6.5
6.6.6

View File

@ -2928,7 +2928,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>20.0</real>
<real>40.0</real>
</map>
<key>DiskCacheDirName</key>
<map>
@ -9567,17 +9567,6 @@
<key>Value</key>
<boolean>1</boolean>
</map>
<key>MiniMapPropertyLines</key>
<map>
<key>Comment</key>
<string>Show property boundaries on the mini-map</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<boolean>0</boolean>
</map>
<key>MiniMapPrimMaxRadius</key>
<map>
<key>Comment</key>
@ -9631,6 +9620,9 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<!-- *HACK: On first run, set this to 0 for new users,
otherwise the default is 1 to maintain consistent experience
for existing users. Hardcoded in llnetmap.cpp -->
<integer>1</integer>
</map>
<key>MiniMapScale</key>
@ -9644,6 +9636,17 @@
<key>Value</key>
<real>128.0</real>
</map>
<key>MiniMapShowPropertyLines</key>
<map>
<key>Comment</key>
<string>Whether or not to show parcel borders on the MiniMap.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<real>1</real>
</map>
<key>MouseSensitivity</key>
<map>
<key>Comment</key>
@ -9917,13 +9920,13 @@
<key>NonvisibleObjectsInMemoryTime</key>
<map>
<key>Comment</key>
<string>Number of frames non-visible objects stay in memory before being removed. 0 means never to remove.</string>
<string>Number of frames non-visible objects stay in memory before being removed. 0 means max.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>300</integer>
<integer>64</integer>
</map>
<key>NoPreload</key>
<map>
@ -14213,7 +14216,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>1024</integer>
<integer>2048</integer>
</map>
<key>SceneLoadLowMemoryBound</key>
<map>

View File

@ -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;
}

View File

@ -2,15 +2,15 @@
<bone aliases="hip avatar_mPelvis" connected="false" end="0.000 0.000 0.084" group="Torso" name="mPelvis" pivot="0.000000 0.000000 1.067015" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.030 0.000 0.095" group="Collision" name="PELVIS" pos="-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="BUTT" pos="-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1" support="base"/>
<bone connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mSpine1" connected="true" end="0.000 0.000 -0.084" group="Spine" name="mSpine1" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mSpine2" connected="true" end="0.000 0.000 0.084" group="Spine" name="mSpine2" pivot="0.000000 0.000000 -0.084073" pos="0.000 0.000 -0.084" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="abdomen avatar_mTorso" connected="true" end="-0.015 0.000 0.205" group="Torso" name="mTorso" pivot="0.000000 0.000000 0.084073" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.028 0.000 0.094" group="Collision" name="BELLY" pos="0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
<collision_volume end="0.000 0.100 0.000" group="Collision" name="LEFT_HANDLE" pos="0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="0.000 -0.100 0.000" group="Collision" name="RIGHT_HANDLE" pos="0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05" support="base"/>
<collision_volume end="-0.100 0.000 0.000" group="Collision" name="LOWER_BACK" pos="0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15" support="base"/>
<bone connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mSpine3" connected="true" end="0.015 0.000 -0.205" group="Spine" name="mSpine3" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mSpine4" connected="true" end="-0.015 0.000 0.205" group="Spine" name="mSpine4" pivot="0.015368 0.000000 -0.204877" pos="0.015 0.000 -0.205" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="chest avatar_mChest" connected="true" end="-0.010 0.000 0.250" group="Torso" name="mChest" pivot="-0.015368 0.000000 0.204877" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="-0.096 0.000 0.152" group="Collision" name="CHEST" pos="0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2" support="base"/>
<collision_volume end="0.080 0.000 -0.006" group="Collision" name="LEFT_PEC" pos="0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05" support="base"/>
@ -23,58 +23,58 @@
<bone aliases="figureHair avatar_mSkull" connected="false" end="0.000 0.000 0.033" group="Extra" name="mSkull" pivot="0.000000 0.000000 0.079000" pos="0.000 0.000 0.079" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeRight" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeRight" pivot="0.098466 -0.036000 0.079000" pos="0.098 -0.036 0.079" rot="0.000000 0.000000 -0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone aliases="avatar_mEyeLeft" connected="false" end="0.025 0.000 0.000" group="Extra" name="mEyeLeft" pivot="0.098461 0.036000 0.079000" pos="0.098 0.036 0.079" rot="0.000000 -0.000000 0.000000" scale="1.000 1.000 1.000" support="base"/>
<bone connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceRoot" connected="false" end="0.020 0.000 0.000" group="Face" name="mFaceRoot" pivot="0.025000 0.000000 0.045000" pos="0.025 0.000 0.045" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mFaceEyeAltRight" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltRight" pivot="0.073466 -0.036000 0.0339300" pos="0.073 -0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyeAltLeft" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceEyeAltLeft" pivot="0.073461 0.036000 0.0339300" pos="0.073 0.036 0.034" rot="0.000000 0.000000 0.000000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceForeheadLeft" connected="false" end="0.024 0.004 0.018" group="Face" name="mFaceForeheadLeft" pivot="0.061 0.035 0.083" pos="0.061 0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceForeheadRight" connected="false" end="0.024 -0.004 0.018" group="Face" name="mFaceForeheadRight" pivot="0.061 -0.035 0.083" pos="0.061 -0.035 0.083" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyebrowOuterLeft" connected="false" end="0.023 0.013 0.000" group="Eyes" name="mFaceEyebrowOuterLeft" pivot="0.064 0.051 0.048" pos="0.064 0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyebrowCenterLeft" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterLeft" pivot="0.070 0.043 0.056" pos="0.070 0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyebrowInnerLeft" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerLeft" pivot="0.075 0.022 0.051" pos="0.075 0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyebrowOuterRight" connected="false" end="0.023 -0.013 0.000" group="Eyes" name="mFaceEyebrowOuterRight" pivot="0.064 -0.051 0.048" pos="0.064 -0.051 0.048" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyebrowCenterRight" connected="false" end="0.027 0.000 0.000" group="Eyes" name="mFaceEyebrowCenterRight" pivot="0.070 -0.043 0.056" pos="0.070 -0.043 0.056" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyebrowInnerRight" connected="false" end="0.026 0.000 0.000" group="Eyes" name="mFaceEyebrowInnerRight" pivot="0.075 -0.022 0.051" pos="0.075 -0.022 0.051" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyeLidUpperLeft" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyeLidLowerLeft" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerLeft" pivot="0.073 0.036 0.034" pos="0.073 0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyeLidUpperRight" connected="false" end="0.027 0.000 0.005" group="Eyes" name="mFaceEyeLidUpperRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyeLidLowerRight" connected="false" end="0.024 0.000 -0.007" group="Eyes" name="mFaceEyeLidLowerRight" pivot="0.073 -0.036 0.034" pos="0.073 -0.036 0.034" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEar1Left" connected="false" end="-0.019 0.018 0.025" group="Ears" name="mFaceEar1Left" pivot="0.000 0.080 0.002" pos="0.000 0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mFaceEar2Left" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Left" pivot="-0.019 0.018 0.025" pos="-0.019 0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
<bone connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEar1Right" connected="false" end="-0.019 -0.018 0.025" group="Ears" name="mFaceEar1Right" pivot="0.000 -0.080 0.002" pos="0.000 -0.080 0.002" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mFaceEar2Right" connected="true" end="0.000 0.000 0.033" group="Ears" name="mFaceEar2Right" pivot="-0.019 -0.018 0.025" pos="-0.019 -0.018 0.025" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
<bone connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceNoseLeft" connected="false" end="0.015 0.004 0.000" group="Face" name="mFaceNoseLeft" pivot="0.086 0.015 -0.004" pos="0.086 0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceNoseCenter" connected="false" end="0.025 0.000 0.000" group="Face" name="mFaceNoseCenter" pivot="0.102 0.000 0.000" pos="0.102 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceNoseRight" connected="false" end="0.015 -0.004 0.000" group="Face" name="mFaceNoseRight" pivot="0.086 -0.015 -0.004" pos="0.086 -0.015 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceCheekLowerLeft" connected="false" end="0.013 0.030 0.000" group="Face" name="mFaceCheekLowerLeft" pivot="0.050 0.034 -0.031" pos="0.050 0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceCheekUpperLeft" connected="false" end="0.022 0.015 0.000" group="Face" name="mFaceCheekUpperLeft" pivot="0.070 0.034 -0.005" pos="0.070 0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceCheekLowerRight" connected="false" end="0.013 -0.030 0.000" group="Face" name="mFaceCheekLowerRight" pivot="0.050 -0.034 -0.031" pos="0.050 -0.034 -0.031" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceCheekUpperRight" connected="false" end="0.022 -0.015 0.000" group="Face" name="mFaceCheekUpperRight" pivot="0.070 -0.034 -0.005" pos="0.070 -0.034 -0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceJaw" connected="false" end="0.059 0.000 -0.039" group="Mouth" name="mFaceJaw" pivot="-0.001 0.000 -0.015" pos="-0.001 0.000 -0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mFaceChin" connected="false" end="0.021 0.000 -0.018" group="Mouth" name="mFaceChin" pivot="0.074 0.000 -0.054" pos="0.074 0.000 -0.054" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceTeethLower" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethLower" pivot="0.021 0.000 -0.039" pos="0.021 0.000 -0.039" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mFaceLipLowerLeft" connected="false" end="0.034 0.017 0.005" group="Lips" name="mFaceLipLowerLeft" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceLipLowerRight" connected="false" end="0.034 -0.017 0.005" group="Lips" name="mFaceLipLowerRight" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceLipLowerCenter" connected="false" end="0.040 0.000 0.002" group="Lips" name="mFaceLipLowerCenter" pivot="0.045 0.000 0.000" pos="0.045 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceTongueBase" connected="false" end="0.022 0.000 0.007" group="Mouth" name="mFaceTongueBase" pivot="0.039 0.000 0.005" pos="0.039 0.000 0.005" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mFaceTongueTip" connected="true" end="0.010 0.000 0.000" group="Mouth" name="mFaceTongueTip" pivot="0.022 0.000 0.007" pos="0.022 0.000 0.007" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
<bone connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceJawShaper" connected="false" end="-0.017 0.000 0.000" group="Face" name="mFaceJawShaper" pivot="0.000 0.000 0.000" pos="0.000 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceForeheadCenter" connected="false" end="0.036 0.000 0.000" group="Face" name="mFaceForeheadCenter" pivot="0.069 0.000 0.065" pos="0.069 0.000 0.065" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceNoseBase" connected="false" end="0.014 0.000 0.000" group="Nose" name="mFaceNoseBase" pivot="0.094 0.000 -0.016" pos="0.094 0.000 -0.016" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceTeethUpper" connected="false" end="0.035 0.000 0.000" group="Mouth" name="mFaceTeethUpper" pivot="0.020 0.000 -0.030" pos="0.020 0.000 -0.030" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mFaceLipUpperLeft" connected="false" end="0.041 0.015 0.000" group="Lips" name="mFaceLipUpperLeft" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceLipUpperRight" connected="false" end="0.041 -0.015 0.000" group="Lips" name="mFaceLipUpperRight" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceLipCornerLeft" connected="false" end="0.045 0.051 0.000" group="Lips" name="mFaceLipCornerLeft" pivot="0.028 -0.019 -0.010" pos="0.028 -0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceLipCornerRight" connected="false" end="0.045 -0.051 0.000" group="Lips" name="mFaceLipCornerRight" pivot="0.028 0.019 -0.010" pos="0.028 0.019 -0.010" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceLipUpperCenter" connected="false" end="0.043 0.000 0.002" group="Lips" name="mFaceLipUpperCenter" pivot="0.045 0.000 -0.003" pos="0.045 0.000 -0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
<bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyecornerInnerLeft" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerLeft" pivot="0.075 0.017 0.032" pos="0.075 0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceEyecornerInnerRight" connected="false" end="0.016 0.000 0.000" group="Face" name="mFaceEyecornerInnerRight" pivot="0.075 -0.017 0.032" pos="0.075 -0.017 0.032" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mFaceNoseBridge" connected="false" end="0.015 0.000 0.008" group="Nose" name="mFaceNoseBridge" pivot="0.091 0.000 0.020" pos="0.091 0.000 0.020" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@ -86,29 +86,29 @@
<collision_volume end="0.000 0.100 -0.001" group="Collision" name="L_LOWER_ARM" pos="0.0 0.1 0.0" rot="-3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="lHand avatar_mWristLeft" connected="true" end="0.000 0.060 0.000" group="Arms" name="mWristLeft" pivot="-0.000000 0.204846 0.000000" pos="-0.000 0.205 0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 0.049 -0.001" group="Collision" name="L_HAND" pos="0.01 0.05 0.0" rot="-3.000000 0.00000 -10.000000" scale="0.05 0.08 0.03" support="base"/>
<bone connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandMiddle1Left" connected="false" end="-0.001 0.040 -0.006" group="Hand" name="mHandMiddle1Left" pivot="0.013 0.101 0.015" pos="0.013 0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandMiddle2Left" connected="true" end="-0.001 0.049 -0.008" group="Hand" name="mHandMiddle2Left" pivot="-0.001 0.040 -0.006" pos="-0.001 0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandMiddle3Left" connected="true" end="-0.002 0.033 -0.006" group="Hand" name="mHandMiddle3Left" pivot="-0.001 0.049 -0.008" pos="-0.001 0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandIndex1Left" connected="false" end="0.017 0.036 -0.006" group="Hand" name="mHandIndex1Left" pivot="0.038 0.097 0.015" pos="0.038 0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandIndex2Left" connected="true" end="0.014 0.032 -0.006" group="Hand" name="mHandIndex2Left" pivot="0.017 0.036 -0.006" pos="0.017 0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandIndex3Left" connected="true" end="0.011 0.025 -0.004" group="Hand" name="mHandIndex3Left" pivot="0.014 0.032 -0.006" pos="0.014 0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandRing1Left" connected="false" end="-0.013 0.038 -0.008" group="Hand" name="mHandRing1Left" pivot="-0.010 0.099 0.009" pos="-0.010 0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandRing2Left" connected="true" end="-0.013 0.040 -0.009" group="Hand" name="mHandRing2Left" pivot="-0.013 0.038 -0.008" pos="-0.013 0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandRing3Left" connected="true" end="-0.010 0.028 -0.006" group="Hand" name="mHandRing3Left" pivot="-0.013 0.040 -0.009" pos="-0.013 0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandPinky1Left" connected="false" end="-0.024 0.025 -0.006" group="Hand" name="mHandPinky1Left" pivot="-0.031 0.095 0.003" pos="-0.031 0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandPinky2Left" connected="true" end="-0.015 0.018 -0.004" group="Hand" name="mHandPinky2Left" pivot="-0.024 0.025 -0.006" pos="-0.024 0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandPinky3Left" connected="true" end="-0.013 0.016 -0.004" group="Hand" name="mHandPinky3Left" pivot="-0.015 0.018 -0.004" pos="-0.015 0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandThumb1Left" connected="false" end="0.028 0.032 0.000" group="Hand" name="mHandThumb1Left" pivot="0.031 0.026 0.004" pos="0.031 0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandThumb2Left" connected="true" end="0.023 0.031 0.000" group="Hand" name="mHandThumb2Left" pivot="0.028 0.032 -0.001" pos="0.028 0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandThumb3Left" connected="true" end="0.015 0.025 0.000" group="Hand" name="mHandThumb3Left" pivot="0.023 0.031 -0.001" pos="0.023 0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@ -123,49 +123,49 @@
<collision_volume end="0.000 -0.100 -0.001" group="Collision" name="R_LOWER_ARM" pos="0.0 -0.1 0.0" rot="3.000000 0.00000 0.000000" scale="0.04 0.14 0.04" support="base"/>
<bone aliases="rHand avatar_mWristRight" connected="true" end="0.000 -0.060 0.000" group="Arms" name="mWristRight" pivot="-0.000000 -0.205000 -0.000000" pos="0.000 -0.205 -0.000" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" support="base">
<collision_volume end="0.005 -0.049 -0.001" group="Collision" name="R_HAND" pos="0.01 -0.05 0.0" rot="3.000000 0.00000 10.000000" scale="0.05 0.08 0.03" support="base"/>
<bone connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandMiddle1Right" connected="false" end="-0.001 -0.040 -0.006" group="Hand" name="mHandMiddle1Right" pivot="0.013 -0.101 0.015" pos="0.013 -0.101 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandMiddle2Right" connected="true" end="-0.001 -0.049 -0.008" group="Hand" name="mHandMiddle2Right" pivot="-0.001 -0.040 -0.006" pos="-0.001 -0.040 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandMiddle3Right" connected="true" end="-0.002 -0.033 -0.006" group="Hand" name="mHandMiddle3Right" pivot="-0.001 -0.049 -0.008" pos="-0.001 -0.049 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandIndex1Right" connected="false" end="0.017 -0.036 -0.006" group="Hand" name="mHandIndex1Right" pivot="0.038 -0.097 0.015" pos="0.038 -0.097 0.015" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandIndex2Right" connected="true" end="0.014 -0.032 -0.006" group="Hand" name="mHandIndex2Right" pivot="0.017 -0.036 -0.006" pos="0.017 -0.036 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandIndex3Right" connected="true" end="0.011 -0.025 -0.004" group="Hand" name="mHandIndex3Right" pivot="0.014 -0.032 -0.006" pos="0.014 -0.032 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandRing1Right" connected="false" end="-0.013 -0.038 -0.008" group="Hand" name="mHandRing1Right" pivot="-0.010 -0.099 0.009" pos="-0.010 -0.099 0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandRing2Right" connected="true" end="-0.013 -0.040 -0.009" group="Hand" name="mHandRing2Right" pivot="-0.013 -0.038 -0.008" pos="-0.013 -0.038 -0.008" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandRing3Right" connected="true" end="-0.010 -0.028 -0.006" group="Hand" name="mHandRing3Right" pivot="-0.013 -0.040 -0.009" pos="-0.013 -0.040 -0.009" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandPinky1Right" connected="false" end="-0.024 -0.025 -0.006" group="Hand" name="mHandPinky1Right" pivot="-0.031 -0.095 0.003" pos="-0.031 -0.095 0.003" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandPinky2Right" connected="true" end="-0.015 -0.018 -0.004" group="Hand" name="mHandPinky2Right" pivot="-0.024 -0.025 -0.006" pos="-0.024 -0.025 -0.006" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandPinky3Right" connected="true" end="-0.013 -0.016 -0.004" group="Hand" name="mHandPinky3Right" pivot="-0.015 -0.018 -0.004" pos="-0.015 -0.018 -0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
<bone connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHandThumb1Right" connected="false" end="0.028 -0.032 0.000" group="Hand" name="mHandThumb1Right" pivot="0.031 -0.026 0.004" pos="0.031 -0.026 0.004" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandThumb2Right" connected="true" end="0.023 -0.031 0.000" group="Hand" name="mHandThumb2Right" pivot="0.028 -0.032 -0.001" pos="0.028 -0.032 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHandThumb3Right" connected="true" end="0.015 -0.025 0.000" group="Hand" name="mHandThumb3Right" pivot="0.023 -0.031 -0.001" pos="0.023 -0.031 -0.001" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
</bone>
<bone connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mWingsRoot" connected="false" end="-0.061 0.000 0.000" group="Wing" name="mWingsRoot" pivot="-0.014 0.000 0.000" pos="-0.014 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mWing1Left" connected="false" end="-0.168 0.169 0.067" group="Wing" name="mWing1Left" pivot="-0.099 0.105 0.181" pos="-0.099 0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mWing2Left" connected="true" end="-0.181 0.183 0.000" group="Wing" name="mWing2Left" pivot="-0.168 0.169 0.067" pos="-0.168 0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mWing3Left" connected="true" end="-0.171 0.173 0.000" group="Wing" name="mWing3Left" pivot="-0.181 0.183 0.000" pos="-0.181 0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mWing4Left" connected="true" end="-0.146 0.132 0.000" group="Wing" name="mWing4Left" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mWing4FanLeft" connected="true" end="-0.068 0.062 -0.159" group="Wing" name="mWing4FanLeft" pivot="-0.171 0.173 0.000" pos="-0.171 0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
<bone connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mWing1Right" connected="false" end="-0.168 -0.169 0.067" group="Wing" name="mWing1Right" pivot="-0.099 -0.105 0.181" pos="-0.099 -0.105 0.181" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mWing2Right" connected="true" end="-0.181 -0.183 0.000" group="Wing" name="mWing2Right" pivot="-0.168 -0.169 0.067" pos="-0.168 -0.169 0.067" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mWing3Right" connected="true" end="-0.171 -0.173 0.000" group="Wing" name="mWing3Right" pivot="-0.181 -0.183 0.000" pos="-0.181 -0.183 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mWing4Right" connected="true" end="-0.146 -0.132 0.000" group="Wing" name="mWing4Right" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mWing4FanRight" connected="true" end="-0.068 -0.062 -0.159" group="Wing" name="mWing4FanRight" pivot="-0.171 -0.173 0.000" pos="-0.171 -0.173 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
@ -200,30 +200,30 @@
</bone>
</bone>
</bone>
<bone connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mTail1" connected="false" end="-0.197 0.000 0.000" group="Tail" name="mTail1" pivot="-0.116 0.000 0.047" pos="-0.116 0.000 0.047" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mTail2" connected="true" end="-0.168 0.000 0.000" group="Tail" name="mTail2" pivot="-0.197 0.000 0.000" pos="-0.197 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mTail3" connected="true" end="-0.142 0.000 0.000" group="Tail" name="mTail3" pivot="-0.168 0.000 0.000" pos="-0.168 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mTail4" connected="true" end="-0.112 0.000 0.000" group="Tail" name="mTail4" pivot="-0.142 0.000 0.000" pos="-0.142 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mTail5" connected="true" end="-0.094 0.000 0.000" group="Tail" name="mTail5" pivot="-0.112 0.000 0.000" pos="-0.112 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mTail6" connected="true" end="-0.089 0.000 0.000" group="Tail" name="mTail6" pivot="-0.094 0.000 0.000" pos="-0.094 0.000 0.000" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
</bone>
</bone>
<bone connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mGroin" connected="false" end="0.004 0.000 -0.066" group="Groin" name="mGroin" pivot="0.064 0.000 -0.097" pos="0.064 0.000 -0.097" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHindLimbsRoot" connected="false" end="-0.204 0.000 0.000" group="Limb" name="mHindLimbsRoot" pivot="-0.200 0.000 0.084" pos="-0.200 0.000 0.084" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHindLimb1Left" connected="false" end="0.002 -0.046 -0.491" group="Limb" name="mHindLimb1Left" pivot="-0.204 0.129 -0.125" pos="-0.204 0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHindLimb2Left" connected="true" end="-0.030 -0.003 -0.468" group="Limb" name="mHindLimb2Left" pivot="0.002 -0.046 -0.491" pos="0.002 -0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHindLimb3Left" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Left" pivot="-0.030 -0.003 -0.468" pos="-0.030 -0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHindLimb4Left" connected="true" end="0.105 0.008 0.000" group="Limb" name="mHindLimb4Left" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>
<bone connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
<bone aliases="avatar_mHindLimb1Right" connected="false" end="0.002 0.046 -0.491" group="Limb" name="mHindLimb1Right" pivot="-0.204 -0.129 -0.125" pos="-0.204 -0.129 -0.125" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHindLimb2Right" connected="true" end="-0.030 0.003 -0.468" group="Limb" name="mHindLimb2Right" pivot="0.002 0.046 -0.491" pos="0.002 0.046 -0.491" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHindLimb3Right" connected="true" end="0.112 0.000 -0.061" group="Limb" name="mHindLimb3Right" pivot="-0.030 0.003 -0.468" pos="-0.030 0.003 -0.468" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended">
<bone aliases="avatar_mHindLimb4Right" connected="true" end="0.105 -0.008 0.000" group="Limb" name="mHindLimb4Right" pivot="0.112 0.000 -0.061" pos="0.112 0.000 -0.061" rot="0.000 0.000 0.000" scale="1.00 1.00 1.00" support="extended"/>
</bone>
</bone>
</bone>

103
indra/newview/cube.dae Normal file
View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<contributor>
modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26
</contributor>
<created>2018-10-25T16:29:03Z</created>
<modified>2022-02-18T00:00:00Z</modified>
<unit meter="1.000000"/>
<up_axis>Y_UP</up_axis>
</asset>
<library_materials>
<material id="Blue" name="Blue">
<instance_effect url="#effect_Blue"/>
</material>
</library_materials>
<library_effects>
<effect id="effect_Blue">
<profile_COMMON>
<technique sid="common">
<phong>
<ambient>
<color>0 0 0 1</color>
</ambient>
<diffuse>
<color>0.137255 0.403922 0.870588 1</color>
</diffuse>
<specular>
<color>0.5 0.5 0.5 1</color>
</specular>
<shininess>
<float>16</float>
</shininess>
<transparent opaque="A_ONE">
<color>0 0 0 1</color>
</transparent>
<transparency>
<float>1</float>
</transparency>
<index_of_refraction>
<float>1</float>
</index_of_refraction>
</phong>
</technique>
</profile_COMMON>
</effect>
</library_effects>
<library_geometries>
<geometry id="F1" name="default_physics_shape">
<mesh>
<source id="cube-vertex-positions">
<float_array id="ID2-array" count="72">-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 </float_array>
<technique_common>
<accessor source="#ID2-array" count="24" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<vertices id="cube-vertices">
<input semantic="POSITION" source="#cube-vertex-positions"/>
</vertices>
<triangles count="12" material="geometryElement5">
<input semantic="VERTEX" offset="0" source="#cube-vertices"/>
<p>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 </p>
</triangles>
</mesh>
</geometry>
</library_geometries>
<library_visual_scenes>
<visual_scene id="reportScene">
<!-- No Spaces allowed in Name -->
<node id="F1" name="Face1">
<instance_geometry url="#F1">
<bind_material>
<technique_common>
<instance_material symbol="geometryElement5" target="#Blue"/>
</technique_common>
</bind_material>
</instance_geometry>
</node>
</visual_scene>
</library_visual_scenes>
<scene>
<instance_visual_scene url="#reportScene"/>
</scene>
</COLLADA>

View File

@ -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
# <FS:Ansariel> 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"

View File

@ -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?"

View File

@ -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())
{

View File

@ -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<LLInventoryCallback> 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<LLInventoryCallback> 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

View File

@ -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");
@ -2925,10 +2925,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();
@ -4259,7 +4273,7 @@ void LLAppViewer::cleanupSavedSettings()
}
}
gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());
// Some things are cached in LLAgent.
if (gAgent.isInitialized())
@ -5099,15 +5113,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);
// <FS:Ansariel> Better cache size control
//const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal");
//const F6432 texture_cache_percent = 100.0 - disk_cache_percent;
// </FS:Ansariel>
// note that the maximum size of this cache is defined as a percentage of the
// total cache size - the 'CacheSize' pref - for all caches.
// <FS:Ansariel> 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;
// <FS:Ansariel> 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;
// </FS:Ansariel>
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;
@ -5186,7 +5208,7 @@ bool LLAppViewer::initCache()
// </FS:Ansariel>
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)
{
@ -5246,22 +5268,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
// <FS:Ansariel> 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;
// </FS:Ansariel>
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<void()>& cb)
@ -5988,8 +6005,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();
}
}

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
}
}
}

View File

@ -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);

View File

@ -59,6 +59,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 +149,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 +221,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);

View File

@ -129,7 +129,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth)
// </FS:Beq>
}
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)
{

View File

@ -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)

View File

@ -528,20 +528,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
is.close();
}
//get time domain
LLSD::Real cur_total_time = 0.0;
for (U32 i = 0; i < cur_data.size(); ++i)
{
cur_total_time += cur_data[i]["Total"]["Time"].asReal();
}
LLSD::Real base_total_time = 0.0;
for (U32 i = 0; i < base_data.size(); ++i)
{
base_total_time += base_data[i]["Total"]["Time"].asReal();
}
//allocate raw scratch space
LLPointer<LLImageRaw> scratch = new LLImageRaw(1024, 512, 3);

View File

@ -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<LLFavoriteLandmarkButton*>(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<LLFavoriteLandmarkButton*> (*cur_it);
if (button)
{
if (mLastTab == button)
{
mLastTab = NULL;
}
removeChild(button);
delete button;
}
@ -1023,6 +1053,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<LLFavoriteLandmarkButton*> (childs->back());
if (button)
{
mLastTab = button;
}
}
mFirstDropDownItem = j;
// Chevron button
if (mFirstDropDownItem < mItems.size())

View File

@ -387,7 +387,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;

View File

@ -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();
}
}

View File

@ -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;

View File

@ -46,19 +46,60 @@
typedef std::pair<LLUUID, std::string> 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<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
getChild<LLButton>("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<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
new_item->rename(current_title_value);
new_item->setDescription(current_notes_value);
LLPointer<LLInventoryCallback> 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());
}
}
}
}

View File

@ -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<LLInventoryItem> mItem;

View File

@ -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)
{

View File

@ -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)
{

View File

@ -107,28 +107,31 @@ void LLFloaterHoverHeight::onClose(bool app_quitting)
// static
void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData)
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(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;
// <FS:Ansariel> 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);
}
// </FS:Ansariel>
if (isAgentAvatarValid())
{
LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(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;
// <FS:Ansariel> 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);
}
// </FS:Ansariel>
}
}
// Do send-to-the-server work when slider drag completes, or new

View File

@ -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)

View File

@ -3291,7 +3291,8 @@ BOOL LLPanelLandCovenant::postBuild()
{
mLastRegionID = LLUUID::null;
mNextUpdateTime = 0;
mTextEstateOwner = getChild<LLTextBox>("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<LLTextBox>("estate_owner_text");
if (editor) editor->setText(name);
self->mTextEstateOwner->setText(name);
}
}

View File

@ -431,6 +431,7 @@ protected:
private:
LLUUID mLastRegionID;
F64 mNextUpdateTime; //seconds since client start
LLTextBox* mTextEstateOwner;
};
#endif

View File

@ -51,7 +51,7 @@
// The minor cardinal direction labels are hidden if their height is more
// than this proportion of the map.
const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f;
const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f;
const S32 MAP_PADDING_LEFT = 0;
const S32 MAP_PADDING_TOP = 2;
@ -81,46 +81,54 @@ LLFloaterMap::~LLFloaterMap()
BOOL LLFloaterMap::postBuild()
{
mMap = getChild<LLNetMap>("Net Map");
// <FS:Ansariel> Synchronize tooltips throughout instances
//if (gSavedSettings.getBOOL("DoubleClickTeleport"))
//{
// mMap->setToolTipMsg(getString("AltToolTipMsg"));
//}
//else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
//{
// mMap->setToolTipMsg(getString("ToolTipMsg"));
//}
// </FS:Ansariel> Synchronize tooltips throughout instances
sendChildToBack(mMap);
mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
mMap = getChild<LLNetMap>("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);
// <FS:Ansariel> Remove titlebar
stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT,
getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM);
mTextBoxNorth = getChild<LLTextBox>("floater_map_north");
mTextBoxEast = getChild<LLTextBox>("floater_map_east");
mTextBoxWest = getChild<LLTextBox>("floater_map_west");
mTextBoxSouth = getChild<LLTextBox>("floater_map_south");
mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast");
mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast");
mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest");
mTextBoxNorthWest = getChild<LLTextBox>("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());
// <FS:Ansariel> Remove titlebar
setIsChrome(TRUE);
getDragHandle()->setTitleVisible(TRUE);
// </FS:Ansariel>
// keep onscreen
gFloaterView->adjustToFitScreen(this, FALSE);
// <FS:Ansariel> 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());
// <FS:Ansariel> Remove titlebar
setIsChrome(TRUE);
getDragHandle()->setTitleVisible(TRUE);
// </FS:Ansariel>
// keep onscreen
gFloaterView->adjustToFitScreen(this, false);
return true;
}
BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
@ -156,23 +164,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 +268,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
updateMinorDirections();
}
// <FS:Ansariel> 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);
// }
//}
// </FS:Ansariel>
LLFloaterMap* LLFloaterMap::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map");

View File

@ -51,8 +51,6 @@ public:
/*virtual*/ F32 getCurrentTransparency();
private:
// <FS:Ansariel> Unused as of 06-02-2014; Handled in LLNetMap
//void handleZoom(const LLSD& userdata);
void setDirectionPos( LLTextBox* text_box, F32 rotation );
void updateMinorDirections();

View File

@ -535,13 +535,14 @@ void LLFloaterModelPreview::loadHighLodModel()
loadModel(3);
}
void LLFloaterModelPreview::loadModel(S32 lod)
void LLFloaterModelPreview::prepareToLoadModel(S32 lod)
{
// <FS:Ansariel> FIRE-15204: Viewer crashes when clicking "upload model" quickly twice then closing both filepickers
if (mModelPreview->mLoading)
{
return;
}
mModelPreview->mLoading = true;
// </FS:Ansariel>
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)
{
// <FS:Ansariel> FIRE-15204: Viewer crashes when clicking "upload model" quickly twice then closing both filepickers
if (mModelPreview->mLoading)
{
return;
}
// </FS:Ansariel>
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)
{
// <FS:Beq> 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)
}
// </FS:Beq>
}
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<LLComboBox>("physics_lod_combo");
if (lod_combo)
{
lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1); // <FS:Beq/> FIRE-30963 - better physics defaults
lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1);
}
}
else
{
{
LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
if (lod_combo)
{

View File

@ -223,6 +223,7 @@ private:
void resetUploadOptions();
void clearLogTab();
void prepareToLoadModel(S32 lod);
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);

View File

@ -2112,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);
@ -2226,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);
@ -2365,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);

View File

@ -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<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend);
return LLPanelRegionInfo::postBuild();
}
@ -2371,6 +2374,7 @@ BOOL LLPanelEstateCovenant::postBuild()
{
mEstateNameText = getChild<LLTextBox>("estate_name_text");
mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);
mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
mEditor = getChild<LLViewerTextEditor>("covenant_editor");
LLButton* reset_button = getChild<LLButton>("reset_covenant");

View File

@ -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<LLPanel>("objects_mapview");
mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem();
@ -367,16 +366,14 @@ BOOL LLFloaterWorldMap::postBuild()
landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f);
getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal);
F32 slider_zoom = mMapView->getZoom();
getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom);
// <FS:Ansariel> Use own expand/collapse function
//getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this));
setDefaultBtn(NULL);
mZoomTimer.stop();
onChangeMaturity();
return TRUE;
@ -393,7 +390,7 @@ LLFloaterWorldMap::~LLFloaterWorldMap()
// </FS:Ansariel> 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<LLUICtrl>("zoom slider")->getValue().asReal();
slider_value += ((F32)clicks * -0.3333f);
getChild<LLUICtrl>("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<LLUICtrl>("zoom slider")->getValue().asReal();
F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f);
getChild<LLUICtrl>("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
// <FS:Ansariel> Performance improvement
//if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal())
if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)zoom_slider->getValue().asReal())
// </FS:Ansariel> Performance improvement
{
mZoomTimer.start();
}
F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
if (interp > 1.f)
{
interp = 1.f;
mZoomTimer.stop();
}
// <FS:Ansariel> Performance improvement
//mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp);
mCurZoomVal = lerp(mCurZoomVal, (F32)zoom_slider->getValue().asReal(), interp);
// </FS:Ansariel> Performance improvement
F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
LLWorldMapView::setScale( map_scale );
mMapView->zoom((F32)getChild<LLUICtrl>("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();
// <FS:Ansariel> 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() :

View File

@ -47,6 +47,7 @@ class LLInventoryObserver;
class LLItemInfo;
class LLLineEditor;
class LLTabContainer;
class LLWorldMapView;
// <FS:Ansariel> Parcel details on map
class FSWorldMapParcelInfoObserver : public LLRemoteParcelInfoObserver
@ -189,11 +190,7 @@ protected:
// </FS:Ansariel> 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 );

View File

@ -64,6 +64,7 @@
#include "llviewerregion.h"
#include <boost/regex.hpp>
#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);

View File

@ -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())

View File

@ -4219,7 +4219,20 @@ void LLFolderBridge::perform_pasteFromClipboard()
{
if (item && can_move_to_landmarks(item))
{
dropToFavorites(item);
if (LLClipboard::instance().isCutMode())
{
LLViewerInventoryItem* viitem = dynamic_cast<LLViewerInventoryItem*>(item);
llassert(viitem);
if (viitem)
{
//changeItemParent() implicity calls dirtyFilter
changeItemParent(model, viitem, parent_id, FALSE);
}
}
else
{
dropToFavorites(item);
}
}
}
else if (LLClipboard::instance().isCutMode())
@ -4782,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"));
}

View File

@ -3433,7 +3433,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
gInventory.accountForUpdate(update);
}
U32 changes = 0x0;
if (account)
{
mask |= LLInventoryObserver::CREATE;
@ -3441,7 +3440,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32
//as above, this loop never seems to loop more than once per call
for (item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
changes |= gInventory.updateItem(*it, mask);
gInventory.updateItem(*it, mask);
}
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();
@ -5232,12 +5231,10 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
}
// as above, this loop never seems to loop more than once per call
U32 changes(0U);
for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it)
{
changes |= gInventory.updateItem(*it);
gInventory.updateItem(*it);
}
// *HUH: Have computed 'changes', nothing uses it.
gInventory.notifyObservers();
gViewerWindow->getWindow()->decBusyCount();

View File

@ -386,7 +386,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
return;
}
const BOOL hide_clip_plane = TRUE;
LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f);
const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
@ -472,33 +471,17 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
render_fog_color = sky_fog_color;
F32 fog_density = 0.f;
fog_distance = mFogRatio * distance;
if (camera_height > water_height)
{
LLColor4 fog(render_fog_color);
mGLFogCol = fog;
if (hide_clip_plane)
{
// For now, set the density to extend to the cull distance.
const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f)))
fog_density = f_log/fog_distance;
}
else
{
const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f))
fog_density = (f_log)/fog_distance;
}
}
else
{
LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
F32 depth = water_height - camera_height;
// get the water param manager variables
float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f);
LLColor4 water_fog_color(pwater->getWaterFogColor());
@ -512,9 +495,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
// set the gl fog color
mGLFogCol = fogCol;
// set the density based on what the shaders use
fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale");
}
mFogColor = sky_fog_color;

View File

@ -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);
// </FS:Beq>
static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape";
const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
#include "glod/glod.h" // <FS:Beq/> 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;
}
}
@ -3647,8 +3668,6 @@ void LLModelPreview::clearBuffers()
void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
{
U32 tri_count = 0;
U32 vertex_count = 0;
U32 mesh_count = 0;
@ -3787,10 +3806,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
mVertexBuffer[lod][mdl].push_back(vb);
vertex_count += num_vertices;
tri_count += num_indices / 3;
++mesh_count;
}
}
}

View File

@ -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
{

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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 );
// <FS:Ansariel> Synchronize tooltips throughout instances
//void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
static void setToolTipMsg(const std::string& msg) { sToolTipMsg = msg; }
static void updateToolTipMsg();
// </FS:Ansariel> 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<LLImageRaw> mObjectRawImagep;
@ -174,10 +186,15 @@ private:
// [SL:KB] - Patch: World-MiniMap | Checked: 2012-07-08 (Catznip-3.3)
LLVector3d mClosestAgentPosition;
// [/SL:KB]
// <FS:Ansariel> Synchronize tooltips throughout instances
//std::string mToolTipMsg;
static std::string sToolTipMsg;
// </FS:Ansariel> 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;
// <FS:Ansariel> Mark avatar feature
typedef std::map<LLUUID, LLColor4> avatar_marks_map_t;
@ -188,14 +205,18 @@ public:
// <FS:CR> Minimap improvements
void handleShowProfile(const LLSD& sdParam) const;
uuid_vec_t mClosestAgentsToCursor;
LLVector3d mPosGlobalRightClick;
LLUUID mClosestAgentRightClick;
uuid_vec_t mClosestAgentsRightClick;
// </FS:CR>
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();

Some files were not shown because too many files have changed in this diff Show More