Merge branch 'V2Mesh' of git://github.com/Shyotl/SingularityViewer into future
Conflicts: indra/newview/lltexturefetch.cpp
This commit is contained in:
@@ -96,7 +96,7 @@ set(llcommon_HEADER_FILES
|
||||
indra_constants.h
|
||||
linden_common.h
|
||||
linked_lists.h
|
||||
llaccountingquota.h
|
||||
llaccountingcost.h
|
||||
llagentconstants.h
|
||||
llavatarname.h
|
||||
llapp.h
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @file llaccountingquota.h
|
||||
* @file llaccountingcost.h
|
||||
* @
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
@@ -58,22 +58,28 @@ struct ParcelQuota
|
||||
F32 mParcelCapacity;
|
||||
};
|
||||
|
||||
struct SelectionQuota
|
||||
//SelectionQuota atm does not require a id
|
||||
struct SelectionCost
|
||||
{
|
||||
SelectionQuota( LLUUID localId, F32 renderCost, F32 physicsCost, F32 networkCost, F32 simulationCost )
|
||||
: mLocalId( localId)
|
||||
, mRenderCost( renderCost )
|
||||
, mPhysicsCost( physicsCost )
|
||||
SelectionCost( /*LLTransactionID transactionId, */ F32 physicsCost, F32 networkCost, F32 simulationCost )
|
||||
//: mTransactionId( transactionId)
|
||||
: mPhysicsCost( physicsCost )
|
||||
, mNetworkCost( networkCost )
|
||||
, mSimulationCost( simulationCost )
|
||||
{
|
||||
}
|
||||
SelectionQuota() {}
|
||||
SelectionCost()
|
||||
: mPhysicsCost( 0.0f )
|
||||
, mNetworkCost( 0.0f )
|
||||
, mSimulationCost( 0.0f )
|
||||
{}
|
||||
|
||||
F32 mRenderCost, mPhysicsCost, mNetworkCost, mSimulationCost;
|
||||
LLUUID mLocalId;
|
||||
F32 mPhysicsCost, mNetworkCost, mSimulationCost;
|
||||
//LLTransactionID mTransactionId;
|
||||
};
|
||||
|
||||
typedef enum { Roots = 0 , Prims } eSelectionType;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -35,7 +35,9 @@
|
||||
|
||||
#include <new>
|
||||
#include <cstdlib>
|
||||
#if !LL_WINDOWS
|
||||
#include <stdint.h> // uintptr_t
|
||||
#endif
|
||||
|
||||
#include "llerror.h"
|
||||
|
||||
|
||||
@@ -42,13 +42,15 @@ template <class Object> class LLStrider
|
||||
U8* mBytep;
|
||||
};
|
||||
U32 mSkip;
|
||||
U32 mTypeSize;
|
||||
public:
|
||||
|
||||
LLStrider() { mObjectp = NULL; mSkip = sizeof(Object); }
|
||||
LLStrider() { mObjectp = NULL; mTypeSize = mSkip = sizeof(Object); }
|
||||
~LLStrider() { }
|
||||
|
||||
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
|
||||
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
|
||||
void setTypeSize (S32 typeBytes){ mTypeSize = (typeBytes ? typeBytes : sizeof(Object)); }
|
||||
|
||||
void skip(const U32 index) { mBytep += mSkip*index;}
|
||||
U32 getSkip() const { return mSkip; }
|
||||
@@ -58,18 +60,68 @@ public:
|
||||
Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
|
||||
Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
|
||||
Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
|
||||
void assignArray(U8* buff, size_t elem_size, size_t elem_count)
|
||||
void assignArray(U8* __restrict source, const size_t elem_size, const size_t elem_count)
|
||||
{
|
||||
llassert_always(sizeof(Object) <= elem_size);
|
||||
if(sizeof(Object) == mSkip && sizeof(Object) == elem_size) //No stride. No difference in element size.
|
||||
LLVector4a::memcpyNonAliased16((F32*) mBytep, (F32*) buff, elem_size * elem_count);
|
||||
|
||||
U8* __restrict dest = mBytep; //refer to dest instead of mBytep to benefit from __restrict hint
|
||||
const U32 bytes = elem_size * elem_count; //total bytes to copy from source to dest
|
||||
|
||||
//stride == sizeof(element) implies entire buffer is unstrided and thus memcpy-able, provided source buffer elements match in size.
|
||||
//Because LLStrider is often passed an LLVector3 even if the reprensentation is LLVector4 in the vertex buffer, mTypeSize is set to
|
||||
//the TRUE vbo datatype size via VertexBufferStrider::get
|
||||
if(mTypeSize == mSkip && mTypeSize == elem_size)
|
||||
{
|
||||
if(bytes >= sizeof(LLVector4) * 4) //Should be able to pull at least 3 16byte blocks from this. Smaller isn't really beneficial.
|
||||
{
|
||||
U8* __restrict aligned_source = LL_NEXT_ALIGNED_ADDRESS(source);
|
||||
U8* __restrict aligned_dest = LL_NEXT_ALIGNED_ADDRESS(dest);
|
||||
const U32 source_offset = aligned_source - source; //Offset to first aligned location in source buffer.
|
||||
const U32 dest_offset = aligned_dest - dest; //Offset to first aligned location in dest buffer.
|
||||
llassert_always(source_offset < 16);
|
||||
llassert_always(dest_offset < 16);
|
||||
if(source_offset == dest_offset) //delta to aligned location matches between source and destination! _mm_*_ps should be viable.
|
||||
{
|
||||
const U32 end_offset = (bytes - source_offset) % sizeof(LLVector4); //buffers may not neatly end on a 16byte alignment boundary.
|
||||
const U32 aligned_bytes = bytes - source_offset - end_offset; //how many bytes to copy from aligned start to aligned end.
|
||||
|
||||
llassert_always(aligned_bytes > 0);
|
||||
|
||||
if(source_offset) //memcpy up to the aligned location if needed
|
||||
memcpy(dest,source,source_offset);
|
||||
LLVector4a::memcpyNonAliased16((F32*) aligned_dest, (F32*) aligned_source, aligned_bytes);
|
||||
if(end_offset) //memcpy to the very end if needed.
|
||||
memcpy(aligned_dest+aligned_bytes,aligned_source+aligned_bytes,end_offset);
|
||||
}
|
||||
else //buffers non-uniformly offset from aligned location. Using _mm_*u_ps.
|
||||
{
|
||||
U32 end = bytes/sizeof(LLVector4); //sizeof(LLVector4) = 16 bytes = 128 bits
|
||||
|
||||
llassert_always(end > 0);
|
||||
|
||||
__m128* dst = (__m128*) dest;
|
||||
__m128* src = (__m128*) source;
|
||||
|
||||
for (U32 i = 0; i < end; i++) //copy 128bit chunks
|
||||
{
|
||||
__m128 res = _mm_loadu_ps((F32*)&src[i]);
|
||||
_mm_storeu_ps((F32*)&dst[i], res);
|
||||
}
|
||||
end*=16;//Convert to real byte offset
|
||||
if(end < bytes) //just memcopy the rest
|
||||
memcpy(dest+end,source+end,bytes-end);
|
||||
}
|
||||
}
|
||||
else //Too small. just do a simple memcpy.
|
||||
memcpy(dest,source,bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(U32 i=0;i<elem_count;i++)
|
||||
{
|
||||
memcpy(mBytep,buff,sizeof(Object));
|
||||
mBytep+=mSkip;
|
||||
buff+=elem_size;
|
||||
memcpy(dest,source,sizeof(Object));
|
||||
dest+=mSkip;
|
||||
source+=elem_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1354,13 +1354,3 @@ LLParcel::ECategory category_ui_string_to_category(const std::string& s)
|
||||
// is a distinct option from "None" and "Other"
|
||||
return LLParcel::C_ANY;
|
||||
}
|
||||
|
||||
#if MESH_ENABLED
|
||||
void LLParcel::updateQuota( const LLUUID& objectId, const ParcelQuota& quota )
|
||||
{
|
||||
if ( mID == objectId )
|
||||
{
|
||||
mQuota = quota;
|
||||
}
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
@@ -40,9 +40,6 @@
|
||||
#include "llpermissions.h"
|
||||
#include "lltimer.h"
|
||||
#include "v3math.h"
|
||||
#if MESH_ENABLED
|
||||
#include "llaccountingquota.h"
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
// Grid out of which parcels taken is stepped every 4 meters.
|
||||
const F32 PARCEL_GRID_STEP_METERS = 4.f;
|
||||
@@ -602,10 +599,7 @@ public:
|
||||
BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; }
|
||||
BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; }
|
||||
|
||||
#if MESH_ENABLED
|
||||
void updateQuota( const LLUUID& objectId, const ParcelQuota& quota );
|
||||
const ParcelQuota& getQuota( void ) { return mQuota; }
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
protected:
|
||||
LLUUID mID;
|
||||
LLUUID mOwnerID;
|
||||
@@ -678,9 +672,6 @@ protected:
|
||||
BOOL mRegionPushOverride;
|
||||
BOOL mRegionDenyAnonymousOverride;
|
||||
BOOL mRegionDenyAgeUnverifiedOverride;
|
||||
#if MESH_ENABLED
|
||||
ParcelQuota mQuota;
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
public:
|
||||
// HACK, make private
|
||||
|
||||
@@ -92,6 +92,9 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;
|
||||
std::string LLCurl::sCAPath;
|
||||
std::string LLCurl::sCAFile;
|
||||
|
||||
bool LLCurl::sMultiThreaded = false;
|
||||
static U32 sMainThreadID = 0;
|
||||
|
||||
void check_curl_code(CURLcode code)
|
||||
{
|
||||
if (code != CURLE_OK)
|
||||
@@ -250,7 +253,7 @@ public:
|
||||
U32 report(CURLcode);
|
||||
void getTransferInfo(LLCurl::TransferInfo* info);
|
||||
|
||||
void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, bool post = false);
|
||||
void prepRequest(const std::string& url, const std::vector<std::string>& headers, ResponderPtr, S32 time_out = 0, bool post = false);
|
||||
|
||||
const char* getErrorBuffer();
|
||||
|
||||
@@ -549,7 +552,7 @@ size_t curlHeaderCallback(void* data, size_t size, size_t nmemb, void* user_data
|
||||
|
||||
void LLCurl::Easy::prepRequest(const std::string& url,
|
||||
const std::vector<std::string>& headers,
|
||||
ResponderPtr responder, bool post)
|
||||
ResponderPtr responder, S32 time_out, bool post)
|
||||
{
|
||||
resetState();
|
||||
|
||||
@@ -599,7 +602,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
|
||||
|
||||
//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
|
||||
setopt(CURLOPT_SSL_VERIFYHOST, 0);
|
||||
setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
|
||||
setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
|
||||
|
||||
setoptString(CURLOPT_URL, url);
|
||||
|
||||
@@ -642,6 +645,7 @@ public:
|
||||
|
||||
S32 process();
|
||||
void perform();
|
||||
void doPerform();
|
||||
|
||||
virtual void run();
|
||||
|
||||
@@ -654,6 +658,7 @@ public:
|
||||
|
||||
LLCondition* mSignal;
|
||||
bool mQuitting;
|
||||
bool mThreaded;
|
||||
|
||||
private:
|
||||
void easyFree(Easy*);
|
||||
@@ -675,7 +680,16 @@ LLCurl::Multi::Multi()
|
||||
mPerformState(PERFORM_STATE_READY)
|
||||
{
|
||||
mQuitting = false;
|
||||
mSignal = new LLCondition;
|
||||
|
||||
mThreaded = LLCurl::sMultiThreaded && LLThread::currentID() == sMainThreadID;
|
||||
if (mThreaded)
|
||||
{
|
||||
mSignal = new LLCondition;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSignal = NULL;
|
||||
}
|
||||
|
||||
mCurlMultiHandle = curl_multi_init();
|
||||
if (!mCurlMultiHandle)
|
||||
@@ -722,16 +736,25 @@ CURLMsg* LLCurl::Multi::info_read(S32* msgs_in_queue)
|
||||
|
||||
void LLCurl::Multi::perform()
|
||||
{
|
||||
mSignal->lock();
|
||||
if (mPerformState == PERFORM_STATE_READY)
|
||||
if (mThreaded)
|
||||
{
|
||||
mSignal->signal();
|
||||
mSignal->lock();
|
||||
if (mPerformState == PERFORM_STATE_READY)
|
||||
{
|
||||
mSignal->signal();
|
||||
}
|
||||
mSignal->unlock();
|
||||
}
|
||||
mSignal->unlock();
|
||||
else
|
||||
{
|
||||
doPerform();
|
||||
}
|
||||
}
|
||||
|
||||
void LLCurl::Multi::run()
|
||||
{
|
||||
llassert(mThreaded);
|
||||
|
||||
mSignal->lock();
|
||||
while (!mQuitting)
|
||||
{
|
||||
@@ -739,26 +762,31 @@ void LLCurl::Multi::run()
|
||||
mPerformState = PERFORM_STATE_PERFORMING;
|
||||
if (!mQuitting)
|
||||
{
|
||||
S32 q = 0;
|
||||
for (S32 call_count = 0;
|
||||
call_count < MULTI_PERFORM_CALL_REPEAT;
|
||||
call_count += 1)
|
||||
{
|
||||
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
|
||||
if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
|
||||
{
|
||||
check_curl_multi_code(code);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
mQueued = q;
|
||||
mPerformState = PERFORM_STATE_COMPLETED;
|
||||
doPerform();
|
||||
}
|
||||
}
|
||||
mSignal->unlock();
|
||||
}
|
||||
|
||||
void LLCurl::Multi::doPerform()
|
||||
{
|
||||
S32 q = 0;
|
||||
for (S32 call_count = 0;
|
||||
call_count < MULTI_PERFORM_CALL_REPEAT;
|
||||
call_count += 1)
|
||||
{
|
||||
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
|
||||
if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
|
||||
{
|
||||
check_curl_multi_code(code);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
mQueued = q;
|
||||
mPerformState = PERFORM_STATE_COMPLETED;
|
||||
}
|
||||
|
||||
S32 LLCurl::Multi::process()
|
||||
{
|
||||
perform();
|
||||
@@ -883,16 +911,21 @@ LLCurlRequest::~LLCurlRequest()
|
||||
for (curlmulti_set_t::iterator iter = mMultiSet.begin(); iter != mMultiSet.end(); ++iter)
|
||||
{
|
||||
LLCurl::Multi* multi = *iter;
|
||||
multi->mSignal->lock();
|
||||
multi->mQuitting = true;
|
||||
while (!multi->isStopped())
|
||||
{
|
||||
multi->mSignal->signal();
|
||||
multi->mSignal->unlock();
|
||||
apr_sleep(1000);
|
||||
if (multi->mThreaded)
|
||||
multi->mSignal->lock();
|
||||
multi->mQuitting = true;
|
||||
if (multi->mThreaded)
|
||||
{
|
||||
while (!multi->isStopped())
|
||||
{
|
||||
multi->mSignal->signal();
|
||||
multi->mSignal->unlock();
|
||||
apr_sleep(1000);
|
||||
multi->mSignal->lock();
|
||||
}
|
||||
}
|
||||
multi->mSignal->unlock();
|
||||
if (multi->mThreaded)
|
||||
multi->mSignal->unlock();
|
||||
}
|
||||
for_each(mMultiSet.begin(), mMultiSet.end(), DeletePointer());
|
||||
}
|
||||
@@ -901,7 +934,10 @@ void LLCurlRequest::addMulti()
|
||||
{
|
||||
llassert_always(mThreadID == LLThread::currentID());
|
||||
LLCurl::Multi* multi = new LLCurl::Multi();
|
||||
multi->start();
|
||||
if (multi->mThreaded)
|
||||
{
|
||||
multi->start();
|
||||
}
|
||||
mMultiSet.insert(multi);
|
||||
mActiveMulti = multi;
|
||||
mActiveRequestCount = 0;
|
||||
@@ -963,14 +999,14 @@ bool LLCurlRequest::getByteRange(const std::string& url,
|
||||
bool LLCurlRequest::post(const std::string& url,
|
||||
const headers_t& headers,
|
||||
const LLSD& data,
|
||||
LLCurl::ResponderPtr responder)
|
||||
LLCurl::ResponderPtr responder, S32 time_out)
|
||||
{
|
||||
LLCurl::Easy* easy = allocEasy();
|
||||
if (!easy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
easy->prepRequest(url, headers, responder);
|
||||
easy->prepRequest(url, headers, responder, time_out);
|
||||
|
||||
LLSDSerialize::toXML(data, easy->getInput());
|
||||
S32 bytes = easy->getInput().str().length();
|
||||
@@ -990,14 +1026,14 @@ bool LLCurlRequest::post(const std::string& url,
|
||||
bool LLCurlRequest::post(const std::string& url,
|
||||
const headers_t& headers,
|
||||
const std::string& data,
|
||||
LLCurl::ResponderPtr responder)
|
||||
LLCurl::ResponderPtr responder, S32 time_out)
|
||||
{
|
||||
LLCurl::Easy* easy = allocEasy();
|
||||
if (!easy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
easy->prepRequest(url, headers, responder);
|
||||
easy->prepRequest(url, headers, responder, time_out);
|
||||
|
||||
easy->getInput().write(data.data(), data.size());
|
||||
S32 bytes = easy->getInput().str().length();
|
||||
@@ -1031,16 +1067,21 @@ S32 LLCurlRequest::process()
|
||||
if (multi != mActiveMulti && tres == 0 && multi->mQueued == 0)
|
||||
{
|
||||
mMultiSet.erase(curiter);
|
||||
multi->mSignal->lock();
|
||||
if (multi->mThreaded)
|
||||
multi->mSignal->lock();
|
||||
multi->mQuitting = true;
|
||||
while (!multi->isStopped())
|
||||
if (multi->mThreaded)
|
||||
{
|
||||
multi->mSignal->signal();
|
||||
multi->mSignal->unlock();
|
||||
apr_sleep(1000);
|
||||
multi->mSignal->unlock();
|
||||
while (!multi->isStopped())
|
||||
{
|
||||
multi->mSignal->signal();
|
||||
multi->mSignal->unlock();
|
||||
apr_sleep(1000);
|
||||
multi->mSignal->unlock();
|
||||
}
|
||||
}
|
||||
multi->mSignal->unlock();
|
||||
if (multi->mThreaded)
|
||||
multi->mSignal->unlock();
|
||||
|
||||
delete multi;
|
||||
}
|
||||
@@ -1059,6 +1100,10 @@ S32 LLCurlRequest::getQueued()
|
||||
curlmulti_set_t::iterator curiter = iter++;
|
||||
LLCurl::Multi* multi = *curiter;
|
||||
queued += multi->mQueued;
|
||||
if (multi->mPerformState != LLCurl::Multi::PERFORM_STATE_READY)
|
||||
{
|
||||
++queued;
|
||||
}
|
||||
}
|
||||
return queued;
|
||||
}
|
||||
@@ -1072,7 +1117,10 @@ LLCurlEasyRequest::LLCurlEasyRequest()
|
||||
mResultReturned(false)
|
||||
{
|
||||
mMulti = new LLCurl::Multi();
|
||||
mMulti->start();
|
||||
if (mMulti->mThreaded)
|
||||
{
|
||||
mMulti->start();
|
||||
}
|
||||
mEasy = mMulti->allocEasy();
|
||||
if (mEasy)
|
||||
{
|
||||
@@ -1083,16 +1131,21 @@ LLCurlEasyRequest::LLCurlEasyRequest()
|
||||
|
||||
LLCurlEasyRequest::~LLCurlEasyRequest()
|
||||
{
|
||||
mMulti->mSignal->lock();
|
||||
mMulti->mQuitting = true;
|
||||
while (!mMulti->isStopped())
|
||||
{
|
||||
mMulti->mSignal->signal();
|
||||
mMulti->mSignal->unlock();
|
||||
apr_sleep(1000);
|
||||
if (mMulti->mThreaded)
|
||||
mMulti->mSignal->lock();
|
||||
mMulti->mQuitting = true;
|
||||
if (mMulti->mThreaded)
|
||||
{
|
||||
while (!mMulti->isStopped())
|
||||
{
|
||||
mMulti->mSignal->signal();
|
||||
mMulti->mSignal->unlock();
|
||||
apr_sleep(1000);
|
||||
mMulti->mSignal->lock();
|
||||
}
|
||||
}
|
||||
mMulti->mSignal->unlock();
|
||||
if (mMulti->mThreaded)
|
||||
mMulti->mSignal->unlock();
|
||||
delete mMulti;
|
||||
}
|
||||
|
||||
@@ -1287,8 +1340,10 @@ unsigned long LLCurl::ssl_thread_id(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void LLCurl::initClass()
|
||||
void LLCurl::initClass(bool multi_threaded)
|
||||
{
|
||||
sMainThreadID = LLThread::currentID();
|
||||
sMultiThreaded = multi_threaded;
|
||||
// Do not change this "unless you are familiar with and mean to control
|
||||
// internal operations of libcurl"
|
||||
// - http://curl.haxx.se/libcurl/c/curl_global_init.html
|
||||
|
||||
@@ -61,6 +61,8 @@ public:
|
||||
class Easy;
|
||||
class Multi;
|
||||
|
||||
static bool sMultiThreaded;
|
||||
|
||||
struct TransferInfo
|
||||
{
|
||||
TransferInfo() : mSizeDownload(0.0), mTotalTime(0.0), mSpeedDownload(0.0) {}
|
||||
@@ -164,7 +166,7 @@ public:
|
||||
/**
|
||||
* @ brief Initialize LLCurl class
|
||||
*/
|
||||
static void initClass();
|
||||
static void initClass(bool multi_threaded = false);
|
||||
|
||||
/**
|
||||
* @ brief Cleanup LLCurl class
|
||||
@@ -206,8 +208,8 @@ public:
|
||||
|
||||
void get(const std::string& url, LLCurl::ResponderPtr responder);
|
||||
bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder);
|
||||
bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder);
|
||||
bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder);
|
||||
bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder, S32 time_out = 0);
|
||||
bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder, S32 time_out = 0);
|
||||
|
||||
S32 process();
|
||||
S32 getQueued();
|
||||
|
||||
@@ -1695,6 +1695,19 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO
|
||||
|
||||
LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
|
||||
{
|
||||
//1. If a vertex has been weighted then we'll find it via pos and return it's weight list
|
||||
weight_map::iterator iterPos = mSkinWeights.begin();
|
||||
weight_map::iterator iterEnd = mSkinWeights.end();
|
||||
|
||||
for ( ; iterPos!=iterEnd; ++iterPos )
|
||||
{
|
||||
if ( jointPositionalLookup( iterPos->first, pos ) )
|
||||
{
|
||||
return iterPos->second;
|
||||
}
|
||||
}
|
||||
|
||||
//2. Otherwise we'll use the older implementation
|
||||
weight_map::iterator iter = mSkinWeights.find(pos);
|
||||
|
||||
if (iter != mSkinWeights.end())
|
||||
|
||||
@@ -223,20 +223,17 @@ public:
|
||||
};
|
||||
|
||||
|
||||
struct JointPositionalCompare
|
||||
//Are the doubles the same w/in epsilon specified tolerance
|
||||
bool areEqual( double a, double b )
|
||||
{
|
||||
//Are the doubles the same w/in epsilon specified tolerance
|
||||
bool areEqual( double a, double b )
|
||||
{
|
||||
const float epsilon = 1e-5f;
|
||||
return (abs((int)(a - b)) < epsilon) && (a < b);
|
||||
}
|
||||
//Make sure that we return false for any values that are within the tolerance for equivalence
|
||||
bool operator() ( const LLVector3& a, const LLVector3& b )
|
||||
{
|
||||
return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? false : true;
|
||||
}
|
||||
};
|
||||
const float epsilon = 1e-5f;
|
||||
return (fabs((a - b)) < epsilon) ? true : false ;
|
||||
}
|
||||
//Make sure that we return false for any values that are within the tolerance for equivalence
|
||||
bool jointPositionalLookup( const LLVector3& a, const LLVector3& b )
|
||||
{
|
||||
return ( areEqual( a[0],b[0]) && areEqual( a[1],b[1] ) && areEqual( a[2],b[2]) ) ? true : false;
|
||||
}
|
||||
|
||||
//copy of position array for this model -- mPosition[idx].mV[X,Y,Z]
|
||||
std::vector<LLVector3> mPosition;
|
||||
|
||||
@@ -66,6 +66,7 @@ BOOL LLVertexBuffer::sIBOActive = FALSE;
|
||||
U32 LLVertexBuffer::sAllocatedBytes = 0;
|
||||
BOOL LLVertexBuffer::sMapped = FALSE;
|
||||
BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
|
||||
U32 LLVertexBuffer::sForceStrideMode = 0;
|
||||
BOOL LLVertexBuffer::sOmitBlank = FALSE;
|
||||
BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
|
||||
S32 LLVertexBuffer::sWeight4Loc = -1;
|
||||
@@ -263,7 +264,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
|
||||
void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
|
||||
{
|
||||
U32 count = pos.size();
|
||||
llassert(norm.size() >= pos.size());
|
||||
llassert_always(norm.size() >= pos.size());
|
||||
llassert_always(count > 0) ;
|
||||
|
||||
unbind();
|
||||
|
||||
@@ -448,7 +450,7 @@ void LLVertexBuffer::clientCopy(F64 max_time)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage, bool strided) :
|
||||
LLRefCount(),
|
||||
|
||||
mNumVerts(0),
|
||||
@@ -466,7 +468,9 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
mFilthy(FALSE),
|
||||
mEmpty(TRUE),
|
||||
mResized(FALSE),
|
||||
mDynamicSize(FALSE)
|
||||
mDynamicSize(FALSE),
|
||||
mIsStrided(strided),
|
||||
mStride(0)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (!sEnableVBOs)
|
||||
@@ -483,20 +487,27 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
|
||||
{
|
||||
mUsage = GL_STREAM_DRAW_ARB;
|
||||
}
|
||||
|
||||
S32 stride = calcStride(typemask, mOffsets);
|
||||
|
||||
//zero out offsets
|
||||
for (U32 i = 0; i < TYPE_MAX; i++)
|
||||
{
|
||||
mOffsets[i] = 0;
|
||||
}
|
||||
|
||||
mTypeMask = typemask;
|
||||
mStride = stride;
|
||||
mSize = 0;
|
||||
mAlignedOffset = 0;
|
||||
mAlignedIndexOffset = 0;
|
||||
|
||||
if(sForceStrideMode)
|
||||
mIsStrided = sForceStrideMode == 1;
|
||||
|
||||
sCount++;
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
|
||||
S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices)
|
||||
{
|
||||
S32 stride = 0;
|
||||
S32 offset = 0;
|
||||
for (S32 i=0; i<TYPE_MAX; i++)
|
||||
{
|
||||
U32 mask = 1<<i;
|
||||
@@ -504,13 +515,50 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets)
|
||||
{
|
||||
if (offsets)
|
||||
{
|
||||
offsets[i] = stride;
|
||||
offsets[i] = offset;
|
||||
}
|
||||
stride += sTypeSize[i];
|
||||
if(mIsStrided)
|
||||
{
|
||||
offset += sTypeSize[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += LLVertexBuffer::sTypeSize[i]*num_vertices;
|
||||
offset = (offset + 0xF) & ~0xF;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(mIsStrided)
|
||||
{
|
||||
mStride = offset;
|
||||
return mStride * num_vertices + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
mStride = -1; //Stride is invalid with unstrided arrays.
|
||||
return offset + 16;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
S32 LLVertexBuffer::calcVertexSize(const U32& typemask)
|
||||
{
|
||||
S32 size = 0;
|
||||
for (S32 i = 0; i < TYPE_MAX; i++)
|
||||
{
|
||||
U32 mask = 1<<i;
|
||||
if (typemask & mask)
|
||||
{
|
||||
size += LLVertexBuffer::sTypeSize[i];
|
||||
}
|
||||
}
|
||||
|
||||
return stride;
|
||||
return size;
|
||||
}
|
||||
|
||||
S32 LLVertexBuffer::getSize() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
// protected, use unref()
|
||||
@@ -750,7 +798,7 @@ void LLVertexBuffer::updateNumVerts(S32 nverts)
|
||||
}
|
||||
mNumVerts = nverts;
|
||||
}
|
||||
|
||||
mSize = calcOffsets(mTypeMask, mOffsets, mNumVerts);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::updateNumIndices(S32 nindices)
|
||||
@@ -958,7 +1006,7 @@ void LLVertexBuffer::allocateClientIndexBuffer()
|
||||
}
|
||||
|
||||
// Map for data access
|
||||
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
||||
volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mFinal)
|
||||
@@ -1031,10 +1079,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
|
||||
sMappedCount++;
|
||||
}
|
||||
|
||||
return mMappedData;
|
||||
return mMappedData+mOffsets[type]+ (mIsStrided ? mStride : sTypeSize[type])*index;
|
||||
}
|
||||
|
||||
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mFinal)
|
||||
@@ -1065,6 +1113,9 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
|
||||
}
|
||||
|
||||
llassert(src != NULL);
|
||||
|
||||
|
||||
mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS<U8>(src);
|
||||
mAlignedIndexOffset = mMappedIndexData - src;
|
||||
stop_glerror();
|
||||
@@ -1095,7 +1146,7 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 access)
|
||||
sMappedCount++;
|
||||
}
|
||||
|
||||
return mMappedIndexData ;
|
||||
return mMappedIndexData + sizeof(U16)*index;
|
||||
}
|
||||
|
||||
void LLVertexBuffer::unmapBuffer(S32 type)
|
||||
@@ -1182,7 +1233,7 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
{
|
||||
if (type == LLVertexBuffer::TYPE_INDEX)
|
||||
{
|
||||
volatile U8* ptr = vbo.mapIndexBuffer();
|
||||
volatile U8* ptr = vbo.mapIndexBuffer(index);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
@@ -1190,14 +1241,16 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(ptr + index*sizeof(T));
|
||||
strider = (T*)ptr;
|
||||
strider.setStride(0);
|
||||
strider.setTypeSize(0);
|
||||
return TRUE;
|
||||
}
|
||||
else if (vbo.hasDataType(type))
|
||||
{
|
||||
S32 stride = vbo.getStride();
|
||||
volatile U8* ptr = vbo.mapVertexBuffer(type);
|
||||
S32 stride = vbo.getStride(type);
|
||||
|
||||
volatile U8* ptr = vbo.mapVertexBuffer(type,index);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
@@ -1205,8 +1258,11 @@ template <class T,S32 type> struct VertexBufferStrider
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
strider = (T*)(ptr + vbo.getOffset(type) + index*stride);
|
||||
|
||||
strider = (T*)ptr;
|
||||
|
||||
strider.setStride(stride);
|
||||
strider.setTypeSize(LLVertexBuffer::sTypeSize[type]);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
@@ -1269,25 +1325,6 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in
|
||||
return VertexBufferStrider<LLVector4,TYPE_CLOTHWEIGHT>::get(*this, strider, index);
|
||||
}
|
||||
|
||||
void LLVertexBuffer::setStride(S32 type, S32 new_stride)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
if (mNumVerts)
|
||||
{
|
||||
llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl;
|
||||
}
|
||||
// This code assumes that setStride() will only be called once per VBO per type.
|
||||
S32 delta = new_stride - sTypeSize[type];
|
||||
for (S32 i=type+1; i<TYPE_MAX; i++)
|
||||
{
|
||||
if (mTypeMask & (1<<i))
|
||||
{
|
||||
mOffsets[i] += delta;
|
||||
}
|
||||
}
|
||||
mStride += delta;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Set for rendering
|
||||
@@ -1485,7 +1522,6 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
||||
LLMemType mt(LLMemType::MTYPE_VERTEX_DATA);
|
||||
stop_glerror();
|
||||
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
|
||||
S32 stride = mStride;
|
||||
|
||||
if ((data_mask & mTypeMask) != data_mask)
|
||||
{
|
||||
@@ -1518,68 +1554,60 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
|
||||
|
||||
if (data_mask & MAP_NORMAL)
|
||||
{
|
||||
glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD3)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE3_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD3]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD3), (void*)(base + mOffsets[TYPE_TEXCOORD3]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD2)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD2), (void*)(base + mOffsets[TYPE_TEXCOORD2]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD1)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(3,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD0)
|
||||
{
|
||||
glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
}
|
||||
if (data_mask & MAP_COLOR)
|
||||
{
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR]));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
|
||||
{
|
||||
glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, stride, (void*)(base+mOffsets[TYPE_WEIGHT4]));
|
||||
glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_CLOTHWEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, stride, (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
{
|
||||
glVertexPointer(3,GL_FLOAT, stride, (void*)(base + 0));
|
||||
glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
|
||||
}
|
||||
|
||||
llglassertok();
|
||||
}
|
||||
|
||||
void LLVertexBuffer::markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count)
|
||||
{
|
||||
// TODO: use GL_APPLE_flush_buffer_range here
|
||||
/*if (useVBOs() && !mFilthy)
|
||||
{
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ public:
|
||||
static S32 sWeight4Loc;
|
||||
|
||||
static BOOL sUseStreamDraw;
|
||||
static U32 sForceStrideMode;
|
||||
static BOOL sOmitBlank;
|
||||
static BOOL sPreferStreamDraw;
|
||||
|
||||
@@ -102,11 +103,15 @@ public:
|
||||
static void unbind(); //unbind any bound vertex buffer
|
||||
|
||||
//get the size of a vertex with the given typemask
|
||||
//if offsets is not NULL, its contents will be filled
|
||||
//with the offset of each vertex component in the buffer,
|
||||
// indexed by the following enum
|
||||
static S32 calcStride(const U32& typemask, S32* offsets = NULL);
|
||||
static S32 calcVertexSize(const U32& typemask);
|
||||
|
||||
//get the size of a buffer with the given typemask and vertex count
|
||||
//fill offsets with the offset of each vertex component array into the buffer
|
||||
// indexed by the following enum
|
||||
//If strided, num_vertices will be ignored.
|
||||
S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
|
||||
|
||||
|
||||
enum {
|
||||
TYPE_VERTEX,
|
||||
TYPE_NORMAL,
|
||||
@@ -162,11 +167,11 @@ protected:
|
||||
void allocateClientIndexBuffer() ;
|
||||
|
||||
public:
|
||||
LLVertexBuffer(U32 typemask, S32 usage);
|
||||
LLVertexBuffer(U32 typemask, S32 usage, bool strided=true);
|
||||
|
||||
// map for data access
|
||||
volatile U8* mapVertexBuffer(S32 type = -1, S32 access = -1);
|
||||
volatile U8* mapIndexBuffer(S32 access = -1);
|
||||
volatile U8* mapVertexBuffer(S32 type, S32 index);
|
||||
volatile U8* mapIndexBuffer(S32 index);
|
||||
|
||||
// set for rendering
|
||||
virtual void setBuffer(U32 data_mask, S32 type = -1); // calls setupVertexBuffer() if data_mask is not 0
|
||||
@@ -201,20 +206,16 @@ public:
|
||||
|
||||
volatile U8* getIndicesPointer() const { return useVBOs() ? (U8*) mAlignedIndexOffset : mMappedIndexData; }
|
||||
volatile U8* getVerticesPointer() const { return useVBOs() ? (U8*) mAlignedOffset : mMappedData; }
|
||||
S32 getStride() const { return mStride; }
|
||||
S32 getTypeMask() const { return mTypeMask; }
|
||||
BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; }
|
||||
S32 getSize() const { return mNumVerts*mStride; }
|
||||
S32 getStride(S32 type) const { return mIsStrided ? mStride : sTypeSize[type]; }
|
||||
U32 getTypeMask() const { return mTypeMask; }
|
||||
bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); }
|
||||
S32 getSize() const;
|
||||
S32 getIndicesSize() const { return mNumIndices * sizeof(U16); }
|
||||
volatile U8* getMappedData() const { return mMappedData; }
|
||||
volatile U8* getMappedIndices() const { return mMappedIndexData; }
|
||||
S32 getOffset(S32 type) const { return mOffsets[type]; }
|
||||
S32 getUsage() const { return mUsage; }
|
||||
|
||||
void setStride(S32 type, S32 new_stride);
|
||||
|
||||
void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
|
||||
|
||||
void draw(U32 mode, U32 count, U32 indices_offset) const;
|
||||
void drawArrays(U32 mode, U32 offset, U32 count) const;
|
||||
void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
|
||||
@@ -232,7 +233,9 @@ protected:
|
||||
|
||||
ptrdiff_t mAlignedOffset;
|
||||
ptrdiff_t mAlignedIndexOffset;
|
||||
S32 mStride;
|
||||
bool mIsStrided;
|
||||
S32 mStride; // Vertex size.
|
||||
S32 mSize; // Full array size
|
||||
U32 mTypeMask;
|
||||
S32 mUsage; // GL usage
|
||||
U32 mGLBuffer; // GL VBO handle
|
||||
|
||||
@@ -100,7 +100,7 @@ set(viewer_SOURCE_FILES
|
||||
jcfloaterareasearch.cpp
|
||||
chatbar_as_cmdline.cpp
|
||||
qtoolalign.cpp
|
||||
llaccountingquotamanager.cpp
|
||||
llaccountingcostmanager.cpp
|
||||
llagent.cpp
|
||||
llagentaccess.cpp
|
||||
llagentcamera.cpp
|
||||
@@ -580,7 +580,7 @@ set(viewer_HEADER_FILES
|
||||
lgghunspell_wrapper.h
|
||||
chatbar_as_cmdline.h
|
||||
qtoolalign.h
|
||||
llaccountingquotamanager.h
|
||||
llaccountingcostmanager.h
|
||||
llagent.h
|
||||
llagentaccess.h
|
||||
llagentcamera.h
|
||||
@@ -1613,6 +1613,13 @@ endif (LL_TESTS)
|
||||
if (WINDOWS)
|
||||
|
||||
get_target_property(BUILT_LLCOMMON llcommon LOCATION)
|
||||
|
||||
set_target_properties(llcommon
|
||||
PROPERTIES
|
||||
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT"
|
||||
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${VIEWER_BINARY_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
|
||||
@@ -475,7 +475,21 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ResetFocusOnSelfClick</key>
|
||||
<key>ShyotlRenderVBOStrideMode</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>0 = Standard behavior
|
||||
1 = Force strided VBOs
|
||||
2 = Force unstrided(dense) VBOs</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
|
||||
<key>ResetFocusOnSelfClick</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Setting this to TRUE resets your camera when you left-click your avatar</string>
|
||||
@@ -3758,10 +3772,21 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>CurlUseMultipleThreads</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use background threads for executing curl_multi_perform (requires restart)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>Cursor3D</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Tread Joystick values as absolute positions (not deltas).</string>
|
||||
<string>Treat Joystick values as absolute positions (not deltas).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
||||
173
indra/newview/llaccountingcostmanager.cpp
Normal file
173
indra/newview/llaccountingcostmanager.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* @file LLAccountingQuotaManager.cpp
|
||||
* @ Handles the setting and accessing for costs associated with mesh
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#if MESH_ENABLED
|
||||
#include "llaccountingcostmanager.h"
|
||||
#include "llagent.h"
|
||||
#include "llcurl.h"
|
||||
#include "llhttpclient.h"
|
||||
|
||||
//===============================================================================
|
||||
LLAccountingCostManager::LLAccountingCostManager()
|
||||
{
|
||||
}
|
||||
//===============================================================================
|
||||
class LLAccountingCostResponder : public LLCurl::Responder
|
||||
{
|
||||
public:
|
||||
LLAccountingCostResponder( const LLSD& objectIDs )
|
||||
: mObjectIDs( objectIDs )
|
||||
{
|
||||
}
|
||||
|
||||
void clearPendingRequests ( void )
|
||||
{
|
||||
for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
|
||||
{
|
||||
LLAccountingCostManager::getInstance()->removePendingObject( iter->asUUID() );
|
||||
}
|
||||
}
|
||||
|
||||
void error( U32 statusNum, const std::string& reason )
|
||||
{
|
||||
llwarns << "Transport error "<<reason<<llendl;
|
||||
clearPendingRequests();
|
||||
}
|
||||
|
||||
void result( const LLSD& content )
|
||||
{
|
||||
//Check for error
|
||||
if ( !content.isMap() || content.has("error") )
|
||||
{
|
||||
llwarns << "Error on fetched data"<< llendl;
|
||||
clearPendingRequests();
|
||||
return;
|
||||
}
|
||||
|
||||
bool containsSelection = content.has("selected");
|
||||
if ( containsSelection )
|
||||
{
|
||||
S32 dataCount = content["selected"].size();
|
||||
|
||||
for(S32 i = 0; i < dataCount; i++)
|
||||
{
|
||||
|
||||
F32 physicsCost = 0.0f;
|
||||
F32 networkCost = 0.0f;
|
||||
F32 simulationCost = 0.0f;
|
||||
|
||||
//LLTransactionID transactionID;
|
||||
|
||||
//transactionID = content["selected"][i]["local_id"].asUUID();
|
||||
physicsCost = content["selected"][i]["physics"].asReal();
|
||||
networkCost = content["selected"][i]["streaming"].asReal();
|
||||
simulationCost = content["selected"][i]["simulation"].asReal();
|
||||
|
||||
SelectionCost selectionCost( /*transactionID,*/ physicsCost, networkCost, simulationCost );
|
||||
|
||||
//How do you want to handle the updating of the invoking object/ui element?
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//List of posted objects
|
||||
LLSD mObjectIDs;
|
||||
};
|
||||
//===============================================================================
|
||||
void LLAccountingCostManager::fetchCosts( eSelectionType selectionType, const std::string& url )
|
||||
{
|
||||
// Invoking system must have already determined capability availability
|
||||
if ( !url.empty() )
|
||||
{
|
||||
LLSD objectList;
|
||||
U32 objectIndex = 0;
|
||||
|
||||
IDIt IDIter = mObjectList.begin();
|
||||
IDIt IDIterEnd = mObjectList.end();
|
||||
|
||||
for ( ; IDIter != IDIterEnd; ++IDIter )
|
||||
{
|
||||
// Check to see if a request for this object has already been made.
|
||||
if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() )
|
||||
{
|
||||
mObjectList.insert( *IDIter );
|
||||
objectList[objectIndex++] = *IDIter;
|
||||
}
|
||||
}
|
||||
|
||||
mObjectList.clear();
|
||||
|
||||
//Post results
|
||||
if ( objectList.size() > 0 )
|
||||
{
|
||||
std::string keystr;
|
||||
if ( selectionType == Roots )
|
||||
{
|
||||
keystr="selected_roots";
|
||||
}
|
||||
else
|
||||
if ( selectionType == Prims )
|
||||
{
|
||||
keystr="prim_roots";
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos<<"Invalid selection type "<<llendl;
|
||||
mObjectList.clear();
|
||||
mPendingObjectQuota.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
LLSD dataToPost = LLSD::emptyMap();
|
||||
dataToPost[keystr.c_str()] = objectList;
|
||||
|
||||
LLHTTPClient::post( url, dataToPost, new LLAccountingCostResponder( objectList ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//url was empty - warn & continue
|
||||
llwarns<<"Supplied url is empty "<<llendl;
|
||||
mObjectList.clear();
|
||||
mPendingObjectQuota.clear();
|
||||
}
|
||||
}
|
||||
//===============================================================================
|
||||
void LLAccountingCostManager::addObject( const LLUUID& objectID )
|
||||
{
|
||||
mObjectList.insert( objectID );
|
||||
}
|
||||
//===============================================================================
|
||||
void LLAccountingCostManager::removePendingObject( const LLUUID& objectID )
|
||||
{
|
||||
mPendingObjectQuota.erase( objectID );
|
||||
}
|
||||
//===============================================================================
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
@@ -27,29 +27,29 @@
|
||||
#ifndef LL_ACCOUNTINGQUOTAMANAGER_H
|
||||
#define LL_ACCOUNTINGQUOTAMANAGER_H
|
||||
//===============================================================================
|
||||
#include "llaccountingquota.h"
|
||||
#include "llaccountingcost.h"
|
||||
//===============================================================================
|
||||
class LLAccountingQuotaManager : public LLSingleton<LLAccountingQuotaManager>
|
||||
class LLAccountingCostManager : public LLSingleton<LLAccountingCostManager>
|
||||
{
|
||||
public:
|
||||
//Ctor
|
||||
LLAccountingQuotaManager();
|
||||
LLAccountingCostManager();
|
||||
//Store an object that will be eventually fetched
|
||||
void updateObjectCost( const LLUUID& objectID );
|
||||
void addObject( const LLUUID& objectID );
|
||||
//Request quotas for object list
|
||||
void fetchQuotas( const std::string& url );
|
||||
void fetchCosts( eSelectionType selectionType, const std::string& url );
|
||||
//Delete a specific object from the pending list
|
||||
void removePendingObjectQuota( const LLUUID& objectID );
|
||||
void removePendingObject( const LLUUID& objectID );
|
||||
|
||||
private:
|
||||
//Set of objects that need to update their cost
|
||||
std::set<LLUUID> mUpdateObjectQuota;
|
||||
//During fetchQuota we move object into a the pending set to signify that
|
||||
//Set of objects that will be used to generate a cost
|
||||
std::set<LLUUID> mObjectList;
|
||||
//During fetchCosts we move object into a the pending set to signify that
|
||||
//a fetch has been instigated.
|
||||
std::set<LLUUID> mPendingObjectQuota;
|
||||
typedef std::set<LLUUID>::iterator IDIt;
|
||||
};
|
||||
//===============================================================================
|
||||
|
||||
#endif // LLACCOUNTINGQUOTAMANAGER
|
||||
#endif // LLACCOUNTINGCOSTMANAGER
|
||||
|
||||
@@ -1,281 +0,0 @@
|
||||
/**
|
||||
* @file LLAccountingQuotaManager.cpp
|
||||
* @ Handles the setting and accessing for costs associated with mesh
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#if MESH_ENABLED
|
||||
#include "llaccountingquotamanager.h"
|
||||
#include "llagent.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
#include "llparcel.h"
|
||||
|
||||
//===============================================================================
|
||||
LLAccountingQuotaManager::LLAccountingQuotaManager()
|
||||
{
|
||||
}
|
||||
//===============================================================================
|
||||
class LLAccountingQuotaResponder : public LLCurl::Responder
|
||||
{
|
||||
public:
|
||||
LLAccountingQuotaResponder( const LLSD& objectIDs )
|
||||
: mObjectIDs( objectIDs )
|
||||
{
|
||||
}
|
||||
|
||||
void clearPendingRequests ( void )
|
||||
{
|
||||
for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
|
||||
{
|
||||
LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( iter->asUUID() );
|
||||
}
|
||||
}
|
||||
|
||||
void error( U32 statusNum, const std::string& reason )
|
||||
{
|
||||
llwarns << "Transport error "<<reason<<llendl;
|
||||
//prep#do we really want to remove all because of one failure - verify
|
||||
clearPendingRequests();
|
||||
}
|
||||
|
||||
void result( const LLSD& content )
|
||||
{
|
||||
if ( !content.isMap() || content.has("error") )
|
||||
{
|
||||
llwarns << "Error on fetched data"<< llendl;
|
||||
//prep#do we really want to remove all because of one failure - verify
|
||||
clearPendingRequests();
|
||||
return;
|
||||
}
|
||||
|
||||
//Differentiate what the incoming caps could be from the data
|
||||
bool containsParcel = content.has("parcel");
|
||||
bool containsSelection = content.has("selected");
|
||||
|
||||
//Loop over the stored object ids checking against the incoming data
|
||||
for ( LLSD::array_iterator iter = mObjectIDs.beginArray(); iter != mObjectIDs.endArray(); ++iter )
|
||||
{
|
||||
LLUUID objectID = iter->asUUID();
|
||||
|
||||
LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
|
||||
|
||||
if ( containsParcel )
|
||||
{
|
||||
//Typically should be one
|
||||
S32 dataCount = content["parcel"].size();
|
||||
for(S32 i = 0; i < dataCount; i++)
|
||||
{
|
||||
//prep#todo verify that this is safe, otherwise just add a bool
|
||||
LLUUID parcelId;
|
||||
//S32 parcelOwner = 0;
|
||||
if ( content["parcel"][i].has("parcel_id") )
|
||||
{
|
||||
parcelId = content["parcel"][i]["parcel_id"].asUUID();
|
||||
}
|
||||
|
||||
//if ( content["parcel"][i].has("parcel_owner") )
|
||||
//{
|
||||
// parcelOwner = content["parcel"][i]["parcel_owner"].asInteger();
|
||||
//}
|
||||
|
||||
F32 ownerRenderCost = 0;
|
||||
F32 ownerPhysicsCost = 0;
|
||||
F32 ownerNetworkCost = 0;
|
||||
F32 ownerSimulationCost = 0;
|
||||
|
||||
F32 groupRenderCost = 0;
|
||||
F32 groupPhysicsCost = 0;
|
||||
F32 groupNetworkCost = 0;
|
||||
F32 groupSimulationCost = 0;
|
||||
|
||||
F32 otherRenderCost = 0;
|
||||
F32 otherPhysicsCost = 0;
|
||||
F32 otherNetworkCost = 0;
|
||||
F32 otherSimulationCost = 0;
|
||||
|
||||
F32 tempRenderCost = 0;
|
||||
F32 tempPhysicsCost = 0;
|
||||
F32 tempNetworkCost = 0;
|
||||
F32 tempSimulationCost = 0;
|
||||
|
||||
F32 selectedRenderCost = 0;
|
||||
F32 selectedPhysicsCost = 0;
|
||||
F32 selectedNetworkCost = 0;
|
||||
F32 selectedSimulationCost = 0;
|
||||
|
||||
F32 parcelCapacity = 0;
|
||||
|
||||
if ( content["parcel"][i].has("capacity") )
|
||||
{
|
||||
parcelCapacity = content["parcel"][i].has("capacity");
|
||||
}
|
||||
|
||||
if ( content["parcel"][i].has("owner") )
|
||||
{
|
||||
ownerRenderCost = content["parcel"][i]["owner"]["rendering"].asReal();
|
||||
ownerPhysicsCost = content["parcel"][i]["owner"]["physics"].asReal();
|
||||
ownerNetworkCost = content["parcel"][i]["owner"]["streaming"].asReal();
|
||||
ownerSimulationCost = content["parcel"][i]["owner"]["simulation"].asReal();
|
||||
}
|
||||
|
||||
if ( content["parcel"][i].has("group") )
|
||||
{
|
||||
groupRenderCost = content["parcel"][i]["group"]["rendering"].asReal();
|
||||
groupPhysicsCost = content["parcel"][i]["group"]["physics"].asReal();
|
||||
groupNetworkCost = content["parcel"][i]["group"]["streaming"].asReal();
|
||||
groupSimulationCost = content["parcel"][i]["group"]["simulation"].asReal();
|
||||
|
||||
}
|
||||
if ( content["parcel"][i].has("other") )
|
||||
{
|
||||
otherRenderCost = content["parcel"][i]["other"]["rendering"].asReal();
|
||||
otherPhysicsCost = content["parcel"][i]["other"]["physics"].asReal();
|
||||
otherNetworkCost = content["parcel"][i]["other"]["streaming"].asReal();
|
||||
otherSimulationCost = content["parcel"][i]["other"]["simulation"].asReal();
|
||||
}
|
||||
|
||||
if ( content["parcel"][i].has("temp") )
|
||||
{
|
||||
tempRenderCost = content["parcel"][i]["total"]["rendering"].asReal();
|
||||
tempPhysicsCost = content["parcel"][i]["total"]["physics"].asReal();
|
||||
tempNetworkCost = content["parcel"][i]["total"]["streaming"].asReal();
|
||||
tempSimulationCost = content["parcel"][i]["total"]["simulation"].asReal();
|
||||
}
|
||||
|
||||
if ( content["parcel"][i].has("selected") )
|
||||
{
|
||||
selectedRenderCost = content["parcel"][i]["total"]["rendering"].asReal();
|
||||
selectedPhysicsCost = content["parcel"][i]["total"]["physics"].asReal();
|
||||
selectedNetworkCost = content["parcel"][i]["total"]["streaming"].asReal();
|
||||
selectedSimulationCost = content["parcel"][i]["total"]["simulation"].asReal();
|
||||
}
|
||||
|
||||
ParcelQuota parcelQuota( ownerRenderCost, ownerPhysicsCost, ownerNetworkCost, ownerSimulationCost,
|
||||
groupRenderCost, groupPhysicsCost, groupNetworkCost, groupSimulationCost,
|
||||
otherRenderCost, otherPhysicsCost, otherNetworkCost, otherSimulationCost,
|
||||
tempRenderCost, tempPhysicsCost, tempNetworkCost, tempSimulationCost,
|
||||
selectedRenderCost, selectedPhysicsCost, selectedNetworkCost, selectedSimulationCost,
|
||||
parcelCapacity );
|
||||
//Update the Parcel
|
||||
LLParcel* pParcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
|
||||
if ( pParcel )
|
||||
{
|
||||
pParcel->updateQuota( objectID, parcelQuota );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if ( containsSelection )
|
||||
{
|
||||
S32 dataCount = content["selected"].size();
|
||||
for(S32 i = 0; i < dataCount; i++)
|
||||
{
|
||||
|
||||
F32 renderCost = 0;
|
||||
F32 physicsCost = 0;
|
||||
F32 networkCost = 0;
|
||||
F32 simulationCost = 0;
|
||||
|
||||
LLUUID objectId;
|
||||
|
||||
objectId = content["selected"][i]["local_id"].asUUID();
|
||||
renderCost = content["selected"][i]["rendering"].asReal();
|
||||
physicsCost = content["selected"][i]["physics"].asReal();
|
||||
networkCost = content["selected"][i]["streaming"].asReal();
|
||||
simulationCost = content["selected"][i]["simulation"].asReal();
|
||||
|
||||
SelectionQuota selectionQuota( objectId, renderCost, physicsCost, networkCost, simulationCost );
|
||||
|
||||
//Update the objects
|
||||
gObjectList.updateQuota( objectId, selectionQuota );
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Nothing in string
|
||||
LLAccountingQuotaManager::getInstance()->removePendingObjectQuota( objectID );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
//List of posted objects
|
||||
LLSD mObjectIDs;
|
||||
};
|
||||
//===============================================================================
|
||||
void LLAccountingQuotaManager::fetchQuotas( const std::string& url )
|
||||
{
|
||||
// Invoking system must have already determined capability availability
|
||||
if ( !url.empty() )
|
||||
{
|
||||
LLSD objectList;
|
||||
U32 objectIndex = 0;
|
||||
IDIt IDIter = mUpdateObjectQuota.begin();
|
||||
IDIt IDIterEnd = mUpdateObjectQuota.end();
|
||||
|
||||
for ( ; IDIter != IDIterEnd; ++IDIter )
|
||||
{
|
||||
// Check to see if a request for this object has already been made.
|
||||
if ( mPendingObjectQuota.find( *IDIter ) == mPendingObjectQuota.end() )
|
||||
{
|
||||
mPendingObjectQuota.insert( *IDIter );
|
||||
objectList[objectIndex++] = *IDIter;
|
||||
}
|
||||
}
|
||||
|
||||
mUpdateObjectQuota.clear();
|
||||
|
||||
//Post results
|
||||
if ( objectList.size() > 0 )
|
||||
{
|
||||
LLSD dataToPost = LLSD::emptyMap();
|
||||
dataToPost["object_ids"] = objectList;
|
||||
LLHTTPClient::post( url, dataToPost, new LLAccountingQuotaResponder( objectList ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//url was empty - warn & continue
|
||||
llwarns<<"Supplied url is empty "<<llendl;
|
||||
mUpdateObjectQuota.clear();
|
||||
mPendingObjectQuota.clear();
|
||||
}
|
||||
}
|
||||
//===============================================================================
|
||||
void LLAccountingQuotaManager::updateObjectCost( const LLUUID& objectID )
|
||||
{
|
||||
mUpdateObjectQuota.insert( objectID );
|
||||
}
|
||||
//===============================================================================
|
||||
void LLAccountingQuotaManager::removePendingObjectQuota( const LLUUID& objectID )
|
||||
{
|
||||
mPendingObjectQuota.erase( objectID );
|
||||
}
|
||||
//===============================================================================
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
@@ -592,7 +592,7 @@ bool LLAppViewer::init()
|
||||
|
||||
// *NOTE:Mani - LLCurl::initClass is not thread safe.
|
||||
// Called before threads are created.
|
||||
LLCurl::initClass();
|
||||
LLCurl::initClass(gSavedSettings.getBOOL("CurlUseMultipleThreads"));
|
||||
LL_INFOS("InitInfo") << "LLCurl initialized." << LL_ENDL ;
|
||||
|
||||
initThreads();
|
||||
|
||||
@@ -1806,20 +1806,20 @@ void LLVertexBufferAvatar::setupVertexBuffer(U32 data_mask) const
|
||||
{
|
||||
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
|
||||
|
||||
glVertexPointer(3,GL_FLOAT, mStride, (void*)(base + 0));
|
||||
glNormalPointer(GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
glTexCoordPointer(2,GL_FLOAT, mStride, (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
|
||||
glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
|
||||
set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], mStride, (F32*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
set_vertex_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT], getStride(TYPE_WEIGHT), (F32*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
|
||||
if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_BUMP)
|
||||
{
|
||||
set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], mStride, (LLVector3*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
set_binormals(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::BINORMAL], getStride(TYPE_BINORMAL), (LLVector3*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
}
|
||||
|
||||
if (sShaderLevel >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)
|
||||
{
|
||||
set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], mStride, (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
set_vertex_clothing_weights(LLDrawPoolAvatar::sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_CLOTHING], getStride(TYPE_CLOTHWEIGHT), (LLVector4*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -82,7 +82,6 @@
|
||||
#include "llviewerjoystick.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#if MESH_ENABLED
|
||||
#include "llaccountingquotamanager.h"
|
||||
#include "llmeshrepository.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1482,6 +1482,8 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
|
||||
|
||||
void LLMeshUploadThread::generateHulls()
|
||||
{
|
||||
bool has_valid_requests = false ;
|
||||
|
||||
for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
|
||||
{
|
||||
LLMeshUploadData data;
|
||||
@@ -1501,6 +1503,10 @@ void LLMeshUploadThread::generateHulls()
|
||||
{
|
||||
physics = data.mModel[LLModel::LOD_PHYSICS];
|
||||
}
|
||||
else if (data.mModel[LLModel::LOD_LOW].notNull())
|
||||
{
|
||||
physics = data.mModel[LLModel::LOD_LOW];
|
||||
}
|
||||
else if (data.mModel[LLModel::LOD_MEDIUM].notNull())
|
||||
{
|
||||
physics = data.mModel[LLModel::LOD_MEDIUM];
|
||||
@@ -1516,13 +1522,17 @@ void LLMeshUploadThread::generateHulls()
|
||||
if(request->isValid())
|
||||
{
|
||||
gMeshRepo.mDecompThread->submitRequest(request);
|
||||
}
|
||||
has_valid_requests = true ;
|
||||
}
|
||||
}
|
||||
|
||||
while (!mPhysicsComplete)
|
||||
|
||||
if(has_valid_requests)
|
||||
{
|
||||
while (!mPhysicsComplete)
|
||||
{
|
||||
apr_sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLMeshUploadThread::doWholeModelUpload()
|
||||
@@ -3180,7 +3190,8 @@ void LLPhysicsDecomp::doDecompositionSingleHull()
|
||||
return;
|
||||
#endif //!MESH_IMPORT
|
||||
#if MESH_IMPORT
|
||||
|
||||
LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance();
|
||||
|
||||
if (decomp == NULL)
|
||||
{
|
||||
//stub. do nothing.
|
||||
|
||||
@@ -769,29 +769,23 @@ LLPolyMesh::LLPolyMesh(LLPolyMeshSharedData *shared_data, LLPolyMesh *reference_
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 1 // Allocate memory without initializing every vector
|
||||
// Allocate memory without initializing every vector
|
||||
// NOTE: This makes asusmptions about the size of LLVector[234]
|
||||
int nverts = mSharedData->mNumVertices;
|
||||
int nfloats = nverts * (3*5 + 2 + 4);
|
||||
mVertexData = new F32[nfloats];
|
||||
int nfloats = nverts * (2*4 + 3*3 + 2 + 4);
|
||||
//use 16 byte aligned vertex data to make LLPolyMesh SSE friendly
|
||||
mVertexData = (F32*) ll_aligned_malloc_16(nfloats*4);
|
||||
int offset = 0;
|
||||
mCoords = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
|
||||
mNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
|
||||
mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
|
||||
mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
|
||||
mCoords = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
|
||||
mNormals = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
|
||||
mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
|
||||
mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
|
||||
|
||||
// these members don't need to be 16-byte aligned, but the first one might be
|
||||
// read during an aligned memcpy of mTexCoords
|
||||
mScaledNormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
|
||||
mBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
|
||||
mScaledBinormals = (LLVector3*)(mVertexData + offset); offset += 3*nverts;
|
||||
mTexCoords = (LLVector2*)(mVertexData + offset); offset += 2*nverts;
|
||||
mClothingWeights = (LLVector4*)(mVertexData + offset); offset += 4*nverts;
|
||||
#else
|
||||
mCoords = new LLVector3[mSharedData->mNumVertices];
|
||||
mNormals = new LLVector3[mSharedData->mNumVertices];
|
||||
mScaledNormals = new LLVector3[mSharedData->mNumVertices];
|
||||
mBinormals = new LLVector3[mSharedData->mNumVertices];
|
||||
mScaledBinormals = new LLVector3[mSharedData->mNumVertices];
|
||||
mTexCoords = new LLVector2[mSharedData->mNumVertices];
|
||||
mClothingWeights = new LLVector4[mSharedData->mNumVertices];
|
||||
memset(mClothingWeights, 0, sizeof(LLVector4) * mSharedData->mNumVertices);
|
||||
#endif
|
||||
initializeForMorph();
|
||||
}
|
||||
}
|
||||
@@ -806,19 +800,11 @@ LLPolyMesh::~LLPolyMesh()
|
||||
for (i = 0; i < mJointRenderData.count(); i++)
|
||||
{
|
||||
delete mJointRenderData[i];
|
||||
mJointRenderData[i] = NULL;
|
||||
}
|
||||
#if 0 // These are now allocated as one big uninitialized chunk
|
||||
delete [] mCoords;
|
||||
delete [] mNormals;
|
||||
delete [] mScaledNormals;
|
||||
delete [] mBinormals;
|
||||
delete [] mScaledBinormals;
|
||||
delete [] mClothingWeights;
|
||||
delete [] mTexCoords;
|
||||
#else
|
||||
delete [] mVertexData;
|
||||
#endif
|
||||
mJointRenderData[i] = NULL;
|
||||
}
|
||||
|
||||
ll_aligned_free_16(mVertexData);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1242,7 +1228,7 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp)
|
||||
int nfaces = mSharedData->mNumFaces;
|
||||
int i;
|
||||
|
||||
LLVector3* coords = getWritableCoords();
|
||||
LLVector4* coords = getWritableCoords();
|
||||
for ( i=0; i<nverts; i++) {
|
||||
std::string outstring = llformat("v %f %f %f\n",
|
||||
coords[i][0],
|
||||
@@ -1254,7 +1240,7 @@ BOOL LLPolyMesh::saveOBJ(LLFILE *fp)
|
||||
}
|
||||
}
|
||||
|
||||
LLVector3* normals = getWritableNormals();
|
||||
LLVector4* normals = getWritableNormals();
|
||||
for ( i=0; i<nverts; i++) {
|
||||
std::string outstring = llformat("vn %f %f %f\n",
|
||||
normals[i][0],
|
||||
@@ -1311,8 +1297,8 @@ BOOL LLPolyMesh::loadOBJ(LLFILE *fp)
|
||||
int nnormals = 0;
|
||||
int ntexcoords = 0;
|
||||
|
||||
LLVector3* coords = getWritableCoords();
|
||||
LLVector3* normals = getWritableNormals();
|
||||
LLVector4* coords = getWritableCoords();
|
||||
LLVector4* normals = getWritableNormals();
|
||||
LLVector3* binormals = getWritableBinormals();
|
||||
LLVector2* tex = getWritableTexCoords();
|
||||
LLPolyFace* faces = getFaces();
|
||||
@@ -1467,8 +1453,8 @@ BOOL LLPolyMesh::setSharedFromCurrent()
|
||||
LLPolyMesh delta(mSharedData, NULL);
|
||||
U32 nverts = delta.getNumVertices();
|
||||
|
||||
LLVector3 *delta_coords = delta.getWritableCoords();
|
||||
LLVector3 *delta_normals = delta.getWritableNormals();
|
||||
LLVector4 *delta_coords = delta.getWritableCoords();
|
||||
LLVector4 *delta_normals = delta.getWritableNormals();
|
||||
LLVector3 *delta_binormals = delta.getWritableBinormals();
|
||||
LLVector2 *delta_tex_coords = delta.getWritableTexCoords();
|
||||
|
||||
@@ -1497,8 +1483,8 @@ BOOL LLPolyMesh::setSharedFromCurrent()
|
||||
LLPolyMesh* mesh = avatarp->getMesh(mSharedData);
|
||||
if (mesh)
|
||||
{
|
||||
LLVector3 *mesh_coords = mesh->getWritableCoords();
|
||||
LLVector3 *mesh_normals = mesh->getWritableNormals();
|
||||
LLVector4 *mesh_coords = mesh->getWritableCoords();
|
||||
LLVector4 *mesh_normals = mesh->getWritableNormals();
|
||||
LLVector3 *mesh_binormals = mesh->getWritableBinormals();
|
||||
LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords();
|
||||
LLVector3 *mesh_scaled_normals = mesh->getScaledNormals();
|
||||
@@ -1509,10 +1495,10 @@ BOOL LLPolyMesh::setSharedFromCurrent()
|
||||
mesh_coords[vert_index] -= delta_coords[vert_index];
|
||||
mesh_tex_coords[vert_index] -= delta_tex_coords[vert_index];
|
||||
|
||||
mesh_scaled_normals[vert_index] -= delta_normals[vert_index];
|
||||
mesh_scaled_normals[vert_index] -= LLVector3(delta_normals[vert_index]);
|
||||
LLVector3 normalized_normal = mesh_scaled_normals[vert_index];
|
||||
normalized_normal.normVec();
|
||||
mesh_normals[vert_index] = normalized_normal;
|
||||
mesh_normals[vert_index] = LLVector4(normalized_normal);
|
||||
|
||||
mesh_scaled_binormals[vert_index] -= delta_binormals[vert_index];
|
||||
LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal;
|
||||
@@ -1616,7 +1602,7 @@ void LLPolyMesh::dumpDiagInfo(void*)
|
||||
//-----------------------------------------------------------------------------
|
||||
// getWritableCoords()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLVector3 *LLPolyMesh::getWritableCoords()
|
||||
LLVector4 *LLPolyMesh::getWritableCoords()
|
||||
{
|
||||
return mCoords;
|
||||
}
|
||||
@@ -1624,7 +1610,7 @@ LLVector3 *LLPolyMesh::getWritableCoords()
|
||||
//-----------------------------------------------------------------------------
|
||||
// getWritableNormals()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLVector3 *LLPolyMesh::getWritableNormals()
|
||||
LLVector4 *LLPolyMesh::getWritableNormals()
|
||||
{
|
||||
return mNormals;
|
||||
}
|
||||
@@ -1679,8 +1665,12 @@ void LLPolyMesh::initializeForMorph()
|
||||
if (!mSharedData)
|
||||
return;
|
||||
|
||||
memcpy(mCoords, mSharedData->mBaseCoords, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
|
||||
memcpy(mNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
|
||||
for (U32 i = 0; i < (U32)mSharedData->mNumVertices; ++i)
|
||||
{
|
||||
mCoords[i] = LLVector4(mSharedData->mBaseCoords[i]);
|
||||
mNormals[i] = LLVector4(mSharedData->mBaseNormals[i]);
|
||||
}
|
||||
|
||||
memcpy(mScaledNormals, mSharedData->mBaseNormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
|
||||
memcpy(mBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
|
||||
memcpy(mScaledBinormals, mSharedData->mBaseBinormals, sizeof(LLVector3) * mSharedData->mNumVertices); /*Flawfinder: ignore*/
|
||||
|
||||
@@ -240,15 +240,15 @@ public:
|
||||
}
|
||||
|
||||
// Get coords
|
||||
const LLVector3 *getCoords() const{
|
||||
const LLVector4 *getCoords() const{
|
||||
return mCoords;
|
||||
}
|
||||
|
||||
// non const version
|
||||
LLVector3 *getWritableCoords();
|
||||
LLVector4 *getWritableCoords();
|
||||
|
||||
// Get normals
|
||||
const LLVector3 *getNormals() const{
|
||||
const LLVector4 *getNormals() const{
|
||||
return mNormals;
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
}
|
||||
|
||||
// intermediate morphed normals and output normals
|
||||
LLVector3 *getWritableNormals();
|
||||
LLVector4 *getWritableNormals();
|
||||
LLVector3 *getScaledNormals();
|
||||
|
||||
LLVector3 *getWritableBinormals();
|
||||
@@ -368,11 +368,11 @@ protected:
|
||||
// Single array of floats for allocation / deletion
|
||||
F32 *mVertexData;
|
||||
// deformed vertices (resulting from application of morph targets)
|
||||
LLVector3 *mCoords;
|
||||
LLVector4 *mCoords;
|
||||
// deformed normals (resulting from application of morph targets)
|
||||
LLVector3 *mScaledNormals;
|
||||
// output normals (after normalization)
|
||||
LLVector3 *mNormals;
|
||||
LLVector4 *mNormals;
|
||||
// deformed binormals (resulting from application of morph targets)
|
||||
LLVector3 *mScaledBinormals;
|
||||
// output binormals (after normalization)
|
||||
|
||||
@@ -282,16 +282,16 @@ BOOL LLPolyMorphData::saveOBJ(LLFILE *fp)
|
||||
|
||||
LLPolyMesh mesh(mMesh, NULL);
|
||||
|
||||
LLVector3 *coords = mesh.getWritableCoords();
|
||||
LLVector3 *normals = mesh.getWritableNormals();
|
||||
LLVector4 *coords = mesh.getWritableCoords();
|
||||
LLVector4 *normals = mesh.getWritableNormals();
|
||||
LLVector2 *tex_coords = mesh.getWritableTexCoords();
|
||||
|
||||
for(U32 vert_index_morph = 0; vert_index_morph < mNumIndices; vert_index_morph++)
|
||||
{
|
||||
S32 vert_index_mesh = mVertexIndices[vert_index_morph];
|
||||
|
||||
coords[vert_index_mesh] += mCoords[vert_index_morph];
|
||||
normals[vert_index_mesh] += mNormals[vert_index_morph];
|
||||
coords[vert_index_mesh] += LLVector4(mCoords[vert_index_morph]);
|
||||
normals[vert_index_mesh] += LLVector4(mNormals[vert_index_morph]);
|
||||
normals[vert_index_mesh].normVec();
|
||||
tex_coords[vert_index_mesh] += mTexCoords[vert_index_morph];
|
||||
}
|
||||
@@ -307,8 +307,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
|
||||
if (!morph)
|
||||
return FALSE;
|
||||
|
||||
LLVector3 *morph_coords = morph->getWritableCoords();
|
||||
LLVector3 *morph_normals = morph->getWritableNormals();
|
||||
LLVector4 *morph_coords = morph->getWritableCoords();
|
||||
LLVector4 *morph_normals = morph->getWritableNormals();
|
||||
LLVector3 *morph_binormals = morph->getWritableBinormals();
|
||||
LLVector2 *morph_tex_coords = morph->getWritableTexCoords();
|
||||
|
||||
@@ -318,8 +318,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
|
||||
LLPolyMesh delta(mMesh, NULL);
|
||||
U32 nverts = delta.getNumVertices();
|
||||
|
||||
LLVector3 *delta_coords = delta.getWritableCoords();
|
||||
LLVector3 *delta_normals = delta.getWritableNormals();
|
||||
LLVector4 *delta_coords = delta.getWritableCoords();
|
||||
LLVector4 *delta_normals = delta.getWritableNormals();
|
||||
LLVector3 *delta_binormals = delta.getWritableBinormals();
|
||||
LLVector2 *delta_tex_coords = delta.getWritableTexCoords();
|
||||
|
||||
@@ -380,8 +380,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
|
||||
{
|
||||
new_vertex_indices[morph_index] = vert_index;
|
||||
|
||||
new_coords[morph_index] = delta_coords[vert_index];
|
||||
new_normals[morph_index] = delta_normals[vert_index];
|
||||
new_coords[morph_index] = LLVector3(delta_coords[vert_index]);
|
||||
new_normals[morph_index] = LLVector3(delta_normals[vert_index]);
|
||||
new_binormals[morph_index] = delta_binormals[vert_index];
|
||||
new_tex_coords[morph_index] = delta_tex_coords[vert_index];
|
||||
|
||||
@@ -417,8 +417,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
|
||||
{
|
||||
vert_index = mVertexIndices[morph_index];
|
||||
|
||||
delta_coords[vert_index] -= mCoords[morph_index];
|
||||
delta_normals[vert_index] -= mNormals[morph_index];
|
||||
delta_coords[vert_index] -= LLVector4(mCoords[morph_index]);
|
||||
delta_normals[vert_index] -= LLVector4(mNormals[morph_index]);
|
||||
delta_binormals[vert_index] -= mBinormals[morph_index];
|
||||
delta_tex_coords[vert_index] -= mTexCoords[morph_index];
|
||||
}
|
||||
@@ -456,8 +456,8 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
|
||||
continue;
|
||||
}
|
||||
|
||||
LLVector3 *mesh_coords = mesh->getWritableCoords();
|
||||
LLVector3 *mesh_normals = mesh->getWritableNormals();
|
||||
LLVector4 *mesh_coords = mesh->getWritableCoords();
|
||||
LLVector4 *mesh_normals = mesh->getWritableNormals();
|
||||
LLVector3 *mesh_binormals = mesh->getWritableBinormals();
|
||||
LLVector2 *mesh_tex_coords = mesh->getWritableTexCoords();
|
||||
LLVector3 *mesh_scaled_normals = mesh->getScaledNormals();
|
||||
@@ -468,10 +468,10 @@ BOOL LLPolyMorphData::setMorphFromMesh(LLPolyMesh *morph)
|
||||
mesh_coords[vert_index] += delta_coords[vert_index] * weight;
|
||||
mesh_tex_coords[vert_index] += delta_tex_coords[vert_index] * weight;
|
||||
|
||||
mesh_scaled_normals[vert_index] += delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR;
|
||||
mesh_scaled_normals[vert_index] += LLVector3(delta_normals[vert_index] * weight * NORMAL_SOFTEN_FACTOR);
|
||||
LLVector3 normalized_normal = mesh_scaled_normals[vert_index];
|
||||
normalized_normal.normVec();
|
||||
mesh_normals[vert_index] = normalized_normal;
|
||||
mesh_normals[vert_index] = LLVector4(normalized_normal);
|
||||
|
||||
mesh_scaled_binormals[vert_index] += delta_binormals[vert_index] * weight * NORMAL_SOFTEN_FACTOR;
|
||||
LLVector3 tangent = mesh_scaled_binormals[vert_index] % normalized_normal;
|
||||
@@ -797,10 +797,10 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
|
||||
if (delta_weight != 0.f)
|
||||
{
|
||||
llassert(!mMesh->isLOD());
|
||||
LLVector3 *coords = mMesh->getWritableCoords();
|
||||
LLVector4 *coords = mMesh->getWritableCoords();
|
||||
|
||||
LLVector3 *scaled_normals = mMesh->getScaledNormals();
|
||||
LLVector3 *normals = mMesh->getWritableNormals();
|
||||
LLVector4 *normals = mMesh->getWritableNormals();
|
||||
|
||||
LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
|
||||
LLVector3 *binormals = mMesh->getWritableBinormals();
|
||||
@@ -820,7 +820,8 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
|
||||
maskWeight = maskWeightArray[vert_index_morph];
|
||||
}
|
||||
|
||||
coords[vert_index_mesh] += mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight;
|
||||
coords[vert_index_mesh] += LLVector4(mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight);
|
||||
|
||||
if (getInfo()->mIsClothingMorph && clothing_weights)
|
||||
{
|
||||
LLVector3 clothing_offset = mMorphData->mCoords[vert_index_morph] * delta_weight * maskWeight;
|
||||
@@ -835,7 +836,7 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
|
||||
scaled_normals[vert_index_mesh] += mMorphData->mNormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
|
||||
LLVector3 normalized_normal = scaled_normals[vert_index_mesh];
|
||||
normalized_normal.normVec();
|
||||
normals[vert_index_mesh] = normalized_normal;
|
||||
normals[vert_index_mesh] = LLVector4(normalized_normal);
|
||||
|
||||
// calculate new binormals
|
||||
scaled_binormals[vert_index_mesh] += mMorphData->mBinormals[vert_index_morph] * delta_weight * maskWeight * NORMAL_SOFTEN_FACTOR;
|
||||
@@ -906,31 +907,31 @@ BOOL LLPolyMorphTarget::undoMask(BOOL delete_mask)
|
||||
|
||||
F32 *mask_weights = mVertMask->getMorphMaskWeights();
|
||||
|
||||
LLVector3 *coords = mMesh->getWritableCoords();
|
||||
LLVector4 *coords = mMesh->getWritableCoords();
|
||||
LLVector3 *scaled_normals = mMesh->getScaledNormals();
|
||||
LLVector3 *scaled_binormals = mMesh->getScaledBinormals();
|
||||
LLVector2 *tex_coords = mMesh->getWritableTexCoords();
|
||||
|
||||
for(U32 vert = 0; vert < mMorphData->mNumIndices; vert++)
|
||||
{
|
||||
F32 mask_weight = 1.f;
|
||||
if (mask_weights)
|
||||
{
|
||||
mask_weight = mask_weights[vert];
|
||||
}
|
||||
F32 mask_weight = 1.f;
|
||||
if (mask_weights)
|
||||
{
|
||||
mask_weight = mask_weights[vert];
|
||||
}
|
||||
|
||||
F32 last_mask_weight = mLastWeight * mask_weight;
|
||||
F32 lastMaskWeight = mLastWeight * mask_weights[vert];
|
||||
S32 out_vert = mMorphData->mVertexIndices[vert];
|
||||
|
||||
// remove effect of existing masked morph
|
||||
coords[out_vert] -= mMorphData->mCoords[vert] * last_mask_weight;
|
||||
scaled_normals[out_vert] -= mMorphData->mNormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR;
|
||||
scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * last_mask_weight * NORMAL_SOFTEN_FACTOR;
|
||||
tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * last_mask_weight;
|
||||
coords[out_vert] -= LLVector4(mMorphData->mCoords[vert]) * lastMaskWeight;
|
||||
scaled_normals[out_vert] -= mMorphData->mNormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
|
||||
scaled_binormals[out_vert] -= mMorphData->mBinormals[vert] * lastMaskWeight * NORMAL_SOFTEN_FACTOR;
|
||||
tex_coords[out_vert] -= mMorphData->mTexCoords[vert] * lastMaskWeight;
|
||||
|
||||
if (clothing_weights)
|
||||
{
|
||||
LLVector3 clothing_offset = mMorphData->mCoords[vert] * last_mask_weight;
|
||||
LLVector3 clothing_offset = mMorphData->mCoords[vert] * lastMaskWeight;
|
||||
LLVector4* clothing_weight = &clothing_weights[out_vert];
|
||||
clothing_weight->mV[VX] -= clothing_offset.mV[VX];
|
||||
clothing_weight->mV[VY] -= clothing_offset.mV[VY];
|
||||
|
||||
@@ -115,27 +115,6 @@ void sg_assert(BOOL expr)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LL_DEBUG
|
||||
void validate_drawable(LLDrawable* drawablep)
|
||||
{
|
||||
F64 rad = drawablep->getBinRadius();
|
||||
LLVector4a const* exta = drawablep->getSpatialExtents();
|
||||
|
||||
LLVector3 ext[2];
|
||||
ext[0].set(exta[0].getF32ptr());
|
||||
ext[1].set(exta[1].getF32ptr());
|
||||
|
||||
if (rad < 0 || rad > 4096 ||
|
||||
(ext[1]-ext[0]).magVec() > 4096)
|
||||
{
|
||||
llwarns << "Invalid drawable found in octree." << llendl;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define validate_drawable(x)
|
||||
#endif
|
||||
|
||||
|
||||
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad)
|
||||
{
|
||||
return AABBSphereIntersectR2(min, max, origin, rad*rad);
|
||||
@@ -281,38 +260,70 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
|
||||
|
||||
void LLSpatialGroup::buildOcclusion()
|
||||
{
|
||||
if (!mOcclusionVerts)
|
||||
if (mOcclusionVerts.isNull())
|
||||
{
|
||||
mOcclusionVerts = new F32[8*3];
|
||||
}
|
||||
|
||||
LLVector3 bounds[2];
|
||||
bounds[0].set(mBounds[0].getF32ptr());
|
||||
bounds[1].set(mBounds[1].getF32ptr());
|
||||
LLVector3 r = bounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE);
|
||||
|
||||
for (U32 k = 0; k < 3; k++)
|
||||
{
|
||||
r.mV[k] = llmin(bounds[1].mV[k]+0.25f, r.mV[k]);
|
||||
}
|
||||
|
||||
F32* v = mOcclusionVerts;
|
||||
F32* c = bounds[0].mV;
|
||||
F32* s = r.mV;
|
||||
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
|
||||
LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
|
||||
mOcclusionVerts->allocateBuffer(8, 64, true);
|
||||
|
||||
//vertex positions are encoded so the 3 bits of their vertex index
|
||||
//correspond to their axis facing, with bit position 3,2,1 matching
|
||||
//axis facing x,y,z, bit set meaning positive facing, bit clear
|
||||
//meaning negative facing
|
||||
v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000
|
||||
v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001
|
||||
v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010
|
||||
v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011
|
||||
|
||||
v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100
|
||||
v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101
|
||||
v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110
|
||||
v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111
|
||||
LLStrider<U16> idx;
|
||||
mOcclusionVerts->getIndexStrider(idx);
|
||||
for (U32 i = 0; i < 64; i++)
|
||||
{
|
||||
*idx++ = sOcclusionIndices[i];
|
||||
}
|
||||
}
|
||||
|
||||
LLVector4a fudge;
|
||||
fudge.splat(SG_OCCLUSION_FUDGE);
|
||||
|
||||
LLVector4a r;
|
||||
r.setAdd(mBounds[1], fudge);
|
||||
|
||||
LLStrider<LLVector3> pos;
|
||||
|
||||
{
|
||||
//LLFastTimer t(LLFastTimer::FTM_BUILD_OCCLUSION);
|
||||
mOcclusionVerts->getVertexStrider(pos);
|
||||
}
|
||||
|
||||
{
|
||||
LLVector4a* v = (LLVector4a*) pos.get();
|
||||
|
||||
const LLVector4a& c = mBounds[0];
|
||||
const LLVector4a& s = r;
|
||||
|
||||
static const LLVector4a octant[] =
|
||||
{
|
||||
LLVector4a(-1.f, -1.f, -1.f),
|
||||
LLVector4a(-1.f, -1.f, 1.f),
|
||||
LLVector4a(-1.f, 1.f, -1.f),
|
||||
LLVector4a(-1.f, 1.f, 1.f),
|
||||
|
||||
LLVector4a(1.f, -1.f, -1.f),
|
||||
LLVector4a(1.f, -1.f, 1.f),
|
||||
LLVector4a(1.f, 1.f, -1.f),
|
||||
LLVector4a(1.f, 1.f, 1.f),
|
||||
};
|
||||
|
||||
//vertex positions are encoded so the 3 bits of their vertex index
|
||||
//correspond to their axis facing, with bit position 3,2,1 matching
|
||||
//axis facing x,y,z, bit set meaning positive facing, bit clear
|
||||
//meaning negative facing
|
||||
|
||||
for (S32 i = 0; i < 8; ++i)
|
||||
{
|
||||
LLVector4a p;
|
||||
p.setMul(s, octant[i]);
|
||||
p.add(c);
|
||||
v[i] = p;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
mOcclusionVerts->setBuffer(0);
|
||||
}
|
||||
|
||||
clearState(LLSpatialGroup::OCCLUSION_DIRTY);
|
||||
}
|
||||
@@ -378,7 +389,6 @@ LLSpatialGroup::~LLSpatialGroup()
|
||||
}
|
||||
}
|
||||
|
||||
delete [] mOcclusionVerts;
|
||||
mOcclusionVerts = NULL;
|
||||
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
@@ -473,52 +483,6 @@ void LLSpatialGroup::checkStates()
|
||||
#endif
|
||||
}
|
||||
|
||||
void validate_draw_info(LLDrawInfo& params)
|
||||
{
|
||||
#if LL_OCTREE_PARANOIA_CHECK
|
||||
if (!params.mVertexBuffer)
|
||||
{
|
||||
llerrs << "Draw batch has no vertex buffer." << llendl;
|
||||
}
|
||||
|
||||
//bad range
|
||||
if (params.mStart >= params.mEnd)
|
||||
{
|
||||
llerrs << "Draw batch has invalid range." << llendl;
|
||||
}
|
||||
|
||||
if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts())
|
||||
{
|
||||
llerrs << "Draw batch has buffer overrun error." << llendl;
|
||||
}
|
||||
|
||||
if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices())
|
||||
{
|
||||
llerrs << "Draw batch has index buffer ovverrun error." << llendl;
|
||||
}
|
||||
|
||||
//bad indices
|
||||
U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer();
|
||||
if (indicesp)
|
||||
{
|
||||
for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++)
|
||||
{
|
||||
if (indicesp[i] < (U16)params.mStart)
|
||||
{
|
||||
llerrs << "Draw batch has vertex buffer index out of range error (index too low). "
|
||||
<< "indicesp["<<i<<"]="<<indicesp[i]<< llendl;
|
||||
}
|
||||
|
||||
if (indicesp[i] > (U16)params.mEnd)
|
||||
{
|
||||
llerrs << "Draw batch has vertex buffer index out of range error (index too high)."
|
||||
<< "indicesp["<<i<<"]="<<indicesp[i]<< llendl;
|
||||
}
|
||||
}
|
||||
} //Complains -SG
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLSpatialGroup::validateDrawMap()
|
||||
{
|
||||
#if LL_OCTREE_PARANOIA_CHECK
|
||||
@@ -528,8 +492,8 @@ void LLSpatialGroup::validateDrawMap()
|
||||
for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
|
||||
{
|
||||
LLDrawInfo& params = **j;
|
||||
|
||||
validate_draw_info(params);
|
||||
|
||||
params.validate();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -540,7 +504,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
|
||||
drawablep->updateSpatialExtents();
|
||||
validate_drawable(drawablep);
|
||||
|
||||
OctreeNode* parent = mOctreeNode->getOctParent();
|
||||
|
||||
@@ -552,7 +515,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
|
||||
unbound();
|
||||
setState(OBJECT_DIRTY);
|
||||
//setState(GEOM_DIRTY);
|
||||
validate_drawable(drawablep);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -570,7 +532,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc
|
||||
else
|
||||
{
|
||||
drawablep->setSpatialGroup(this);
|
||||
validate_drawable(drawablep);
|
||||
setState(OBJECT_DIRTY | GEOM_DIRTY);
|
||||
setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
|
||||
gPipeline.markRebuild(this, TRUE);
|
||||
@@ -843,7 +804,7 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
|
||||
gPipeline.markRebuild(this, TRUE);
|
||||
}
|
||||
|
||||
if (mOcclusionVerts)
|
||||
if (mOcclusionVerts.notNull())
|
||||
{
|
||||
setState(OCCLUSION_DIRTY);
|
||||
}
|
||||
@@ -878,24 +839,16 @@ void LLSpatialGroup::setState(eSpatialState state)
|
||||
// if (LLSpatialPartition::sFreezeState)
|
||||
// return;
|
||||
mState |= state;
|
||||
|
||||
if (state > LLSpatialGroup::STATE_MASK)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
llassert(state <= LLSpatialGroup::STATE_MASK);
|
||||
}
|
||||
|
||||
void LLSpatialGroup::setState(eSpatialState state, S32 mode)
|
||||
{
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
// if (LLSpatialPartition::sFreezeState)
|
||||
// return;
|
||||
|
||||
if (state > LLSpatialGroup::STATE_MASK)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
llassert(state <= LLSpatialGroup::STATE_MASK);
|
||||
|
||||
if (mode > STATE_MODE_SINGLE)
|
||||
{
|
||||
if (mode == STATE_MODE_DIFF)
|
||||
@@ -941,25 +894,14 @@ public:
|
||||
|
||||
void LLSpatialGroup::clearState(eSpatialState state)
|
||||
{
|
||||
// if (LLSpatialPartition::sFreezeState)
|
||||
// return;
|
||||
if (state > LLSpatialGroup::STATE_MASK)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
llassert(state <= LLSpatialGroup::STATE_MASK);
|
||||
|
||||
mState &= ~state;
|
||||
}
|
||||
|
||||
void LLSpatialGroup::clearState(eSpatialState state, S32 mode)
|
||||
{
|
||||
|
||||
// if (LLSpatialPartition::sFreezeState)
|
||||
// return;
|
||||
if (state > LLSpatialGroup::STATE_MASK)
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
llassert(state <= LLSpatialGroup::STATE_MASK);
|
||||
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
|
||||
@@ -984,10 +926,7 @@ void LLSpatialGroup::clearState(eSpatialState state, S32 mode)
|
||||
|
||||
BOOL LLSpatialGroup::isState(eSpatialState state) const
|
||||
{
|
||||
if (state > LLSpatialGroup::STATE_MASK)
|
||||
{
|
||||
llerrs << "LLSpatialGroup::isState passed invalid state '" << state << "'" << llendl;
|
||||
}
|
||||
llassert(state <= LLSpatialGroup::STATE_MASK);
|
||||
|
||||
return mState & state ? TRUE : FALSE;
|
||||
}
|
||||
@@ -1125,7 +1064,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
|
||||
mOctreeNode(node),
|
||||
mSpatialPartition(part),
|
||||
mVertexBuffer(NULL),
|
||||
mBufferUsage(GL_STATIC_DRAW_ARB),
|
||||
mBufferUsage(part->mBufferUsage),
|
||||
mDistance(0.f),
|
||||
mDepth(0.f),
|
||||
mLastUpdateDistance(-1.f),
|
||||
@@ -1403,7 +1342,6 @@ void LLSpatialGroup::destroyGL()
|
||||
}
|
||||
}
|
||||
|
||||
delete [] mOcclusionVerts;
|
||||
mOcclusionVerts = NULL;
|
||||
|
||||
for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
|
||||
@@ -1577,7 +1515,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
|
||||
mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
|
||||
}
|
||||
|
||||
if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY))
|
||||
if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
|
||||
{
|
||||
buildOcclusion();
|
||||
}
|
||||
@@ -1604,37 +1542,32 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
|
||||
{
|
||||
//LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
|
||||
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts);
|
||||
|
||||
mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
|
||||
|
||||
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
|
||||
{
|
||||
LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
|
||||
if (camera->getOrigin().isExactlyZero())
|
||||
{ //origin is invalid, draw entire box
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, sOcclusionIndices);
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8);
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0]));
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (camera->getOrigin().isExactlyZero())
|
||||
{ //origin is invalid, draw entire box
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, sOcclusionIndices);
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8);
|
||||
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0]));
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1693,7 +1626,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
|
||||
drawablep->updateSpatialExtents();
|
||||
validate_drawable(drawablep);
|
||||
|
||||
//keep drawable from being garbage collected
|
||||
LLPointer<LLDrawable> ptr = drawablep;
|
||||
@@ -1992,11 +1924,8 @@ public:
|
||||
|
||||
virtual void processGroup(LLSpatialGroup* group)
|
||||
{
|
||||
if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty())
|
||||
{
|
||||
llerrs << "WTF?" << llendl;
|
||||
}
|
||||
|
||||
llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty())
|
||||
|
||||
if (mRes < 2)
|
||||
{
|
||||
if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0)
|
||||
@@ -2360,6 +2289,8 @@ void pushVerts(LLSpatialGroup* group, U32 mask)
|
||||
|
||||
void pushVerts(LLFace* face, U32 mask)
|
||||
{
|
||||
llassert(face->verify());
|
||||
|
||||
LLVertexBuffer* buffer = face->getVertexBuffer();
|
||||
|
||||
if (buffer)
|
||||
@@ -3163,7 +3094,6 @@ public:
|
||||
{
|
||||
renderAgentTarget(avatar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
|
||||
@@ -3554,18 +3484,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
|
||||
mFace(NULL),
|
||||
mDistance(0.f)
|
||||
{
|
||||
mDebugColor = (rand() << 16) + rand();
|
||||
if (mStart >= mVertexBuffer->getRequestedVerts() ||
|
||||
mEnd >= mVertexBuffer->getRequestedVerts())
|
||||
{
|
||||
llerrs << "Invalid draw info vertex range." << llendl;
|
||||
}
|
||||
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
|
||||
|
||||
if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() ||
|
||||
mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices())
|
||||
{
|
||||
llerrs << "Invalid draw info index range." << llendl;
|
||||
}
|
||||
mDebugColor = (rand() << 16) + rand();
|
||||
}
|
||||
|
||||
LLDrawInfo::~LLDrawInfo()
|
||||
@@ -3586,6 +3507,11 @@ LLDrawInfo::~LLDrawInfo()
|
||||
}
|
||||
}
|
||||
|
||||
void LLDrawInfo::validate()
|
||||
{
|
||||
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
|
||||
}
|
||||
|
||||
LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
|
||||
{
|
||||
return new LLVertexBuffer(type_mask, usage);
|
||||
|
||||
@@ -88,6 +88,7 @@ public:
|
||||
BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
|
||||
|
||||
|
||||
void validate();
|
||||
|
||||
LLVector4a mExtents[2];
|
||||
|
||||
@@ -361,9 +362,9 @@ public:
|
||||
F32 mBuilt;
|
||||
OctreeNode* mOctreeNode;
|
||||
LLSpatialPartition* mSpatialPartition;
|
||||
|
||||
|
||||
LLPointer<LLVertexBuffer> mVertexBuffer;
|
||||
F32* mOcclusionVerts;
|
||||
LLPointer<LLVertexBuffer> mOcclusionVerts;
|
||||
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
|
||||
|
||||
U32 mBufferUsage;
|
||||
@@ -694,8 +695,6 @@ public:
|
||||
virtual void shift(const LLVector4a &offset);
|
||||
};
|
||||
|
||||
void validate_draw_info(LLDrawInfo& params);
|
||||
|
||||
extern const F32 SG_BOX_SIDE;
|
||||
extern const F32 SG_BOX_OFFSET;
|
||||
extern const F32 SG_BOX_RAD;
|
||||
|
||||
@@ -1144,7 +1144,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
||||
|
||||
if (region)
|
||||
{
|
||||
std::string http_url = region->getCapability("GetTexture");
|
||||
std::string http_url = region->getHttpUrl() ;
|
||||
if (!http_url.empty())
|
||||
{
|
||||
mUrl = http_url + "/?texture_id=" + mID.asString().c_str();
|
||||
@@ -1278,7 +1278,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
|
||||
static const LLCachedControl<S32> min_http_requests("HTTPMinRequests", 2);
|
||||
if((mFetcher->getNumHTTPRequests() > max_http_requests) ||
|
||||
((mFetcher->getTextureBandwidth() > mFetcher->mMaxBandwidth) &&
|
||||
(mFetcher->getNumHTTPRequests() > min_http_requests)) ||
|
||||
((U32)mFetcher->getNumHTTPRequests() > min_http_requests)) ||
|
||||
!sgConnectionThrottle())
|
||||
{
|
||||
return false ; //wait.
|
||||
@@ -2348,6 +2348,7 @@ void LLTextureFetch::commonUpdate()
|
||||
#endif
|
||||
|
||||
// Update Curl on same thread as mCurlGetRequest was constructed
|
||||
llassert_always(mCurlGetRequest);
|
||||
S32 processed = mCurlGetRequest->process();
|
||||
if (processed > 0)
|
||||
{
|
||||
|
||||
@@ -646,6 +646,7 @@ void settings_setup_listeners()
|
||||
gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
|
||||
//See LL jira VWR-3258 comment section. Implemented by LL in 2.1 -Shyotl
|
||||
gSavedSettings.getControl("ShyotlRenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
|
||||
gSavedSettings.getControl("ShyotlRenderVBOStrideMode")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
|
||||
gSavedSettings.getControl("SianaRenderOmitBlankVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
|
||||
gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2));
|
||||
gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "v4math.h"
|
||||
#include "m3math.h"
|
||||
#include "m4math.h"
|
||||
#include "llmatrix4a.h"
|
||||
|
||||
#if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS
|
||||
extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
|
||||
@@ -382,6 +383,7 @@ const S32 NUM_AXES = 3;
|
||||
// pivot parent 0-n -- child = n+1
|
||||
|
||||
static LLMatrix4 gJointMatUnaligned[32];
|
||||
static LLMatrix4a gJointMatAligned[32];
|
||||
static LLMatrix3 gJointRotUnaligned[32];
|
||||
static LLVector4 gJointPivot[32];
|
||||
|
||||
@@ -467,6 +469,14 @@ void LLViewerJointMesh::uploadJointMatrices()
|
||||
glUniform4fvARB(gAvatarMatrixParam, 45, mat);
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
//load gJointMatUnaligned into gJointMatAligned
|
||||
for (joint_num = 0; joint_num < reference_mesh->mJointRenderData.count(); ++joint_num)
|
||||
{
|
||||
gJointMatAligned[joint_num].loadu(gJointMatUnaligned[joint_num]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@@ -516,6 +526,8 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
|
||||
U32 triangle_count = 0;
|
||||
|
||||
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;
|
||||
|
||||
stop_glerror();
|
||||
|
||||
//----------------------------------------------------------------
|
||||
@@ -531,7 +543,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
|
||||
stop_glerror();
|
||||
|
||||
LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), gRenderForSelect ? 0.0f : mShiny && !(mFace->getPool()->getVertexShaderLevel() > 0));
|
||||
LLGLSSpecular specular(LLColor4(1.f,1.f,1.f,1.f), (mFace->getPool()->getVertexShaderLevel() > 0 && !gRenderForSelect) ? 0.f : mShiny);
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// setup current texture
|
||||
@@ -541,7 +553,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP;
|
||||
if (mTestImageName)
|
||||
{
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
|
||||
gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
|
||||
|
||||
if (mIsTransparent)
|
||||
{
|
||||
@@ -550,14 +562,14 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
else
|
||||
{
|
||||
glColor4f(0.7f, 0.6f, 0.3f, 1.f);
|
||||
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
|
||||
gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
|
||||
}
|
||||
}
|
||||
else if( !is_dummy && mLayerSet )
|
||||
{
|
||||
if( mLayerSet->hasComposite() )
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(mLayerSet->getComposite());
|
||||
gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -567,7 +579,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
{
|
||||
llwarns << "Layerset without composite" << llendl;
|
||||
}
|
||||
gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
|
||||
gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -577,24 +589,25 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
{
|
||||
old_mode = mTexture->getAddressMode();
|
||||
}
|
||||
gGL.getTexUnit(0)->bind(mTexture);
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
|
||||
gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR));
|
||||
gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR));
|
||||
}
|
||||
|
||||
if (gRenderForSelect)
|
||||
{
|
||||
if (isTransparent())
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
|
||||
gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA);
|
||||
gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
|
||||
gGL.getTexUnit(diffuse_channel)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_CONST_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,13 +644,13 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
|
||||
if (mTestImageName)
|
||||
{
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
|
||||
gGL.getTexUnit(diffuse_channel)->setTextureBlendType(LLTexUnit::TB_MULT);
|
||||
}
|
||||
|
||||
if (mTexture.notNull() && !is_dummy)
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(mTexture.get());
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
|
||||
gGL.getTexUnit(diffuse_channel)->bind(mTexture);
|
||||
gGL.getTexUnit(diffuse_channel)->setTextureAddressMode(old_mode);
|
||||
}
|
||||
|
||||
return triangle_count;
|
||||
@@ -648,6 +661,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
|
||||
{
|
||||
num_vertices = (num_vertices + 0x3) & ~0x3;
|
||||
// Do a pre-alloc pass to determine sizes of data.
|
||||
if (mMesh && mValid)
|
||||
{
|
||||
@@ -676,6 +690,16 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
|
||||
return;
|
||||
}
|
||||
|
||||
LLDrawPool *poolp = mFace->getPool();
|
||||
BOOL hardware_skinning = (poolp && poolp->getVertexShaderLevel() > 0) ? TRUE : FALSE;
|
||||
|
||||
if (!hardware_skinning && terse_update)
|
||||
{ //no need to do terse updates if we're doing software vertex skinning
|
||||
// since mMesh is being copied into mVertexBuffer every frame
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
LLStrider<LLVector3> verticesp;
|
||||
LLStrider<LLVector3> normalsp;
|
||||
LLStrider<LLVector2> tex_coordsp;
|
||||
@@ -686,111 +710,64 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
|
||||
// Copy data into the faces from the polymesh data.
|
||||
if (mMesh && mValid)
|
||||
{
|
||||
if (mMesh->getNumVertices())
|
||||
const U32 num_verts = mMesh->getNumVertices();
|
||||
|
||||
if (num_verts)
|
||||
{
|
||||
stop_glerror();
|
||||
face->getGeometryAvatar(verticesp, normalsp, tex_coordsp, vertex_weightsp, clothing_weightsp);
|
||||
stop_glerror();
|
||||
face->getVertexBuffer()->getIndexStrider(indicesp);
|
||||
stop_glerror();
|
||||
|
||||
verticesp += mMesh->mFaceVertexOffset;
|
||||
tex_coordsp += mMesh->mFaceVertexOffset;
|
||||
normalsp += mMesh->mFaceVertexOffset;
|
||||
vertex_weightsp += mMesh->mFaceVertexOffset;
|
||||
clothing_weightsp += mMesh->mFaceVertexOffset;
|
||||
|
||||
const U32* __restrict coords = (U32*) mMesh->getCoords();
|
||||
const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords();
|
||||
const U32* __restrict normals = (U32*) mMesh->getNormals();
|
||||
const U32* __restrict weights = (U32*) mMesh->getWeights();
|
||||
const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights();
|
||||
|
||||
const U32 num_verts = mMesh->getNumVertices();
|
||||
|
||||
U32 i = 0;
|
||||
|
||||
const U32 skip = verticesp.getSkip()/sizeof(U32);
|
||||
|
||||
U32* __restrict v = (U32*) verticesp.get();
|
||||
U32* __restrict n = (U32*) normalsp.get();
|
||||
|
||||
if (terse_update)
|
||||
//F32* v = (F32*) verticesp.get();
|
||||
//F32* n = (F32*) normalsp.get();
|
||||
|
||||
//U32 words = num_verts*4;
|
||||
|
||||
//LLVector4a::memcpyNonAliased16(v, (F32*) mMesh->getCoords(), words*sizeof(F32));
|
||||
verticesp.assignArray((U8*)mMesh->getCoords(), sizeof(mMesh->getCoords()[0]), num_verts);
|
||||
//LLVector4a::memcpyNonAliased16(n, (F32*) mMesh->getNormals(), words*sizeof(F32));
|
||||
normalsp.assignArray((U8*)mMesh->getNormals(), sizeof(mMesh->getNormals()[0]), num_verts);
|
||||
|
||||
|
||||
if (!terse_update)
|
||||
{
|
||||
for (S32 i = num_verts; i > 0; --i)
|
||||
{
|
||||
//morph target application only, only update positions and normals
|
||||
v[0] = coords[0];
|
||||
v[1] = coords[1];
|
||||
v[2] = coords[2];
|
||||
coords += 3;
|
||||
v += skip;
|
||||
}
|
||||
vertex_weightsp += mMesh->mFaceVertexOffset;
|
||||
clothing_weightsp += mMesh->mFaceVertexOffset;
|
||||
tex_coordsp += mMesh->mFaceVertexOffset;
|
||||
|
||||
//F32* tc = (F32*) tex_coordsp.get();
|
||||
//F32* vw = (F32*) vertex_weightsp.get();
|
||||
//F32* cw = (F32*) clothing_weightsp.get();
|
||||
|
||||
for (S32 i = num_verts; i > 0; --i)
|
||||
{
|
||||
n[0] = normals[0];
|
||||
n[1] = normals[1];
|
||||
n[2] = normals[2];
|
||||
normals += 3;
|
||||
n += skip;
|
||||
}
|
||||
//LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32));
|
||||
tex_coordsp.assignArray((U8*)mMesh->getTexCoords(), sizeof(mMesh->getTexCoords()[0]), num_verts);
|
||||
//LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32));
|
||||
vertex_weightsp.assignArray((U8*)mMesh->getWeights(), sizeof(mMesh->getWeights()[0]), num_verts);
|
||||
//LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32));
|
||||
clothing_weightsp.assignArray((U8*)mMesh->getClothingWeights(), sizeof(mMesh->getClothingWeights()[0]), num_verts);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
U32* __restrict tc = (U32*) tex_coordsp.get();
|
||||
U32* __restrict vw = (U32*) vertex_weightsp.get();
|
||||
U32* __restrict cw = (U32*) clothing_weightsp.get();
|
||||
|
||||
do
|
||||
{
|
||||
v[0] = *(coords++);
|
||||
v[1] = *(coords++);
|
||||
v[2] = *(coords++);
|
||||
v += skip;
|
||||
|
||||
tc[0] = *(tex_coords++);
|
||||
tc[1] = *(tex_coords++);
|
||||
tc += skip;
|
||||
|
||||
n[0] = *(normals++);
|
||||
n[1] = *(normals++);
|
||||
n[2] = *(normals++);
|
||||
n += skip;
|
||||
|
||||
vw[0] = *(weights++);
|
||||
vw += skip;
|
||||
|
||||
cw[0] = *(cloth_weights++);
|
||||
cw[1] = *(cloth_weights++);
|
||||
cw[2] = *(cloth_weights++);
|
||||
cw[3] = *(cloth_weights++);
|
||||
cw += skip;
|
||||
}
|
||||
while (++i < num_verts);
|
||||
|
||||
const U32 idx_count = mMesh->getNumFaces()*3;
|
||||
const U32 idx_count = mMesh->getNumFaces()*3;
|
||||
|
||||
indicesp += mMesh->mFaceIndexOffset;
|
||||
|
||||
U16* __restrict idx = indicesp.get();
|
||||
S32* __restrict src_idx = (S32*) mMesh->getFaces();
|
||||
U16* __restrict idx = indicesp.get();
|
||||
S32* __restrict src_idx = (S32*) mMesh->getFaces();
|
||||
|
||||
i = 0;
|
||||
const S32 offset = (S32) mMesh->mFaceVertexOffset;
|
||||
|
||||
const S32 offset = (S32) mMesh->mFaceVertexOffset;
|
||||
|
||||
do
|
||||
{
|
||||
*(idx++) = *(src_idx++)+offset;
|
||||
}
|
||||
while (++i < idx_count);
|
||||
for (S32 i = 0; i < (S32)idx_count; ++i)
|
||||
{
|
||||
*(idx++) = *(src_idx++)+offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// updateLOD()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -812,85 +789,45 @@ void LLViewerJointMesh::updateGeometryOriginal(LLFace *mFace, LLPolyMesh *mMesh)
|
||||
buffer->getVertexStrider(o_vertices, 0);
|
||||
buffer->getNormalStrider(o_normals, 0);
|
||||
|
||||
F32 last_weight = F32_MAX;
|
||||
LLMatrix4 gBlendMat;
|
||||
LLMatrix3 gBlendRotMat;
|
||||
F32* __restrict vert = o_vertices[0].mV;
|
||||
F32* __restrict norm = o_normals[0].mV;
|
||||
|
||||
const F32* __restrict weights = mMesh->getWeights();
|
||||
const LLVector4a* __restrict coords = (LLVector4a*) mMesh->getCoords();
|
||||
const LLVector4a* __restrict normals = (LLVector4a*) mMesh->getNormals();
|
||||
|
||||
U32 offset = mMesh->mFaceVertexOffset*4;
|
||||
vert += offset;
|
||||
norm += offset;
|
||||
|
||||
const F32* weights = mMesh->getWeights();
|
||||
const LLVector3* coords = mMesh->getCoords();
|
||||
const LLVector3* normals = mMesh->getNormals();
|
||||
for (U32 index = 0; index < mMesh->getNumVertices(); index++)
|
||||
{
|
||||
U32 bidx = index + mMesh->mFaceVertexOffset;
|
||||
|
||||
// blend by first matrix
|
||||
F32 w = weights[index];
|
||||
|
||||
// Maybe we don't have to change gBlendMat.
|
||||
// Profiles of a single-avatar scene on a Mac show this to be a very
|
||||
// common case. JC
|
||||
if (w == last_weight)
|
||||
// equivalent to joint = floorf(weights[index]);
|
||||
S32 joint = _mm_cvtt_ss2si(_mm_load_ss(weights+index));
|
||||
F32 w = weights[index] - joint;
|
||||
|
||||
LLMatrix4a gBlendMat;
|
||||
|
||||
if (w != 0.f)
|
||||
{
|
||||
o_vertices[bidx] = coords[index] * gBlendMat;
|
||||
o_normals[bidx] = normals[index] * gBlendRotMat;
|
||||
continue;
|
||||
// blend between matrices and apply
|
||||
gBlendMat.setLerp(gJointMatAligned[joint+0],
|
||||
gJointMatAligned[joint+1], w);
|
||||
|
||||
LLVector4a res;
|
||||
gBlendMat.affineTransform(coords[index], res);
|
||||
res.store4a(vert+index*4);
|
||||
gBlendMat.rotate(normals[index], res);
|
||||
res.store4a(norm+index*4);
|
||||
}
|
||||
|
||||
last_weight = w;
|
||||
|
||||
S32 joint = llfloor(w);
|
||||
w -= joint;
|
||||
|
||||
// No lerp required in this case.
|
||||
if (w == 1.0f)
|
||||
{
|
||||
gBlendMat = gJointMatUnaligned[joint+1];
|
||||
o_vertices[bidx] = coords[index] * gBlendMat;
|
||||
gBlendRotMat = gJointRotUnaligned[joint+1];
|
||||
o_normals[bidx] = normals[index] * gBlendRotMat;
|
||||
continue;
|
||||
else
|
||||
{ // No lerp required in this case.
|
||||
LLVector4a res;
|
||||
gJointMatAligned[joint].affineTransform(coords[index], res);
|
||||
res.store4a(vert+index*4);
|
||||
gJointMatAligned[joint].rotate(normals[index], res);
|
||||
res.store4a(norm+index*4);
|
||||
}
|
||||
|
||||
// Try to keep all the accesses to the matrix data as close
|
||||
// together as possible. This function is a hot spot on the
|
||||
// Mac. JC
|
||||
LLMatrix4 &m0 = gJointMatUnaligned[joint+1];
|
||||
LLMatrix4 &m1 = gJointMatUnaligned[joint+0];
|
||||
|
||||
gBlendMat.mMatrix[VX][VX] = lerp(m1.mMatrix[VX][VX], m0.mMatrix[VX][VX], w);
|
||||
gBlendMat.mMatrix[VX][VY] = lerp(m1.mMatrix[VX][VY], m0.mMatrix[VX][VY], w);
|
||||
gBlendMat.mMatrix[VX][VZ] = lerp(m1.mMatrix[VX][VZ], m0.mMatrix[VX][VZ], w);
|
||||
|
||||
gBlendMat.mMatrix[VY][VX] = lerp(m1.mMatrix[VY][VX], m0.mMatrix[VY][VX], w);
|
||||
gBlendMat.mMatrix[VY][VY] = lerp(m1.mMatrix[VY][VY], m0.mMatrix[VY][VY], w);
|
||||
gBlendMat.mMatrix[VY][VZ] = lerp(m1.mMatrix[VY][VZ], m0.mMatrix[VY][VZ], w);
|
||||
|
||||
gBlendMat.mMatrix[VZ][VX] = lerp(m1.mMatrix[VZ][VX], m0.mMatrix[VZ][VX], w);
|
||||
gBlendMat.mMatrix[VZ][VY] = lerp(m1.mMatrix[VZ][VY], m0.mMatrix[VZ][VY], w);
|
||||
gBlendMat.mMatrix[VZ][VZ] = lerp(m1.mMatrix[VZ][VZ], m0.mMatrix[VZ][VZ], w);
|
||||
|
||||
gBlendMat.mMatrix[VW][VX] = lerp(m1.mMatrix[VW][VX], m0.mMatrix[VW][VX], w);
|
||||
gBlendMat.mMatrix[VW][VY] = lerp(m1.mMatrix[VW][VY], m0.mMatrix[VW][VY], w);
|
||||
gBlendMat.mMatrix[VW][VZ] = lerp(m1.mMatrix[VW][VZ], m0.mMatrix[VW][VZ], w);
|
||||
|
||||
o_vertices[bidx] = coords[index] * gBlendMat;
|
||||
|
||||
LLMatrix3 &n0 = gJointRotUnaligned[joint+1];
|
||||
LLMatrix3 &n1 = gJointRotUnaligned[joint+0];
|
||||
|
||||
gBlendRotMat.mMatrix[VX][VX] = lerp(n1.mMatrix[VX][VX], n0.mMatrix[VX][VX], w);
|
||||
gBlendRotMat.mMatrix[VX][VY] = lerp(n1.mMatrix[VX][VY], n0.mMatrix[VX][VY], w);
|
||||
gBlendRotMat.mMatrix[VX][VZ] = lerp(n1.mMatrix[VX][VZ], n0.mMatrix[VX][VZ], w);
|
||||
|
||||
gBlendRotMat.mMatrix[VY][VX] = lerp(n1.mMatrix[VY][VX], n0.mMatrix[VY][VX], w);
|
||||
gBlendRotMat.mMatrix[VY][VY] = lerp(n1.mMatrix[VY][VY], n0.mMatrix[VY][VY], w);
|
||||
gBlendRotMat.mMatrix[VY][VZ] = lerp(n1.mMatrix[VY][VZ], n0.mMatrix[VY][VZ], w);
|
||||
|
||||
gBlendRotMat.mMatrix[VZ][VX] = lerp(n1.mMatrix[VZ][VX], n0.mMatrix[VZ][VX], w);
|
||||
gBlendRotMat.mMatrix[VZ][VY] = lerp(n1.mMatrix[VZ][VY], n0.mMatrix[VZ][VY], w);
|
||||
gBlendRotMat.mMatrix[VZ][VZ] = lerp(n1.mMatrix[VZ][VZ], n0.mMatrix[VZ][VZ], w);
|
||||
|
||||
o_normals[bidx] = normals[index] * gBlendRotMat;
|
||||
}
|
||||
|
||||
buffer->setBuffer(0);
|
||||
|
||||
@@ -94,8 +94,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
|
||||
buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
|
||||
|
||||
const F32* weights = mesh->getWeights();
|
||||
const LLVector3* coords = mesh->getCoords();
|
||||
const LLVector3* normals = mesh->getNormals();
|
||||
const LLVector4* coords = mesh->getCoords();
|
||||
const LLVector4* normals = mesh->getNormals();
|
||||
for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
|
||||
{
|
||||
if( weight != weights[index])
|
||||
@@ -103,8 +103,8 @@ void LLViewerJointMesh::updateGeometrySSE(LLFace *face, LLPolyMesh *mesh)
|
||||
S32 joint = llfloor(weight = weights[index]);
|
||||
blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
|
||||
}
|
||||
blend_mat.multiply(coords[index], o_vertices[index]);
|
||||
((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
|
||||
blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]);
|
||||
((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]);
|
||||
}
|
||||
|
||||
buffer->setBuffer(0);
|
||||
|
||||
@@ -101,8 +101,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
|
||||
buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
|
||||
|
||||
const F32* weights = mesh->getWeights();
|
||||
const LLVector3* coords = mesh->getCoords();
|
||||
const LLVector3* normals = mesh->getNormals();
|
||||
const LLVector4* coords = mesh->getCoords();
|
||||
const LLVector4* normals = mesh->getNormals();
|
||||
for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
|
||||
{
|
||||
if( weight != weights[index])
|
||||
@@ -110,8 +110,8 @@ void LLViewerJointMesh::updateGeometrySSE2(LLFace *face, LLPolyMesh *mesh)
|
||||
S32 joint = llfloor(weight = weights[index]);
|
||||
blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
|
||||
}
|
||||
blend_mat.multiply(coords[index], o_vertices[index]);
|
||||
((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
|
||||
blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]);
|
||||
((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]);
|
||||
}
|
||||
|
||||
buffer->setBuffer(0);
|
||||
|
||||
@@ -84,8 +84,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh)
|
||||
buffer->getNormalStrider(o_normals, mesh->mFaceVertexOffset);
|
||||
|
||||
const F32* weights = mesh->getWeights();
|
||||
const LLVector3* coords = mesh->getCoords();
|
||||
const LLVector3* normals = mesh->getNormals();
|
||||
const LLVector4* coords = mesh->getCoords();
|
||||
const LLVector4* normals = mesh->getNormals();
|
||||
for (U32 index = 0, index_end = mesh->getNumVertices(); index < index_end; ++index)
|
||||
{
|
||||
if( weight != weights[index])
|
||||
@@ -93,8 +93,8 @@ void LLViewerJointMesh::updateGeometryVectorized(LLFace *face, LLPolyMesh *mesh)
|
||||
S32 joint = llfloor(weight = weights[index]);
|
||||
blend_mat.lerp(sJointMat[joint], sJointMat[joint+1], weight - joint);
|
||||
}
|
||||
blend_mat.multiply(coords[index], o_vertices[index]);
|
||||
((LLV4Matrix3)blend_mat).multiply(normals[index], o_normals[index]);
|
||||
blend_mat.multiply((const LLVector3)coords[index], o_vertices[index]);
|
||||
((LLV4Matrix3)blend_mat).multiply((const LLVector3)normals[index], o_normals[index]);
|
||||
}
|
||||
|
||||
buffer->setBuffer(0);
|
||||
|
||||
@@ -5627,10 +5627,4 @@ public:
|
||||
LLHTTPRegistration<ObjectPhysicsProperties>
|
||||
gHTTPRegistrationObjectPhysicsProperties("/message/ObjectPhysicsProperties");
|
||||
|
||||
|
||||
void LLViewerObject::updateQuota( const SelectionQuota& quota )
|
||||
{
|
||||
//update quotas
|
||||
mSelectionQuota = quota;
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
@@ -49,9 +49,6 @@
|
||||
#include "v3dmath.h"
|
||||
#include "v3math.h"
|
||||
#include "llvertexbuffer.h"
|
||||
#if MESH_ENABLED
|
||||
#include "llaccountingquota.h"
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
class LLAgent; // TODO: Get rid of this.
|
||||
class LLAudioSource;
|
||||
@@ -657,11 +654,7 @@ protected:
|
||||
void deleteParticleSource();
|
||||
void setParticleSource(const LLPartSysData& particle_parameters, const LLUUID& owner_id);
|
||||
|
||||
#if MESH_ENABLED
|
||||
public:
|
||||
void updateQuota( const SelectionQuota& quota );
|
||||
const SelectionQuota& getQuota( void ) { return mSelectionQuota; }
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
private:
|
||||
void setNameValueList(const std::string& list); // clears nv pairs and then individually adds \n separated NV pairs from \0 terminated string
|
||||
@@ -724,8 +717,6 @@ protected:
|
||||
F32 mPhysicsCost;
|
||||
F32 mLinksetPhysicsCost;
|
||||
|
||||
SelectionQuota mSelectionQuota;
|
||||
|
||||
bool mCostStale;
|
||||
mutable bool mPhysicsShapeUnknown;
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
@@ -1422,15 +1422,6 @@ void LLViewerObjectList::onObjectCostFetchFailure(const LLUUID& object_id)
|
||||
mPendingObjectCost.erase(object_id);
|
||||
}
|
||||
|
||||
void LLViewerObjectList::updateQuota( const LLUUID& objectId, const SelectionQuota& quota )
|
||||
{
|
||||
LLViewerObject* pVO = findObject( objectId );
|
||||
if ( pVO )
|
||||
{
|
||||
pVO->updateQuota( quota );
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerObjectList::updatePhysicsFlags(const LLViewerObject* object)
|
||||
{
|
||||
mStalePhysicsFlags.insert(object->getID());
|
||||
|
||||
@@ -112,7 +112,6 @@ public:
|
||||
F32 restitution,
|
||||
F32 gravity_multiplier);
|
||||
|
||||
void updateQuota( const LLUUID& objectId, const SelectionQuota& costs );
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
void shiftObjects(const LLVector3 &offset);
|
||||
|
||||
@@ -101,6 +101,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void buildCapabilityNames(LLSD& capabilityNames);
|
||||
|
||||
// The surfaces and other layers
|
||||
LLSurface* mLandp;
|
||||
|
||||
@@ -1480,6 +1482,82 @@ void LLViewerRegion::unpackRegionHandshake()
|
||||
msg->sendReliable(host);
|
||||
}
|
||||
|
||||
|
||||
void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
|
||||
{
|
||||
//capabilityNames.append("AttachmentResources"); //Script limits (llfloaterscriptlimits.cpp)
|
||||
//capabilityNames.append("AvatarPickerSearch"); //Display name/SLID lookup (llfloateravatarpicker.cpp)
|
||||
capabilityNames.append("ChatSessionRequest");
|
||||
capabilityNames.append("CopyInventoryFromNotecard");
|
||||
capabilityNames.append("DispatchRegionInfo");
|
||||
capabilityNames.append("EstateChangeInfo");
|
||||
capabilityNames.append("EventQueueGet");
|
||||
/*capabilityNames.append("EnvironmentSettings");
|
||||
capabilityNames.append("ObjectMedia");
|
||||
capabilityNames.append("ObjectMediaNavigate");*/
|
||||
|
||||
if (false)//gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first.
|
||||
{
|
||||
capabilityNames.append("FetchLib");
|
||||
capabilityNames.append("FetchLibDescendents");
|
||||
capabilityNames.append("FetchInventory");
|
||||
capabilityNames.append("FetchInventoryDescendents");
|
||||
}
|
||||
|
||||
capabilityNames.append("GetDisplayNames");
|
||||
capabilityNames.append("GetTexture");
|
||||
#if MESH_ENABLED
|
||||
capabilityNames.append("GetMesh");
|
||||
capabilityNames.append("GetObjectCost");
|
||||
capabilityNames.append("GetObjectPhysicsData");
|
||||
#endif //MESH_ENABLED
|
||||
capabilityNames.append("GroupProposalBallot");
|
||||
|
||||
capabilityNames.append("HomeLocation");
|
||||
//capabilityNames.append("LandResources"); //Script limits (llfloaterscriptlimits.cpp)
|
||||
capabilityNames.append("MapLayer");
|
||||
capabilityNames.append("MapLayerGod");
|
||||
#if MESH_IMPORT
|
||||
capabilityNames.append("MeshUploadFlag");
|
||||
#endif //MESH_IMPORT
|
||||
capabilityNames.append("NewFileAgentInventory");
|
||||
capabilityNames.append("ParcelPropertiesUpdate");
|
||||
capabilityNames.append("ParcelMediaURLFilterList");
|
||||
capabilityNames.append("ParcelNavigateMedia");
|
||||
capabilityNames.append("ParcelVoiceInfoRequest");
|
||||
capabilityNames.append("ProductInfoRequest");
|
||||
capabilityNames.append("ProvisionVoiceAccountRequest");
|
||||
capabilityNames.append("RemoteParcelRequest");
|
||||
capabilityNames.append("RequestTextureDownload");
|
||||
capabilityNames.append("ResourceCostSelected"); //Unreferenced?
|
||||
capabilityNames.append("SearchStatRequest");
|
||||
capabilityNames.append("SearchStatTracking");
|
||||
capabilityNames.append("SendPostcard");
|
||||
capabilityNames.append("SendUserReport");
|
||||
capabilityNames.append("SendUserReportWithScreenshot");
|
||||
capabilityNames.append("ServerReleaseNotes");
|
||||
//capabilityNames.append("SimConsole");
|
||||
capabilityNames.append("SimulatorFeatures");
|
||||
capabilityNames.append("SetDisplayName");
|
||||
//capabilityNames.append("SimConsoleAsync");
|
||||
capabilityNames.append("StartGroupProposal");
|
||||
capabilityNames.append("TextureStats");
|
||||
capabilityNames.append("UntrustedSimulatorMessage");
|
||||
capabilityNames.append("UpdateAgentInformation");
|
||||
capabilityNames.append("UpdateAgentLanguage");
|
||||
capabilityNames.append("UpdateGestureAgentInventory");
|
||||
capabilityNames.append("UpdateNotecardAgentInventory");
|
||||
capabilityNames.append("UpdateScriptAgent");
|
||||
capabilityNames.append("UpdateGestureTaskInventory");
|
||||
capabilityNames.append("UpdateNotecardTaskInventory");
|
||||
capabilityNames.append("UpdateScriptTask");
|
||||
capabilityNames.append("UploadBakedTexture");
|
||||
//capabilityNames.append("ViewerMetrics");
|
||||
capabilityNames.append("ViewerStartAuction");
|
||||
capabilityNames.append("ViewerStats");
|
||||
// Please add new capabilities alphabetically to reduce
|
||||
// merge conflicts.
|
||||
}
|
||||
void LLViewerRegion::setSeedCapability(const std::string& url)
|
||||
{
|
||||
if (getCapability("Seed") == url)
|
||||
@@ -1495,63 +1573,9 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
|
||||
setCapability("Seed", url);
|
||||
|
||||
LLSD capabilityNames = LLSD::emptyArray();
|
||||
capabilityNames.append("ChatSessionRequest");
|
||||
capabilityNames.append("CopyInventoryFromNotecard");
|
||||
capabilityNames.append("DispatchRegionInfo");
|
||||
capabilityNames.append("EstateChangeInfo");
|
||||
capabilityNames.append("EventQueueGet");
|
||||
if (false)//gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first.
|
||||
{
|
||||
capabilityNames.append("FetchLib");
|
||||
capabilityNames.append("FetchLibDescendents");
|
||||
capabilityNames.append("FetchInventory");
|
||||
capabilityNames.append("FetchInventoryDescendents");
|
||||
}
|
||||
capabilityNames.append("GetDisplayNames");
|
||||
capabilityNames.append("GetTexture");
|
||||
#if MESH_ENABLED
|
||||
capabilityNames.append("GetMesh");
|
||||
capabilityNames.append("GetObjectCost");
|
||||
capabilityNames.append("GetObjectPhysicsData");
|
||||
#endif //MESH_ENABLED
|
||||
capabilityNames.append("GroupProposalBallot");
|
||||
|
||||
capabilityNames.append("HomeLocation");
|
||||
capabilityNames.append("MapLayer");
|
||||
capabilityNames.append("MapLayerGod");
|
||||
capabilityNames.append("NewFileAgentInventory");
|
||||
capabilityNames.append("ParcelPropertiesUpdate");
|
||||
capabilityNames.append("ParcelMediaURLFilterList");
|
||||
capabilityNames.append("ParcelNavigateMedia");
|
||||
capabilityNames.append("ParcelVoiceInfoRequest");
|
||||
capabilityNames.append("ProductInfoRequest");
|
||||
capabilityNames.append("ProvisionVoiceAccountRequest");
|
||||
capabilityNames.append("RemoteParcelRequest");
|
||||
capabilityNames.append("RequestTextureDownload");
|
||||
capabilityNames.append("SearchStatRequest");
|
||||
capabilityNames.append("SearchStatTracking");
|
||||
capabilityNames.append("SendPostcard");
|
||||
capabilityNames.append("SendUserReport");
|
||||
capabilityNames.append("SendUserReportWithScreenshot");
|
||||
capabilityNames.append("ServerReleaseNotes");
|
||||
capabilityNames.append("SimulatorFeatures");
|
||||
capabilityNames.append("SetDisplayName");
|
||||
capabilityNames.append("StartGroupProposal");
|
||||
capabilityNames.append("TextureStats");
|
||||
capabilityNames.append("UntrustedSimulatorMessage");
|
||||
capabilityNames.append("UpdateAgentInformation");
|
||||
capabilityNames.append("UpdateAgentLanguage");
|
||||
capabilityNames.append("UpdateGestureAgentInventory");
|
||||
capabilityNames.append("UpdateNotecardAgentInventory");
|
||||
capabilityNames.append("UpdateScriptAgent");
|
||||
capabilityNames.append("UpdateGestureTaskInventory");
|
||||
capabilityNames.append("UpdateNotecardTaskInventory");
|
||||
capabilityNames.append("UpdateScriptTask");
|
||||
capabilityNames.append("UploadBakedTexture");
|
||||
capabilityNames.append("ViewerStartAuction");
|
||||
capabilityNames.append("ViewerStats");
|
||||
// Please add new capabilities alphabetically to reduce
|
||||
// merge conflicts.
|
||||
|
||||
mImpl->buildCapabilityNames(capabilityNames);
|
||||
|
||||
|
||||
llinfos << "posting to seed " << url << llendl;
|
||||
|
||||
|
||||
@@ -64,23 +64,75 @@ public:
|
||||
mTypeMask |= MAP_TEXCOORD2 | MAP_TEXCOORD3;
|
||||
};
|
||||
|
||||
/*// virtual
|
||||
// virtual
|
||||
void setupVertexBuffer(U32 data_mask) const
|
||||
{
|
||||
if (LLDrawPoolTerrain::getDetailMode() == 0 || LLPipeline::sShadowRender)
|
||||
{
|
||||
volatile U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData;
|
||||
|
||||
//assume tex coords 2 and 3 are present
|
||||
U32 type_mask = mTypeMask | MAP_TEXCOORD2 | MAP_TEXCOORD3;
|
||||
|
||||
if ((data_mask & type_mask) != data_mask)
|
||||
{
|
||||
LLVertexBuffer::setupVertexBuffer(data_mask);
|
||||
llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl;
|
||||
}
|
||||
else if (data_mask & LLVertexBuffer::MAP_TEXCOORD1)
|
||||
|
||||
if (data_mask & MAP_NORMAL)
|
||||
{
|
||||
LLVertexBuffer::setupVertexBuffer(data_mask);
|
||||
glNormalPointer(GL_FLOAT, getStride(TYPE_NORMAL), (void*)(base + mOffsets[TYPE_NORMAL]));
|
||||
}
|
||||
else
|
||||
if (data_mask & MAP_TEXCOORD3)
|
||||
{ //substitute tex coord 0 for tex coord 3
|
||||
glClientActiveTextureARB(GL_TEXTURE3_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD2)
|
||||
{ //substitute tex coord 0 for tex coord 2
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD1)
|
||||
{
|
||||
LLVertexBuffer::setupVertexBuffer(data_mask);
|
||||
glClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD1), (void*)(base + mOffsets[TYPE_TEXCOORD1]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
llglassertok();
|
||||
}*/
|
||||
if (data_mask & MAP_BINORMAL)
|
||||
{
|
||||
glClientActiveTextureARB(GL_TEXTURE2_ARB);
|
||||
glTexCoordPointer(3,GL_FLOAT, getStride(TYPE_BINORMAL), (void*)(base + mOffsets[TYPE_BINORMAL]));
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
}
|
||||
if (data_mask & MAP_TEXCOORD0)
|
||||
{
|
||||
glTexCoordPointer(2,GL_FLOAT, getStride(TYPE_TEXCOORD0), (void*)(base + mOffsets[TYPE_TEXCOORD0]));
|
||||
}
|
||||
if (data_mask & MAP_COLOR)
|
||||
{
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, getStride(TYPE_COLOR), (void*)(base + mOffsets[TYPE_COLOR]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT), (void*)(base + mOffsets[TYPE_WEIGHT]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_WEIGHT4 && sWeight4Loc != -1)
|
||||
{
|
||||
glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, getStride(TYPE_WEIGHT4), (void*)(base+mOffsets[TYPE_WEIGHT4]));
|
||||
}
|
||||
|
||||
if (data_mask & MAP_CLOTHWEIGHT)
|
||||
{
|
||||
glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, getStride(TYPE_CLOTHWEIGHT), (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]));
|
||||
}
|
||||
if (data_mask & MAP_VERTEX)
|
||||
{
|
||||
glVertexPointer(3,GL_FLOAT, getStride(TYPE_VERTEX), (void*)(base + 0));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
||||
@@ -2212,6 +2212,33 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
|
||||
return mDrawable->getWorldMatrix();
|
||||
}
|
||||
|
||||
#if MESH_ENABLED
|
||||
F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes)
|
||||
{
|
||||
F32 radius = getScale().length()*0.5f;
|
||||
|
||||
if (isMesh())
|
||||
{
|
||||
LLSD& header = gMeshRepo.getMeshHeader(getVolume()->getParams().getSculptID());
|
||||
|
||||
return LLMeshRepository::getStreamingCost(header, radius, bytes, visible_bytes, mLOD);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLVolume* volume = getVolume();
|
||||
S32 counts[4];
|
||||
LLVolume::getLoDTriangleCounts(volume->getParams(), counts);
|
||||
|
||||
LLSD header;
|
||||
header["lowest_lod"]["size"] = counts[0] * 10;
|
||||
header["low_lod"]["size"] = counts[1] * 10;
|
||||
header["medium_lod"]["size"] = counts[2] * 10;
|
||||
header["high_lod"]["size"] = counts[3] * 10;
|
||||
|
||||
return LLMeshRepository::getStreamingCost(header, radius);
|
||||
}
|
||||
}
|
||||
#endif //MESH_ENABLED
|
||||
|
||||
U32 LLVOVolume::getTriangleCount()
|
||||
{
|
||||
@@ -2920,7 +2947,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
||||
draw_vec[idx]->mCount += facep->getIndicesCount();
|
||||
draw_vec[idx]->mEnd += facep->getGeomCount();
|
||||
draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
|
||||
validate_draw_info(*draw_vec[idx]);
|
||||
draw_vec[idx]->validate();
|
||||
update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
|
||||
update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
|
||||
}
|
||||
@@ -2944,7 +2971,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
|
||||
}
|
||||
draw_info->mExtents[0] = facep->mExtents[0];
|
||||
draw_info->mExtents[1] = facep->mExtents[1];
|
||||
validate_draw_info(*draw_info);
|
||||
draw_info->validate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3026,8 +3053,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
|
||||
static const LLCachedControl<S32> render_max_vbo_size("RenderMaxVBOSize", 512);
|
||||
static const LLCachedControl<S32> render_max_node_size("RenderMaxNodeSize",8192);
|
||||
U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
|
||||
U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
|
||||
U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
|
||||
U32 max_total = (render_max_node_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
|
||||
max_vertices = llmin(max_vertices, (U32) 65535);
|
||||
|
||||
U32 cur_total = 0;
|
||||
@@ -3408,6 +3435,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
||||
|
||||
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
{
|
||||
llassert(group);
|
||||
static int warningsCount = 20;
|
||||
if (group && group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY))
|
||||
{
|
||||
@@ -3419,15 +3447,16 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
{
|
||||
LLDrawable* drawablep = *drawable_iter;
|
||||
|
||||
if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
|
||||
if (drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (drawablep->isState(LLDrawable::REBUILD_ALL))
|
||||
if (!drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) )
|
||||
{
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
vobj->preRebuild();
|
||||
|
||||
LLVolume* volume = vobj->getVolume();
|
||||
for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
|
||||
{
|
||||
@@ -3494,6 +3523,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
||||
|
||||
group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
|
||||
}
|
||||
|
||||
llassert(!group || !group->isState(LLSpatialGroup::NEW_DRAWINFO));
|
||||
}
|
||||
|
||||
struct CompareBatchBreakerModified
|
||||
@@ -3526,7 +3557,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
{
|
||||
//calculate maximum number of vertices to store in a single buffer
|
||||
static const LLCachedControl<S32> render_max_vbo_size("RenderMaxVBOSize", 512);
|
||||
U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
|
||||
U32 max_vertices = (render_max_vbo_size*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
|
||||
max_vertices = llmin(max_vertices, (U32) 65535);
|
||||
|
||||
if (!distance_sort)
|
||||
@@ -3652,12 +3683,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
|
||||
U32 te_idx = facep->getTEOffset();
|
||||
|
||||
if (facep->getGeometryVolume(*volume, te_idx,
|
||||
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset))
|
||||
{
|
||||
buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(),
|
||||
facep->getIndicesStart(), facep->getIndicesCount());
|
||||
}
|
||||
facep->getGeometryVolume(*volume, te_idx,
|
||||
vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3683,9 +3710,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
|
||||
// can we safely treat this as an alpha mask?
|
||||
if (facep->canRenderAsMask())
|
||||
{
|
||||
const LLDrawable* drawablep = facep->getDrawable();
|
||||
const LLVOVolume* vobj = drawablep ? drawablep->getVOVolume() : NULL;
|
||||
if (te->getFullbright() || (vobj && vobj->isHUDAttachment()))
|
||||
//const LLDrawable* drawablep = facep->getDrawable();
|
||||
//const LLVOVolume* vobj = drawablep ? drawablep->getVOVolume() : NULL;
|
||||
if (te->getFullbright() /*|| (vobj && vobj->isHUDAttachment())*/)
|
||||
{
|
||||
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
|
||||
}
|
||||
|
||||
@@ -132,7 +132,9 @@ public:
|
||||
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
|
||||
/*virtual*/ const LLMatrix4 getRenderMatrix() const;
|
||||
|
||||
|
||||
#if MESH_ENABLED
|
||||
/*virtual*/ F32 getStreamingCost(S32* bytes = NULL, S32* visible_bytes = NULL);
|
||||
#endif //MESH_ENABLED
|
||||
/*virtual*/ U32 getTriangleCount();
|
||||
/*virtual*/ U32 getHighLODTriangleCount();
|
||||
/*virtual*/ BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
|
||||
|
||||
@@ -336,7 +336,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
|
||||
{
|
||||
const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024;
|
||||
const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
|
||||
const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcStride(data_mask);
|
||||
const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask);
|
||||
|
||||
const U32 total_stacks = getNumStacks();
|
||||
|
||||
|
||||
@@ -653,8 +653,8 @@ void LLWorld::updateRegions(F32 max_update_time)
|
||||
BOOL did_one = FALSE;
|
||||
|
||||
// Perform idle time updates for the regions (and associated surfaces)
|
||||
for (region_list_t::iterator iter = mRegionList.begin();
|
||||
iter != mRegionList.end(); ++iter)
|
||||
for (region_list_t::iterator iter = mActiveRegionList.begin()/*mRegionList.begin()*/;
|
||||
iter != mActiveRegionList.end()/*mRegionList.end()*/; ++iter)
|
||||
{
|
||||
LLViewerRegion* regionp = *iter;
|
||||
F32 max_time = max_update_time - update_timer.getElapsedTimeF32();
|
||||
|
||||
@@ -484,13 +484,15 @@ void LLWorldMapView::draw()
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
// Infohubs
|
||||
if (gSavedSettings.getBOOL("MapShowInfohubs")) //(sMapScale >= sThresholdB)
|
||||
static const LLCachedControl<bool> map_show_infohubs("MapShowInfohubs");
|
||||
if (map_show_infohubs) //(sMapScale >= sThresholdB)
|
||||
{
|
||||
drawGenericItems(LLWorldMap::getInstance()->mInfohubs, sInfohubImage);
|
||||
}
|
||||
|
||||
// Telehubs
|
||||
if (gSavedSettings.getBOOL("MapShowTelehubs")) //(sMapScale >= sThresholdB)
|
||||
static const LLCachedControl<bool> map_show_telehubs("MapShowTelehubs");
|
||||
if (map_show_telehubs) //(sMapScale >= sThresholdB)
|
||||
{
|
||||
drawGenericItems(LLWorldMap::getInstance()->mTelehubs, sTelehubImage);
|
||||
}
|
||||
@@ -502,7 +504,8 @@ void LLWorldMapView::draw()
|
||||
drawImage(home, sHomeImage);
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("MapShowLandForSale"))
|
||||
static const LLCachedControl<bool> map_show_land_for_sale("MapShowLandForSale");
|
||||
if (map_show_land_for_sale)
|
||||
{
|
||||
drawGenericItems(LLWorldMap::getInstance()->mLandForSale, sForSaleImage);
|
||||
// for 1.23, we're showing normal land and adult land in the same UI; you don't
|
||||
@@ -514,12 +517,7 @@ void LLWorldMapView::draw()
|
||||
}
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("MapShowPGEvents") ||
|
||||
gSavedSettings.getBOOL("MapShowMatureEvents") ||
|
||||
gSavedSettings.getBOOL("MapShowAdultEvents") )
|
||||
{
|
||||
drawEvents();
|
||||
}
|
||||
drawEvents();
|
||||
|
||||
// Now draw your avatar after all that other stuff.
|
||||
LLVector3d pos_global = gAgent.getPositionGlobal();
|
||||
@@ -541,7 +539,8 @@ void LLWorldMapView::draw()
|
||||
|
||||
// Draw icons for the avatars in each region.
|
||||
// Drawn after your avatar so you can see nearby people.
|
||||
if (gSavedSettings.getBOOL("MapShowPeople"))
|
||||
static const LLCachedControl<bool> map_show_people("MapShowPeople");
|
||||
if (map_show_people)
|
||||
{
|
||||
drawAgents();
|
||||
}
|
||||
@@ -887,7 +886,8 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) {
|
||||
gGL.vertex3f(right, top, 0.f);
|
||||
gGL.end();
|
||||
|
||||
if (gSavedSettings.getBOOL("MapShowLandForSale") && overlayimage && overlayimage->hasGLTexture())
|
||||
static const LLCachedControl<bool> map_show_land_for_sale("MapShowLandForSale");
|
||||
if (map_show_land_for_sale && overlayimage && overlayimage->hasGLTexture())
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(overlayimage);
|
||||
gGL.color4f(1.f, 1.f, 1.f, alpha);
|
||||
@@ -1057,9 +1057,13 @@ void LLWorldMapView::drawEvents()
|
||||
bool mature_enabled = gAgent.canAccessMature();
|
||||
bool adult_enabled = gAgent.canAccessAdult();
|
||||
|
||||
BOOL show_pg = gSavedSettings.getBOOL("MapShowPGEvents");
|
||||
BOOL show_mature = mature_enabled && gSavedSettings.getBOOL("MapShowMatureEvents");
|
||||
BOOL show_adult = adult_enabled && gSavedSettings.getBOOL("MapShowAdultEvents");
|
||||
static const LLCachedControl<bool> map_show_pg_events("MapShowPGEvents");
|
||||
static const LLCachedControl<bool> map_show_mature_events("MapShowMatureEvents");
|
||||
static const LLCachedControl<bool> map_show_adult_events("MapShowAdultEvents");
|
||||
|
||||
BOOL show_pg = map_show_pg_events;
|
||||
BOOL show_mature = mature_enabled && map_show_mature_events;
|
||||
BOOL show_adult = adult_enabled && map_show_adult_events;
|
||||
|
||||
// First the non-selected events
|
||||
LLWorldMap::item_info_list_t::const_iterator e;
|
||||
@@ -1874,8 +1878,9 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
|
||||
}
|
||||
|
||||
// Select event you clicked on
|
||||
if (gSavedSettings.getBOOL("MapShowPGEvents"))
|
||||
{
|
||||
static const LLCachedControl<bool> map_show_pg_events("MapShowPGEvents");
|
||||
if (map_show_pg_events)
|
||||
{
|
||||
for (it = LLWorldMap::getInstance()->mPGEvents.begin(); it != LLWorldMap::getInstance()->mPGEvents.end(); ++it)
|
||||
{
|
||||
LLItemInfo& event = *it;
|
||||
@@ -1889,7 +1894,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gSavedSettings.getBOOL("MapShowMatureEvents"))
|
||||
static const LLCachedControl<bool> map_show_mature_events("MapShowMatureEvents");
|
||||
if (map_show_mature_events)
|
||||
{
|
||||
for (it = LLWorldMap::getInstance()->mMatureEvents.begin(); it != LLWorldMap::getInstance()->mMatureEvents.end(); ++it)
|
||||
{
|
||||
@@ -1904,7 +1910,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gSavedSettings.getBOOL("MapShowAdultEvents"))
|
||||
static const LLCachedControl<bool> map_show_adult_events("MapShowAdultEvents");
|
||||
if (map_show_adult_events)
|
||||
{
|
||||
for (it = LLWorldMap::getInstance()->mAdultEvents.begin(); it != LLWorldMap::getInstance()->mAdultEvents.end(); ++it)
|
||||
{
|
||||
@@ -1919,8 +1926,8 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("MapShowLandForSale"))
|
||||
static const LLCachedControl<bool> map_show_land_for_sale("MapShowLandForSale");
|
||||
if (map_show_land_for_sale)
|
||||
{
|
||||
for (it = LLWorldMap::getInstance()->mLandForSale.begin(); it != LLWorldMap::getInstance()->mLandForSale.end(); ++it)
|
||||
{
|
||||
|
||||
@@ -372,6 +372,7 @@ void LLPipeline::init()
|
||||
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
|
||||
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
|
||||
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO");
|
||||
LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode");
|
||||
LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO");
|
||||
LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
|
||||
sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
|
||||
@@ -5822,6 +5823,7 @@ void LLPipeline::resetVertexBuffers()
|
||||
{
|
||||
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
|
||||
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("ShyotlRenderUseStreamVBO");
|
||||
LLVertexBuffer::sForceStrideMode = gSavedSettings.getU32("ShyotlRenderVBOStrideMode");
|
||||
LLVertexBuffer::sOmitBlank = gSavedSettings.getBOOL("SianaRenderOmitBlankVBO");
|
||||
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
|
||||
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
|
||||
@@ -7905,17 +7907,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
||||
gPipeline.pushRenderTypeMask();
|
||||
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
|
||||
LLPipeline::RENDER_TYPE_WL_SKY,
|
||||
LLPipeline::RENDER_TYPE_WL_CLOUDS,
|
||||
LLPipeline::END_RENDER_TYPES);
|
||||
|
||||
static LLCullResult result;
|
||||
updateCull(camera, result);
|
||||
stateSort(camera, result);
|
||||
andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
|
||||
LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS,
|
||||
LLPipeline::RENDER_TYPE_WL_CLOUDS,
|
||||
LLPipeline::RENDER_TYPE_WL_SKY,
|
||||
LLPipeline::END_RENDER_TYPES);
|
||||
|
||||
renderGeom(camera, TRUE);
|
||||
|
||||
gPipeline.popRenderTypeMask();
|
||||
}
|
||||
|
||||
@@ -7925,7 +7925,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
||||
gPipeline.pushRenderTypeMask();
|
||||
if (detail < 4)
|
||||
{
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS, END_RENDER_TYPES);
|
||||
if (detail < 3)
|
||||
{
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
|
||||
@@ -7940,7 +7940,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
||||
LLPipeline::RENDER_TYPE_VOIDWATER,
|
||||
LLPipeline::RENDER_TYPE_GROUND,
|
||||
LLPipeline::RENDER_TYPE_SKY,
|
||||
LLPipeline::RENDER_TYPE_CLASSIC_CLOUDS,
|
||||
LLPipeline::RENDER_TYPE_WL_CLOUDS,
|
||||
LLPipeline::END_RENDER_TYPES);
|
||||
static const LLCachedControl<bool> skip_distortion_updates("SkipReflectOcclusionUpdates",false);
|
||||
|
||||
Reference in New Issue
Block a user