From 1d3b85356f516fa2f5a5d49572743dc2a03ac86a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Apr 2022 16:19:42 -0700 Subject: SL-17021: Only calculate the octree for a skinned mesh if intersection falls inside an on-the-fly calculated bounding box. Technically not a broadphase check, but better than calculating an octree for a bunch of meshes. --- indra/newview/llvovolume.cpp | 17 ++++++++--------- indra/newview/llvovolume.h | 7 ++++--- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index fce233969b..6a53e704c3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4660,7 +4660,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } - updateRiggedVolume(true, i); + // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. + // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. + updateRiggedVolume(true, i, false); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4784,7 +4786,7 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index) +void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. @@ -4819,10 +4821,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume, face_index); + mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index) +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; @@ -4974,15 +4976,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } + if (rebuild_face_octrees) { delete dst_face.mOctree; dst_face.mOctree = NULL; - LLVector4a size; - size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); - size.splat(size.getLength3().getF32()*0.5f); - - dst_face.createOctree(1.f); + dst_face.createOctree(); } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 00a0a1dfd0..f0213848c6 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -68,7 +68,7 @@ public: using FaceIndex = S32; static const FaceIndex UPDATE_ALL_FACES = -1; static const FaceIndex DO_NOT_UPDATE_FACES = -2; - void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES); + void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES, bool rebuild_face_octrees = true); std::string mExtraDebugText; }; @@ -365,8 +365,9 @@ public: S32 getMDCImplCount() { return mMDCImplCount; } - //rigged volume update (for raycasting) - void updateRiggedVolume(bool force_update = false, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES); + // Rigged volume update (for raycasting) + // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting + void updateRiggedVolume(bool force_update = false, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true); LLRiggedVolume* getRiggedVolume(); //returns true if volume should be treated as a rigged volume -- cgit v1.2.3