Per-frame per-avie rigged transform matrix cache from Alchemy, with minor alterations.
This commit is contained in:
@@ -1457,6 +1457,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
||||
}
|
||||
}
|
||||
|
||||
extern int sMaxCacheHit;
|
||||
extern int sCurCacheHit;
|
||||
|
||||
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||
{
|
||||
if ((avatar->isSelf() && !gAgent.needsRenderAvatar()) || !gMeshRepo.meshRezEnabled())
|
||||
@@ -1516,44 +1519,57 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||
if (buff)
|
||||
{
|
||||
if (sShaderLevel > 0)
|
||||
{ //upload matrix palette to shader
|
||||
// upload matrix palette to shader
|
||||
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12];
|
||||
|
||||
for (U32 i = 0; i < count; ++i)
|
||||
{
|
||||
auto& mesh_cache = avatar->getRiggedMatrixCache();
|
||||
auto& mesh_id = skin->mMeshID;
|
||||
auto rigged_matrix_data_iter = find_if(mesh_cache.begin(), mesh_cache.end(), [&mesh_id](decltype(mesh_cache[0]) & entry) { return entry.first == mesh_id; });
|
||||
if (rigged_matrix_data_iter != avatar->getRiggedMatrixCache().cend())
|
||||
{
|
||||
F32* m = (F32*) mat[i].getF32ptr();
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
|
||||
rigged_matrix_data_iter->second.first,
|
||||
FALSE,
|
||||
(GLfloat*)rigged_matrix_data_iter->second.second.data());
|
||||
LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(rigged_matrix_data_iter->second.first - 1));
|
||||
|
||||
U32 idx = i*12;
|
||||
|
||||
mp[idx+0] = m[0];
|
||||
mp[idx+1] = m[1];
|
||||
mp[idx+2] = m[2];
|
||||
mp[idx+3] = m[12];
|
||||
|
||||
mp[idx+4] = m[4];
|
||||
mp[idx+5] = m[5];
|
||||
mp[idx+6] = m[6];
|
||||
mp[idx+7] = m[13];
|
||||
|
||||
mp[idx+8] = m[8];
|
||||
mp[idx+9] = m[9];
|
||||
mp[idx+10] = m[10];
|
||||
mp[idx+11] = m[14];
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
// upload matrix palette to shader
|
||||
LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
|
||||
U32 count = LLSkinningUtil::getMeshJointCount(skin);
|
||||
LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, avatar);
|
||||
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
|
||||
count,
|
||||
FALSE,
|
||||
(GLfloat*) mp);
|
||||
std::array<F32, LL_MAX_JOINTS_PER_MESH_OBJECT * 12> mp;
|
||||
|
||||
LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(count-1));
|
||||
for (U32 i = 0; i < count; ++i)
|
||||
{
|
||||
F32* m = (F32*)mat[i].getF32ptr();
|
||||
|
||||
U32 idx = i * 12;
|
||||
|
||||
mp[idx + 0] = m[0];
|
||||
mp[idx + 1] = m[1];
|
||||
mp[idx + 2] = m[2];
|
||||
mp[idx + 3] = m[12];
|
||||
|
||||
mp[idx + 4] = m[4];
|
||||
mp[idx + 5] = m[5];
|
||||
mp[idx + 6] = m[6];
|
||||
mp[idx + 7] = m[13];
|
||||
|
||||
mp[idx + 8] = m[8];
|
||||
mp[idx + 9] = m[9];
|
||||
mp[idx + 10] = m[10];
|
||||
mp[idx + 11] = m[14];
|
||||
}
|
||||
mesh_cache.emplace_back(std::make_pair( skin->mMeshID, std::make_pair(count, mp) ) );
|
||||
LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
|
||||
count,
|
||||
FALSE,
|
||||
(GLfloat*)mp.data());
|
||||
LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(count - 1));
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@
|
||||
#include "llviewerregion.h"
|
||||
#include "lldrawpoolwater.h"
|
||||
#include "lldrawpoolbump.h"
|
||||
#include "lldrawpoolavatar.h"
|
||||
#include "llwlparammanager.h"
|
||||
#include "llwaterparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
@@ -255,11 +256,24 @@ static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class");
|
||||
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Bump");
|
||||
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_LIST("List");
|
||||
static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_DELETE("Delete");
|
||||
|
||||
int sMaxCacheHit = 0;
|
||||
int sCurCacheHit = 0;
|
||||
|
||||
// Paint the display!
|
||||
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, bool tiling)
|
||||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_RENDER);
|
||||
|
||||
for (auto avatar : LLCharacter::sInstances)
|
||||
{
|
||||
LLVOAvatar* avatarp = dynamic_cast<LLVOAvatar*>(avatar);
|
||||
if (!avatarp) continue;
|
||||
if (avatarp->isDead()) continue;
|
||||
avatarp->clearRiggedMatrixCache();
|
||||
}
|
||||
sCurCacheHit = 0;
|
||||
|
||||
if (gWindowResized)
|
||||
{ //skip render on frames where window has been resized
|
||||
gGL.flush();
|
||||
|
||||
@@ -1096,6 +1096,21 @@ protected: // Shared with LLVOAvatarSelf
|
||||
/** Support classes
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
public:
|
||||
typedef std::array<F32, LL_MAX_JOINTS_PER_MESH_OBJECT * 12> rigged_matrix_array_t;
|
||||
typedef std::vector<std::pair<LLUUID, std::pair<U32, rigged_matrix_array_t> > > rigged_transformation_cache_t;
|
||||
auto& getRiggedMatrixCache()
|
||||
{
|
||||
return mRiggedMatrixDataCache;
|
||||
}
|
||||
void clearRiggedMatrixCache()
|
||||
{
|
||||
mRiggedMatrixDataCache.clear();
|
||||
}
|
||||
private:
|
||||
rigged_transformation_cache_t mRiggedMatrixDataCache;
|
||||
|
||||
// <edit>
|
||||
|
||||
//Avatar idle timer
|
||||
|
||||
Reference in New Issue
Block a user