diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 607f290cee6673692801417fb889348c00798724..e56e3ef472f12e6bb93d876d4c6112bf7b040156 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1720,43 +1720,56 @@ 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(mat, count, skin, avatar); + auto rigged_matrix_data_iter = avatar->getRiggedMatrixCache().find(skin->mMeshID); + if (rigged_matrix_data_iter != avatar->getRiggedMatrixCache().cend()) + { + LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, + rigged_matrix_data_iter->second.first, + FALSE, + (GLfloat*) rigged_matrix_data_iter->second.second.data()); - stop_glerror(); + 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); - F32 mp[LL_MAX_JOINTS_PER_MESH_OBJECT*12]; + stop_glerror(); - for (U32 i = 0; i < count; ++i) - { - F32* m = (F32*) mat[i].getF32ptr(); + std::array<F32, LL_MAX_JOINTS_PER_MESH_OBJECT * 12> mp; - U32 idx = i*12; + for (U32 i = 0; i < count; ++i) + { + F32* m = (F32*) mat[i].getF32ptr(); - mp[idx+0] = m[0]; - mp[idx+1] = m[1]; - mp[idx+2] = m[2]; - mp[idx+3] = m[12]; + U32 idx = i * 12; - mp[idx+4] = m[4]; - mp[idx+5] = m[5]; - mp[idx+6] = m[6]; - mp[idx+7] = m[13]; + mp[idx + 0] = m[0]; + mp[idx + 1] = m[1]; + mp[idx + 2] = m[2]; + mp[idx + 3] = m[12]; - mp[idx+8] = m[8]; - mp[idx+9] = m[9]; - mp[idx+10] = m[10]; - mp[idx+11] = m[14]; - } + mp[idx + 4] = m[4]; + mp[idx + 5] = m[5]; + mp[idx + 6] = m[6]; + mp[idx + 7] = m[13]; - LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, - count, - FALSE, - (GLfloat*) mp); + mp[idx + 8] = m[8]; + mp[idx + 9] = m[9]; + mp[idx + 10] = m[10]; + mp[idx + 11] = m[14]; + } + avatar->getRiggedMatrixCache().emplace(skin->mMeshID, std::make_pair(count, mp)); + LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, + count, + FALSE, + (GLfloat*) mp.data()); - stop_glerror(); + stop_glerror(); + } } else { diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 25d966ec6f0c9c4f3394532388ca53065c275a2b..1088ee202618b021a83fddba8cde16ea8eb5a2f9 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -36,8 +36,6 @@ class LLMeshSkinInfo; class LLVolume; class LLVolumeFace; -constexpr U32 JOINT_COUNT = 52; - class LLDrawPoolAvatar : public LLFacePool { public: diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 0b5aa080abda1debec260d04417bdd0cbef59f60..cce918c922b4a049fb720c48369385848e6ecfa3 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -81,6 +81,7 @@ #include "llwlparammanager.h" #include "llwaterparammanager.h" #include "llscenemonitor.h" +#include "lldrawpoolavatar.h" #include <glm/vec3.hpp> #include <glm/mat4x4.hpp> @@ -265,6 +266,14 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LL_RECORD_BLOCK_TIME(FTM_RENDER); + for(auto avatar : LLCharacter::sInstances) + { + LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(avatar); + if (!avatar) continue; + if (avatar->isDead()) continue; + avatar->clearRiggedMatrixCache(); + } + if (gWindowResized) { //skip render on frames where window has been resized LL_RECORD_BLOCK_TIME(FTM_RESIZE_WINDOW); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a91d2a564d0b5960e1552e6ffcd955e1c0f8ee64..7fac82cfc332da3d120420ec227abc6d45ab812f 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -45,6 +45,7 @@ #include "llviewertexlayer.h" #include "material_codes.h" // LL_MCODE_END #include "llviewerstats.h" +#include "llskinningutil.h" extern const LLUUID ANIM_AGENT_BODY_NOISE; extern const LLUUID ANIM_AGENT_BREATHE_ROT; @@ -1037,6 +1038,20 @@ protected: // Shared with LLVOAvatarSelf ** ** *******************************************************************************/ +public: + typedef std::array<F32, LL_MAX_JOINTS_PER_MESH_OBJECT * 12> rigged_matrix_array_t; + typedef std::map<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; + }; // LLVOAvatar extern const F32 SELF_ADDITIONAL_PRI; extern const S32 MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL;