From 9be476e3bb4cde7b086581931ed39ac137207ffe Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 9 Jul 2018 22:30:50 +0100 Subject: MAINT-7926, MAINT-8400 - fixes related to bounding box and LOD calculations for rigged meshes in animated objects --- indra/newview/llcontrolavatar.cpp | 13 ++++++++++++- indra/newview/lldrawable.cpp | 20 ++++++++++++++++++++ indra/newview/llskinningutil.cpp | 25 ++++++++++++++++++++++--- indra/newview/llvoavatar.cpp | 6 +++--- indra/newview/llvovolume.cpp | 28 ++++++++++++++++++++++++++-- indra/newview/llvovolume.h | 3 +++ 6 files changed, 86 insertions(+), 9 deletions(-) diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 88152d2dc6..93b178e0e9 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -316,7 +316,10 @@ void LLControlAvatar::updateDebugText() F32 est_tris = 0.f; F32 est_streaming_tris = 0.f; F32 streaming_cost = 0.f; - + std::string cam_dist_string = ""; + S32 cam_dist_count = 0; + F32 lod_radius = mRootVolp->mLODRadius; + for (std::vector::iterator it = volumes.begin(); it != volumes.end(); ++it) { @@ -351,6 +354,7 @@ void LLControlAvatar::updateDebugText() { // Rigged/animatable mesh type_string += "R"; + lod_radius = volp->mLODRadius; } else if (volp->isMesh()) { @@ -362,6 +366,12 @@ void LLControlAvatar::updateDebugText() // Any other prim type_string += "P"; } + if (cam_dist_count < 4) + { + cam_dist_string += LLStringOps::getReadableNumber(volp->mLODDistance) + "/" + + LLStringOps::getReadableNumber(volp->mLODAdjustedDistance) + " "; + cam_dist_count++; + } } else { @@ -376,6 +386,7 @@ void LLControlAvatar::updateDebugText() addDebugText(llformat("flags %s", animated_object_flag_string.c_str())); addDebugText(llformat("tris %d (est %.1f, streaming %.1f), verts %d", total_tris, est_tris, est_streaming_tris, total_verts)); addDebugText(llformat("pxarea %s rank %d", LLStringOps::getReadableNumber(getPixelArea()).c_str(), getVisibilityRank())); + addDebugText(llformat("lod_radius %s dists %s", LLStringOps::getReadableNumber(lod_radius).c_str(),cam_dist_string.c_str())); if (mPositionConstraintFixup.length() > 0.0f) { addDebugText(llformat("pos fix (%.1f %.1f %.1f)", diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 22ed54913a..6d9c2c5eb8 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -32,6 +32,7 @@ #include "material_codes.h" // viewer includes +#include "llagent.h" #include "llcriticaldamp.h" #include "llface.h" #include "lllightconstants.h" @@ -900,6 +901,25 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) } } } + + // MAINT-7926 Handle volumes in an animated object as a special case + if (volume->getAvatar() && volume->getAvatar()->isControlAvatar()) + { + const LLVector3* av_box = volume->getAvatar()->getLastAnimExtents(); + LLVector3d cam_pos = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()); + LLVector3 cam_region_pos = LLVector3(cam_pos - volume->getRegion()->getOriginGlobal()); + + LLVector3 cam_to_box_offset = point_to_box_offset(cam_region_pos, av_box); + //LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname() + // << " pos (ignored) " << pos + // << " cam pos " << cam_pos + // << " cam region pos " << cam_region_pos + // << " box " << av_box[0] << "," << av_box[1] << LL_ENDL; + mDistanceWRTCamera = ll_round(cam_to_box_offset.magVec(), 0.01f); + mVObjp->updateLOD(); + return; + } + } else { diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 0878cee1a3..1f39097a98 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -241,11 +241,29 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a for (S32 i=0; i 0.0f) + { + for (U32 k=0; k<4; ++k) + { + wght[k] /= scale; + } + } for (U32 k=0; k<4; ++k) { - S32 joint_index = llfloor(w[k]); - if (w[k]-joint_index > 0.0f) + S32 joint_index = idx[k]; + if (wght[k] > 0.0f) { S32 joint_num = skin->mJointNums[joint_index]; if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) @@ -263,6 +281,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a matMul(bind_shape, inv_bind, mat); LLVector4a pos_joint_space; mat.affineTransform(pos, pos_joint_space); + pos_joint_space.mul(wght[k]); LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); update_min_max(extents[0], extents[1], pos_joint_space); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 9b8af204cf..1ed105f8d4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1316,10 +1316,10 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) newMin = pos; newMax = pos; - //stretch bounding box by joint positions. No point doing this for + //stretch bounding box by joint positions. Doing this for //control avs, where the polymeshes aren't maintained or - //displayed. - if (box_detail>=1 && !isControlAvatar()) + //displayed, can give inaccurate boxes due to joints stuck at (0,0,0). + if ((box_detail>=1) && !isControlAvatar()) { for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 7f353ea8aa..6bcbebb546 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -108,6 +108,10 @@ static LLTrace::BlockTimerStatHandle FTM_VOLUME_TEXTURES("Volume Textures"); extern BOOL gGLDebugLoggingEnabled; +#if LL_MSVC +#pragma optimize("", off) +#endif + // Implementation class of LLMediaDataClientObject. See llmediadataclient.h class LLMediaDataClientObjectImpl : public LLMediaDataClientObject { @@ -219,6 +223,9 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mFaceMappingChanged = FALSE; mLOD = MIN_LOD; + mLODDistance = 0.0f; + mLODAdjustedDistance = 0.0f; + mLODRadius = 0.0f; mTextureAnimp = NULL; mVolumeChanged = FALSE; mVObjRadius = LLVector3(1,1,0.5f).length(); @@ -1293,7 +1300,19 @@ BOOL LLVOVolume::calcLOD() } distance = avatar->mDrawable->mDistanceWRTCamera; - radius = avatar->getBinRadius(); + if (avatar->isControlAvatar()) + { + // MAINT-7926 Handle volumes in an animated object as a special case + const LLVector3* box = avatar->getLastAnimExtents(); + LLVector3 diag = box[1] - box[0]; + radius = diag.magVec() * 0.5f; + //LL_DEBUGS("DynamicBox") << avatar->getFullname() << " diag " << diag << " radius " << radius << LL_ENDL; + } + else + { + // Note this isn't really a radius, so distance calcs are off by factor of 2 + radius = avatar->getBinRadius(); + } if (distance <= 0.f || radius <= 0.f) { LL_DEBUGS("CalcLOD") << "avatar distance/radius uninitialized, skipping" << LL_ENDL; @@ -1313,7 +1332,10 @@ BOOL LLVOVolume::calcLOD() //hold onto unmodified distance for debugging //F32 debug_distance = distance; - + + mLODDistance = distance; + mLODRadius = radius; + distance *= sDistanceFactor; F32 rampDist = LLVOVolume::sLODFactor * 2; @@ -1335,6 +1357,8 @@ BOOL LLVOVolume::calcLOD() lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV(); } + mLODAdjustedDistance = distance; + cur_detail = computeLODDetail(ll_round(distance, 0.01f), ll_round(radius, 0.01f), lod_factor); if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT) && mDrawable->getFace(0)) diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 446d4a3d37..0882fc095d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -380,6 +380,9 @@ public: LLViewerTextureAnim *mTextureAnimp; U8 mTexAnimMode; + F32 mLODDistance; + F32 mLODAdjustedDistance; + F32 mLODRadius; private: friend class LLDrawable; friend class LLFace; -- cgit v1.2.3