Merge branch 'master' of https://vcs.firestormviewer.org/phoenix-firestorm
commit
8b0d341aca
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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. Let’s say thread
|
||||
// Interaction through the filesystem itself should be safe. Let’s say thread
|
||||
// A is accessing the cache file for reading/writing and thread B is trimming
|
||||
// the cache. Let’s also assume using llifstream to open a file and
|
||||
// the cache. Let’s also assume using llifstream to open a file and
|
||||
// boost::filesystem::remove are not atomic (which will be pretty much the
|
||||
// case).
|
||||
|
||||
|
|
@ -150,49 +150,86 @@ void LLDiskCache::purge()
|
|||
LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL;
|
||||
|
||||
// <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
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.6.5
|
||||
6.6.6
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -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?"
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -431,6 +431,7 @@ protected:
|
|||
private:
|
||||
LLUUID mLastRegionID;
|
||||
F64 mNextUpdateTime; //seconds since client start
|
||||
LLTextBox* mTextEstateOwner;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -223,6 +223,7 @@ private:
|
|||
|
||||
void resetUploadOptions();
|
||||
void clearLogTab();
|
||||
void prepareToLoadModel(S32 lod);
|
||||
|
||||
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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() :
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
Loading…
Reference in New Issue