merge of 56479 with 56480 (why oh why hg?)
commit
9bf8e22d53
|
|
@ -181,7 +181,11 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
|
|||
for (child_list_t::iterator iter = mChildren.begin();
|
||||
iter != mChildren.end(); ++iter)
|
||||
{
|
||||
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
//<FS:Beq> Make this s static cast. The dynamic cast must be working or it would have been crashing on the nullptr in the next line.
|
||||
// LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
|
||||
//</FS:Beq>
|
||||
|
||||
F32 jointLOD = joint->getLOD();
|
||||
|
||||
if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
|
||||
|
|
|
|||
|
|
@ -3869,6 +3869,28 @@
|
|||
<key>Value</key>
|
||||
<integer>3</integer>
|
||||
</map>
|
||||
<key>AvatarExtentRefreshPeriodBatch</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>how many frames do we spread over by default when refreshing extents (default is 4)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>4</integer>
|
||||
</map>
|
||||
<key>AvatarExtentRefreshMaxPerBatch</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>how many avatars do we want to handle in total per batch (default is 5)</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>5</integer>
|
||||
</map>
|
||||
<key>DebugAvatarAppearanceMessage</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include "llvocache.h"
|
||||
#include "llcontrolavatar.h"
|
||||
#include "lldrawpoolavatar.h"
|
||||
#include "llskinningutil.h"
|
||||
|
||||
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
|
||||
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
|
||||
|
|
@ -94,7 +95,10 @@ void LLDrawable::incrementVisible()
|
|||
LLDrawable::LLDrawable(LLViewerObject *vobj, bool new_entry)
|
||||
: LLViewerOctreeEntryData(LLViewerOctreeEntry::LLDRAWABLE),
|
||||
LLTrace::MemTrackable<LLDrawable, 16>("LLDrawable"),
|
||||
mVObjp(vobj)
|
||||
mVObjp(vobj),
|
||||
mSkinningMatCache(nullptr),
|
||||
mLastSkinningMatCacheFrame(0),
|
||||
mCacheSize(0)
|
||||
{
|
||||
init(new_entry);
|
||||
}
|
||||
|
|
@ -140,7 +144,7 @@ void LLDrawable::init(bool new_entry)
|
|||
|
||||
llassert(!vo_entry->getGroup()); //not in the object cache octree.
|
||||
}
|
||||
|
||||
|
||||
llassert(!vo_entry || vo_entry->getEntry() == mEntry);
|
||||
|
||||
initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
|
||||
|
|
@ -164,7 +168,10 @@ void LLDrawable::unload()
|
|||
}
|
||||
facep->clearState(LLFace::RIGGED);
|
||||
}
|
||||
|
||||
//<FS:Beq> ckinning matrix caching
|
||||
delete[] mSkinningMatCache;
|
||||
mSkinningMatCache = nullptr;
|
||||
//</FS:Beq>
|
||||
pVVol->markForUpdate(TRUE);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,9 @@ class LLDrawable
|
|||
public:
|
||||
LLDrawable(const LLDrawable& rhs)
|
||||
: LLTrace::MemTrackable<LLDrawable, 16>("LLDrawable"),
|
||||
LLViewerOctreeEntryData(rhs)
|
||||
LLViewerOctreeEntryData(rhs),
|
||||
mLastSkinningMatCacheFrame(0),
|
||||
mCacheSize(0)
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
|
|
@ -79,6 +81,12 @@ public:
|
|||
|
||||
static void initClass();
|
||||
|
||||
//<FS:Beq> per frame matrix cache
|
||||
U32 mLastSkinningMatCacheFrame;
|
||||
LLMatrix4a* mSkinningMatCache;
|
||||
U32 mCacheSize;
|
||||
//</FS:Beq>
|
||||
|
||||
LLDrawable(LLViewerObject *vobj, bool new_entry = false);
|
||||
|
||||
void markDead(); // Mark this drawable as dead
|
||||
|
|
|
|||
|
|
@ -1864,9 +1864,13 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
|
|||
LLVector4a* norm = has_normal ? (LLVector4a*) normal.get() : NULL;
|
||||
|
||||
//build matrix palette
|
||||
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
|
||||
//<FS:Beq> per frame cache of skinning matrices
|
||||
//LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
//U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
//LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar);
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
auto mat = getCacheSkinningMats(drawable, skin, count, avatar);
|
||||
//</FS:Beq>
|
||||
LLSkinningUtil::checkSkinWeights(weights, buffer->getNumVerts(), skin);
|
||||
|
||||
LLMatrix4a bind_shape_matrix;
|
||||
|
|
@ -1902,6 +1906,32 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
|
|||
}
|
||||
}
|
||||
|
||||
//<FS:Beq> cache per frame Skinning mats
|
||||
LLMatrix4a* LLDrawPoolAvatar::getCacheSkinningMats(LLDrawable* drawable, const LLMeshSkinInfo* skin,
|
||||
U32 count, LLVOAvatar* avatar)
|
||||
{
|
||||
if (drawable->mCacheSize < count || !drawable->mSkinningMatCache)
|
||||
{
|
||||
delete[](drawable->mSkinningMatCache);
|
||||
drawable->mCacheSize = count;
|
||||
drawable->mSkinningMatCache = new LLMatrix4a[count];
|
||||
}
|
||||
|
||||
if (drawable->mSkinningMatCache && LLFrameTimer::getFrameCount() != drawable->mLastSkinningMatCacheFrame)
|
||||
{
|
||||
// LL_DEBUGS("Skinning") << "Call InitSkinningMatrixPalette for drawable @" << (U64)drawable << LL_ENDL;
|
||||
//<FS:Beq> add caching of matrix pallette as high up the stack as we can
|
||||
drawable->mLastSkinningMatCacheFrame = LLFrameTimer::getFrameCount();
|
||||
LLSkinningUtil::initSkinningMatrixPalette(drawable->mSkinningMatCache, count, skin, avatar);
|
||||
}
|
||||
else
|
||||
{
|
||||
// LL_DEBUGS("Skinning") << "Avoiding InitSkinningMatrixPalette for drawable @" << (U64)drawable << LL_ENDL;
|
||||
}
|
||||
return drawable->mSkinningMatCache;
|
||||
}
|
||||
//</FS:Beq>
|
||||
|
||||
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||
{
|
||||
if (!avatar->shouldRenderRigged())
|
||||
|
|
@ -1956,11 +1986,16 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
|||
{
|
||||
if (sShaderLevel > 0)
|
||||
{
|
||||
// upload matrix palette to shader
|
||||
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
|
||||
// upload matrix palette to shader
|
||||
|
||||
//<FS:Beq> per frame cache of skinning matrices
|
||||
//LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
//U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
//LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar);
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
auto mat = getCacheSkinningMats(drawable, skin, count, avatar);
|
||||
//</FS:Beq>
|
||||
|
||||
stop_glerror();
|
||||
|
||||
F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12];
|
||||
|
|
@ -2152,9 +2187,14 @@ void LLDrawPoolAvatar::renderRiggedShadows(LLVOAvatar* avatar)
|
|||
if (sShaderLevel > 0)
|
||||
{
|
||||
// upload matrix palette to shader
|
||||
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
|
||||
//<FS:Beq> per frame cache of skinning matrices
|
||||
//LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
//U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
//LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar);
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, skin, avatar);
|
||||
auto mat = getCacheSkinningMats(drawable, skin, count, avatar);
|
||||
//</FS:Beq>
|
||||
|
||||
stop_glerror();
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#define LL_LLDRAWPOOLAVATAR_H
|
||||
|
||||
#include "lldrawpool.h"
|
||||
#include "fsareasearch.h"
|
||||
|
||||
class LLVOAvatar;
|
||||
class LLGLSLShader;
|
||||
|
|
@ -64,7 +65,10 @@ public:
|
|||
/*virtual*/ BOOL isDead();
|
||||
|
||||
static LLMatrix4& getModelView();
|
||||
|
||||
//<FS:Beq> per frame cache
|
||||
static LLMatrix4a* getCacheSkinningMats(LLDrawable* drawable, const LLMeshSkinInfo* skin, U32 count,
|
||||
LLVOAvatar* avatar);
|
||||
//</FS:Beq>
|
||||
/*virtual*/ LLDrawPool *instancePool();
|
||||
|
||||
/*virtual*/ S32 getNumPasses();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "llvertexbuffer.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "lldrawable.h"
|
||||
#include "lljoint.h"
|
||||
|
||||
class LLFacePool;
|
||||
class LLVolume;
|
||||
|
|
@ -267,7 +268,6 @@ public:
|
|||
|
||||
private:
|
||||
LLPointer<LLVertexBuffer> mVertexBuffer;
|
||||
|
||||
U32 mState;
|
||||
LLFacePool* mDrawPoolp;
|
||||
U32 mPoolType;
|
||||
|
|
|
|||
|
|
@ -4318,12 +4318,16 @@ BOOL LLModelPreview::render()
|
|||
//quick 'n dirty software vertex skinning
|
||||
|
||||
//build matrix palette
|
||||
|
||||
//<FS:Beq> use Mat4a part of the caching changes, no point in using the cache itself in the preview though.
|
||||
//LLMatrix4 mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
const LLMeshSkinInfo *skin = &model->mSkinInfo;
|
||||
const LLMeshSkinInfo *skin = &model->mSkinInfo;
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count,
|
||||
skin, getPreviewAvatar());
|
||||
//LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count,
|
||||
// skin, getPreviewAvatar());
|
||||
LLSkinningUtil::initSkinningMatrixPalette(mat, count,
|
||||
skin, getPreviewAvatar());
|
||||
//</FS:Beq>
|
||||
LLMatrix4a bind_shape_matrix;
|
||||
bind_shape_matrix.loadu(skin->mBindShapeMatrix);
|
||||
U32 max_joints = LLSkinningUtil::getMaxJointCount();
|
||||
|
|
|
|||
|
|
@ -128,49 +128,100 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin
|
|||
skin->mInvalidJointsScrubbed = true;
|
||||
}
|
||||
|
||||
//<FS:Beq> Per frame SkinningMatrix Caching
|
||||
//void LLSkinningUtil::initSkinningMatrixPalette(
|
||||
// LLMatrix4* mat,
|
||||
// S32 count,
|
||||
// const LLMeshSkinInfo* skin,
|
||||
// LLVOAvatar *avatar)
|
||||
//{
|
||||
// initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
|
||||
// for (U32 j = 0; j < count; ++j)
|
||||
// {
|
||||
// LLJoint *joint = avatar->getJoint(skin->mJointNums[j]);
|
||||
// if (joint)
|
||||
// {
|
||||
//#define MAT_USE_SSE
|
||||
//#ifdef MAT_USE_SSE
|
||||
// LLMatrix4a bind, world, res;
|
||||
// bind.loadu(skin->mInvBindMatrix[j]);
|
||||
// world.loadu(joint->getWorldMatrix());
|
||||
// matMul(bind, world, res);
|
||||
// memcpy(mat[j].mMatrix, res.mMatrix, 16 * sizeof(float));
|
||||
//#else
|
||||
// mat[j] = skin->mInvBindMatrix[j];
|
||||
// mat[j] *= joint->getWorldMatrix();
|
||||
//#endif
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// mat[j] = skin->mInvBindMatrix[j];
|
||||
// // This shouldn't happen - in mesh upload, skinned
|
||||
// // rendering should be disabled unless all joints are
|
||||
// // valid. In other cases of skinned rendering, invalid
|
||||
// // joints should already have been removed during scrubInvalidJoints().
|
||||
// LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
// << " rigged to invalid joint name " << skin->mJointNames[j]
|
||||
// << " num " << skin->mJointNums[j] << LL_ENDL;
|
||||
// LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
// << " avatar build state: isBuilt() " << avatar->isBuilt()
|
||||
// << " mInitFlags " << avatar->mInitFlags << LL_ENDL;
|
||||
//#if 0
|
||||
// dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin);
|
||||
//#endif
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
static LLTrace::BlockTimerStatHandle FTM_SKINNING_INIT("Init Skinning Mats");
|
||||
#endif
|
||||
|
||||
void LLSkinningUtil::initSkinningMatrixPalette(
|
||||
LLMatrix4* mat,
|
||||
LLMatrix4a* mat,
|
||||
S32 count,
|
||||
const LLMeshSkinInfo* skin,
|
||||
LLVOAvatar *avatar)
|
||||
{
|
||||
initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
|
||||
for (U32 j = 0; j < count; ++j)
|
||||
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
||||
// This timer is too hot for normal use (though better now with caching)
|
||||
LL_RECORD_BLOCK_TIME(FTM_SKINNING_INIT);
|
||||
#endif
|
||||
LLMatrix4a bind[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
LLMatrix4a world[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
|
||||
initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
|
||||
// TODO: Refactored to encourage the compiler to optimise better but it's too old and stubborn. Need to hand tool the SIMD.
|
||||
// TODO: There are two overheads in this function casued by the unaligned loads. use Matrix4a
|
||||
// TODO: getWorldMatrix forces a reverse recursion up through the skelly. Check if this is happening efficiently.
|
||||
for (S32 j = 0; j < count; ++j)
|
||||
{
|
||||
LLJoint *joint = avatar->getJoint(skin->mJointNums[j]);
|
||||
if (joint)
|
||||
{
|
||||
#define MAT_USE_SSE
|
||||
#ifdef MAT_USE_SSE
|
||||
LLMatrix4a bind, world, res;
|
||||
bind.loadu(skin->mInvBindMatrix[j]);
|
||||
world.loadu(joint->getWorldMatrix());
|
||||
matMul(bind,world,res);
|
||||
memcpy(mat[j].mMatrix,res.mMatrix,16*sizeof(float));
|
||||
#else
|
||||
mat[j] = skin->mInvBindMatrix[j];
|
||||
mat[j] *= joint->getWorldMatrix();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
mat[j] = skin->mInvBindMatrix[j];
|
||||
// This shouldn't happen - in mesh upload, skinned
|
||||
// rendering should be disabled unless all joints are
|
||||
// valid. In other cases of skinned rendering, invalid
|
||||
// joints should already have been removed during scrubInvalidJoints().
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
<< " rigged to invalid joint name " << skin->mJointNames[j]
|
||||
<< " num " << skin->mJointNums[j] << LL_ENDL;
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
<< " avatar build state: isBuilt() " << avatar->isBuilt()
|
||||
<< " mInitFlags " << avatar->mInitFlags << LL_ENDL;
|
||||
#if 0
|
||||
dump_avatar_and_skin_state("initSkinningMatrixPalette joint not found", avatar, skin);
|
||||
#endif
|
||||
}
|
||||
if (joint != nullptr){
|
||||
bind[j].loadu(skin->mInvBindMatrix[j]);
|
||||
world[j].loadu(joint->getWorldMatrix());
|
||||
matMul(bind[j], world[j], mat[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
mat[j].loadu(skin->mInvBindMatrix[j]);
|
||||
// This shouldn't happen - in mesh upload, skinned
|
||||
// rendering should be disabled unless all joints are
|
||||
// valid. In other cases of skinned rendering, invalid
|
||||
// joints should already have been removed during scrubInvalidJoints().
|
||||
// Beq note - Oct 2018 Animesh - Many rigged meshes still fail here. ('mElbowLeeft' typo in the rigging data)
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
<< " rigged to invalid joint name " << skin->mJointNames[j]
|
||||
<< " num " << skin->mJointNums[j] << LL_ENDL;
|
||||
LL_WARNS_ONCE("Avatar") << avatar->getFullname()
|
||||
<< " avatar build state: isBuilt() " << avatar->isBuilt()
|
||||
<< " mInitFlags " << avatar->mInitFlags << LL_ENDL;
|
||||
|
||||
}
|
||||
//LL_DEBUGS("Skinning") << "[" << avatar->getFullname() << "] joint(" << skin->mJointNames[j] << ") matices bind(" << bind << ") world(" << world << ")" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
//</FS:Beq>
|
||||
|
||||
void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,8 +38,11 @@ namespace LLSkinningUtil
|
|||
U32 getMaxJointCount();
|
||||
U32 getMeshJointCount(const LLMeshSkinInfo *skin);
|
||||
void scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin);
|
||||
void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar *avatar);
|
||||
void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
|
||||
//<FS:Beq> Per frame SkinningMatrix Caching
|
||||
//void initSkinningMatrixPalette(LLMatrix4* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar* avatar);
|
||||
void initSkinningMatrixPalette(LLMatrix4a* mat, S32 count, const LLMeshSkinInfo* skin, LLVOAvatar* avatar);
|
||||
//</FS:Beq>
|
||||
void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
|
||||
void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin);
|
||||
void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints);
|
||||
void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar);
|
||||
|
|
|
|||
|
|
@ -1001,7 +1001,9 @@ void LLViewerObjectList::update(LLAgent &agent)
|
|||
static std::vector<LLViewerObject*> idle_list;
|
||||
|
||||
U32 idle_count = 0;
|
||||
|
||||
//<FS:Beq> need avatar count for dynamic BB load balancing
|
||||
mNumAvatars = 0;
|
||||
//</FS:Beq>
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_IDLE_COPY);
|
||||
|
||||
|
|
@ -1020,6 +1022,10 @@ void LLViewerObjectList::update(LLAgent &agent)
|
|||
idle_list[idle_count] = objectp;
|
||||
}
|
||||
++idle_count;
|
||||
//<FS:Beq> need avatar count for dynamic BB load balancing
|
||||
if (objectp->isAvatar())
|
||||
mNumAvatars++;
|
||||
//</FS:Beq>
|
||||
}
|
||||
else
|
||||
{ // There shouldn't be any NULL pointers in the list, but they have caused
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ public:
|
|||
boost::signals2::connection setNewObjectCallback(new_object_callback_t cb);
|
||||
new_object_signal_t mNewObjectSignal;
|
||||
// </FS:CR>
|
||||
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
// Only accessed by markDead in LLViewerObject
|
||||
|
|
@ -162,6 +161,10 @@ public:
|
|||
|
||||
S32 getOrphanParentCount() const { return (S32) mOrphanParents.size(); }
|
||||
S32 getOrphanCount() const { return mNumOrphans; }
|
||||
//<FS:Beq> need avatar count for dynamic BB load balancing
|
||||
S32 getAvatarCount() const { return mNumAvatars; }
|
||||
//</FS:Beq>
|
||||
|
||||
void orphanize(LLViewerObject *childp, U32 parent_id, U32 ip, U32 port);
|
||||
void findOrphans(LLViewerObject* objectp, U32 ip, U32 port);
|
||||
|
||||
|
|
@ -208,6 +211,9 @@ protected:
|
|||
std::vector<U64> mOrphanParents; // LocalID/ip,port of orphaned objects
|
||||
std::vector<OrphanInfo> mOrphanChildren; // UUID's of orphaned objects
|
||||
S32 mNumOrphans;
|
||||
//<FS:Beq> need avatar count for dynamic BB load balancing
|
||||
S32 mNumAvatars;
|
||||
//</FS:Beq>
|
||||
|
||||
typedef std::vector<LLPointer<LLViewerObject> > vobj_list_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -1390,9 +1390,10 @@ static LLTrace::BlockTimerStatHandle FTM_AVATAR_EXTENT_UPDATE("Av Upd Extent");
|
|||
void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE);
|
||||
|
||||
S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity");
|
||||
|
||||
//<FS:Beq> not called as often as it used to be but still no harm in optimising
|
||||
// S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity");
|
||||
static const LLCachedControl<S32> box_detail(gSavedSettings, "AvatarBoundingBoxComplexity");
|
||||
//<FS:Beq>
|
||||
// FIXME the update_min_max function used below assumes there is a
|
||||
// known starting point, but in general there isn't. Ideally the
|
||||
// box update logic should be modified to handle the no-point-yet
|
||||
|
|
@ -2569,7 +2570,21 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
}
|
||||
|
||||
// Update should be happening max once per frame.
|
||||
const S32 upd_freq = 4; // force update every upd_freq frames.
|
||||
// <FS:Beq> enable dynamic spreading of the BB calculations
|
||||
//const S32 upd_freq = 4; // force update every upd_freq frames.
|
||||
static LLCachedControl<S32> refreshPeriod(gSavedSettings, "AvatarExtentRefreshPeriodBatch");
|
||||
static LLCachedControl<S32> refreshMaxPerPeriod(gSavedSettings, "AvatarExtentRefreshMaxPerBatch");
|
||||
static S32 upd_freq = refreshPeriod; // initialise to a reasonable defauilt of 1 batch
|
||||
static S32 lastRecalibrationFrame{ 0 };
|
||||
|
||||
const S32 thisFrame = LLDrawable::getCurrentFrame();
|
||||
if (thisFrame - lastRecalibrationFrame >= upd_freq)
|
||||
{
|
||||
// Only update at the start of a cycle. .
|
||||
upd_freq = (((gObjectList.getAvatarCount() - 1) / refreshMaxPerPeriod) + 1)*refreshPeriod;
|
||||
lastRecalibrationFrame = thisFrame;
|
||||
}
|
||||
//</FS:Beq>
|
||||
if ((mLastAnimExtents[0]==LLVector3())||
|
||||
(mLastAnimExtents[1])==LLVector3())
|
||||
{
|
||||
|
|
@ -2577,7 +2592,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
|
|||
}
|
||||
else
|
||||
{
|
||||
mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0);
|
||||
//<FS:Beq> enable dynamic spreading of the BB calculations
|
||||
//mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0]) % upd_freq == 0);
|
||||
mNeedsExtentUpdate = ((thisFrame + mID.mData[0]) % upd_freq == 0);
|
||||
//</FS:Beq>
|
||||
}
|
||||
|
||||
LLScopedContextString str("avatar_idle_update " + getFullname());
|
||||
|
|
@ -10661,8 +10679,10 @@ void LLVOAvatar::updateRiggingInfo()
|
|||
|
||||
//LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL;
|
||||
//LL_DEBUGS("RigSpammish") << getFullname() << " after update rig tab:" << LL_ENDL; // <FS:Ansariel> Performance tweak
|
||||
S32 joint_count, box_count;
|
||||
showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count);
|
||||
//<FS:Beq> remove debug only stuff on hot path
|
||||
//S32 joint_count, box_count;
|
||||
//showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count);
|
||||
//</FS:Beq>
|
||||
//LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; // <FS:Ansariel> Performance tweak
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1641,7 +1641,11 @@ BOOL LLVOVolume::updateLOD()
|
|||
|
||||
if (lod_changed)
|
||||
{
|
||||
if (debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
//<FS:Beq> avoid unfortunate sleep during trylock by static check
|
||||
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
|
||||
if (debug_logging_on)
|
||||
//</FS:Beq>
|
||||
{
|
||||
if (isAnimatedObject() && isRiggedMesh())
|
||||
{
|
||||
|
|
@ -4615,8 +4619,12 @@ const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const
|
|||
|
||||
void LLVOVolume::markForUpdate(BOOL priority)
|
||||
{
|
||||
if (debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
{
|
||||
//<FS:Beq> avoid unfortunate sleep during trylock by static check
|
||||
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
|
||||
if (debug_logging_on)
|
||||
//</FS:Beq>
|
||||
{
|
||||
if (isAnimatedObject() && isRiggedMesh())
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%p", this);
|
||||
|
|
@ -4941,6 +4949,7 @@ static LLTrace::BlockTimerStatHandle FTM_RIGGED_OCTREE("Octree");
|
|||
|
||||
void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume)
|
||||
{
|
||||
|
||||
bool copy = false;
|
||||
if (volume->getNumVolumeFaces() != getNumVolumeFaces())
|
||||
{
|
||||
|
|
@ -4982,7 +4991,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
|
|||
|
||||
LLMatrix4a mat[kMaxJoints];
|
||||
U32 maxJoints = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, maxJoints, skin, avatar);
|
||||
//<FS:Beq> Skinning Matrix caching
|
||||
//LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4)mat, maxJoints, skin, avatar);
|
||||
LLSkinningUtil::initSkinningMatrixPalette(mat, maxJoints, skin, avatar);
|
||||
//</FS:Beq>
|
||||
|
||||
S32 rigged_vert_count = 0;
|
||||
S32 rigged_face_count = 0;
|
||||
|
|
@ -5669,7 +5681,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string vobj_name = llformat("Vol%p", vobj);
|
||||
//<FS:Beq> Stop doing stupid stuff we don;t need to.
|
||||
// Moving this inside a debug enabled check
|
||||
// std::string vobj_name = llformat("Vol%p", vobj);
|
||||
//</FS:Beq>
|
||||
|
||||
if (vobj->isMesh() &&
|
||||
((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
|
||||
|
|
@ -5683,26 +5698,37 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
const LLVector3& scale = vobj->getScale();
|
||||
group->mSurfaceArea += volume->getSurfaceArea() * llmax(llmax(scale.mV[0], scale.mV[1]), scale.mV[2]);
|
||||
}
|
||||
|
||||
bool is_mesh = vobj->isMesh();
|
||||
F32 est_tris = vobj->getEstTrianglesMax();
|
||||
//<FS:Beq> Stop doing stupid stuff we don;t need on the critical path
|
||||
//bool is_mesh = vobj->isMesh();
|
||||
//F32 est_tris = vobj->getEstTrianglesMax();
|
||||
|
||||
vobj->updateControlAvatar();
|
||||
|
||||
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment()
|
||||
<< " is_mesh " << is_mesh
|
||||
<< " est_tris " << est_tris
|
||||
<< " is_animated " << vobj->isAnimatedObject()
|
||||
<< " can_animate " << vobj->canBeAnimatedObject()
|
||||
<< " cav " << vobj->getControlAvatar()
|
||||
<< " lod " << vobj->getLOD()
|
||||
<< " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED))
|
||||
<< " drawable state " << drawablep->getState()
|
||||
<< " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false)
|
||||
<< " frame " << LLFrameTimer::getFrameCount()
|
||||
<< LL_ENDL;
|
||||
// Also avoid unfortunate sleep during trylock by static check
|
||||
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
|
||||
if (debug_logging_on)
|
||||
//</FS:Beq>
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%p", vobj);
|
||||
bool is_mesh = vobj->isMesh();
|
||||
F32 est_tris = vobj->getEstTrianglesMax();
|
||||
|
||||
LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuilding, isAttachment: " << (U32) vobj->isAttachment()
|
||||
<< " is_mesh " << is_mesh
|
||||
<< " est_tris " << est_tris
|
||||
<< " is_animated " << vobj->isAnimatedObject()
|
||||
<< " can_animate " << vobj->canBeAnimatedObject()
|
||||
<< " cav " << vobj->getControlAvatar()
|
||||
<< " lod " << vobj->getLOD()
|
||||
<< " drawable rigged " << (drawablep->isState(LLDrawable::RIGGED))
|
||||
<< " drawable state " << drawablep->getState()
|
||||
<< " playing " << (U32) (vobj->getControlAvatar() ? vobj->getControlAvatar()->mPlaying : false)
|
||||
<< " frame " << LLFrameTimer::getFrameCount()
|
||||
<< LL_ENDL;
|
||||
}
|
||||
//<FS:Beq> Pointless. We already checked this and have used it.
|
||||
//llassert_always(vobj);
|
||||
|
||||
llassert_always(vobj);
|
||||
|
||||
// <FS:AO> Z's protection auto-derender code
|
||||
if (enableVolumeSAPProtection())
|
||||
|
|
@ -6242,8 +6268,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
|
|||
if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
|
||||
{
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
if (debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
{
|
||||
//<FS:Beq> avoid unfortunate sleep during trylock by static check
|
||||
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
|
||||
if (debug_logging_on)
|
||||
//</FS:Beq>
|
||||
{
|
||||
if (vobj->isAnimatedObject() && vobj->isRiggedMesh())
|
||||
{
|
||||
std::string vobj_name = llformat("Vol%p", vobj);
|
||||
|
|
|
|||
|
|
@ -3480,8 +3480,12 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
|
|||
{
|
||||
if (drawablep && !drawablep->isDead() && assertInitialized())
|
||||
{
|
||||
if (debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
{
|
||||
//<FS:Beq> avoid unfortunate sleep during trylock by static check
|
||||
//if(debugLoggingEnabled("AnimatedObjectsLinkset"))
|
||||
static auto debug_logging_on = debugLoggingEnabled("AnimatedObjectsLinkset");
|
||||
if (debug_logging_on)
|
||||
//</FS:Beq>
|
||||
{
|
||||
LLVOVolume *vol_obj = drawablep->getVOVolume();
|
||||
if (vol_obj && vol_obj->isAnimatedObject() && vol_obj->isRiggedMesh())
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue