diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h index d8070b997..48416cfcb 100644 --- a/indra/newview/llcontrolavatar.h +++ b/indra/newview/llcontrolavatar.h @@ -39,6 +39,7 @@ public: LLControlAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual void initInstance(); // Called after construction to initialize the class. virtual ~LLControlAvatar(); + virtual LLControlAvatar* asControlAvatar() { return this; } void getNewConstraintFixups(LLVector3& new_pos_constraint, F32& new_scale_constraint) const; void matchVolumeTransform(); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 64c69b76f..97c3ffbc6 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1457,6 +1457,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* LLPointer buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); + if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD()) + { + return; + } + U32 data_mask = face->getRiggedVertexBufferDataMask(); if (!vol_face.mWeightsScrubbed) @@ -1557,9 +1562,15 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) { if (sShaderLevel > 0) { - 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; }); + static LLCachedControl sh_use_rigging_cache("SHUseRiggedMatrixCache", true); + auto& mesh_cache = avatar->getRiggedMatrixCache();; + auto rigged_matrix_data_iter = mesh_cache.cend(); + if (sh_use_rigging_cache) + { + auto& mesh_id = skin->mMeshID; + 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()) { LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, @@ -1567,8 +1578,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) FALSE, (GLfloat*)rigged_matrix_data_iter->second.second.data()); LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(rigged_matrix_data_iter->second.first - 1)); - - stop_glerror(); } else { @@ -1600,7 +1609,8 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow) mp[idx + 10] = m[10]; mp[idx + 11] = m[14]; } - mesh_cache.emplace_back(std::make_pair( skin->mMeshID, std::make_pair(count, mp) ) ); + if (sh_use_rigging_cache) + mesh_cache.emplace_back(std::make_pair( skin->mMeshID, std::make_pair(count, mp) ) ); LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, count, FALSE, diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 71b9a5dcc..fdd580477 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -257,6 +257,10 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a //S32 active_verts = 0; vol_face.mJointRiggingInfoTab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); LLJointRiggingInfoTab &rig_info_tab = vol_face.mJointRiggingInfoTab; + + LLMatrix4a bind_shape; + bind_shape.loadu(skin->mBindShapeMatrix); + for (S32 i=0; imInvBindMatrix[joint_index]); + LLMatrix4a mat; + mat.setMul(bind_shape, inv_bind); + LLVector4a pos_joint_space; + mat.affineTransform(pos, pos_joint_space); if (wght[k] > 0.0f) { S32 joint_num = skin->mJointNums[joint_index]; if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) { rig_info_tab[joint_num].setIsRiggedTo(true); - - // FIXME could precompute these matMuls. - LLMatrix4a bind_shape; - bind_shape.loadu(skin->mBindShapeMatrix); - LLMatrix4a inv_bind; - inv_bind.loadu(skin->mInvBindMatrix[joint_index]); - LLMatrix4a mat; - mat.setMul(bind_shape, inv_bind); - LLVector4a pos_joint_space; - mat.affineTransform(pos, pos_joint_space); - pos_joint_space.mul(wght[k]); + LLVector4a final_pos; + final_pos.setMul(pos_joint_space, wght[k]); LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); - update_min_max(extents[0], extents[1], pos_joint_space); + update_min_max(extents[0], extents[1], final_pos); } } } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3f24e1998..dcbdeb2da 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4912,7 +4912,7 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w root_pos += LLVector3d(getHoverOffset()); } - LLControlAvatar *cav = dynamic_cast(this); + LLControlAvatar *cav = asControlAvatar(); if (cav) { // SL-1350: Moved to LLDrawable::updateXform() @@ -5003,7 +5003,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) bool is_attachment = false; if (is_control_avatar) { - LLControlAvatar *cav = dynamic_cast(this); + LLControlAvatar *cav = asControlAvatar(); is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects } @@ -5577,10 +5577,19 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) } first_pass = FALSE; } - // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) - // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); - if ((getImage(TEX_HAIR_BAKED, 0) && - getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE) || LLDrawPoolAlpha::sShowDebugAlpha) + bool show_hair = false; + if (isControlAvatar()) + { + show_hair = isTextureVisible(TEX_HAIR_BAKED); + } + else + { + // Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair) + // TODO: 1.25 will be able to switch this logic back to calling isTextureVisible(); + auto image = getImage(TEX_HAIR_BAKED, 0); + show_hair = LLDrawPoolAlpha::sShowDebugAlpha || (image && image->getID() != IMG_INVISIBLE); + } + if (show_hair) { LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); if (hair_mesh) @@ -6783,7 +6792,7 @@ void LLVOAvatar::rebuildAttachmentOverrides() clearAttachmentOverrides(); // Handle the case that we're resetting the skeleton of an animated object. - LLControlAvatar *control_av = dynamic_cast(this); + LLControlAvatar *control_av = asControlAvatar(); if (control_av) { LLVOVolume *volp = control_av->mRootVolp; @@ -6837,7 +6846,7 @@ void LLVOAvatar::updateAttachmentOverrides() std::set meshes_seen; // Handle the case that we're updating the skeleton of an animated object. - LLControlAvatar *control_av = dynamic_cast(this); + LLControlAvatar *control_av = asControlAvatar(); if (control_av) { LLVOVolume *volp = control_av->mRootVolp; @@ -10402,7 +10411,7 @@ void LLVOAvatar::getAssociatedVolumes(std::vector& volumes) } } - LLControlAvatar *control_av = dynamic_cast(this); + LLControlAvatar *control_av = asControlAvatar(); if (control_av) { LLVOVolume *volp = control_av->mRootVolp; @@ -10616,7 +10625,7 @@ void LLVOAvatar::idleUpdateRenderComplexity() { if (isControlAvatar()) { - LLControlAvatar *cav = dynamic_cast(this); + LLControlAvatar *cav = asControlAvatar(); bool is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects if (is_attachment) { @@ -10891,7 +10900,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() // A standalone animated object needs to be accounted for // using its associated volume. Attached animated objects // will be covered by the subsequent loop over attachments. - LLControlAvatar *control_av = dynamic_cast(this); + LLControlAvatar *control_av = asControlAvatar(); if (control_av) { LLVOVolume *volp = control_av->mRootVolp; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 9ad8bfdb4..32c0df376 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -82,6 +82,7 @@ class LLViewerJoint; struct LLAppearanceMessageContents; class LLMeshSkinInfo; class LLViewerJointMesh; +class LLControlAvatar; class SHClientTagMgr : public LLSingleton, public boost::signals2::trackable { @@ -296,8 +297,9 @@ public: public: virtual bool isSelf() const { return false; } // True if this avatar is for this viewer's agent - virtual bool isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user) - virtual bool isUIAvatar() const { return mIsUIAvatar; } // True if this avatar is a supplemental av used in some UI views (no associated user) + bool isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user) + virtual LLControlAvatar* asControlAvatar() { return nullptr; } + bool isUIAvatar() const { return mIsUIAvatar; } // True if this avatar is a supplemental av used in some UI views (no associated user) private: //aligned members LL_ALIGN_16(LLVector4a mImpostorExtents[2]);