summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llvovolume.cpp40
-rw-r--r--indra/newview/llvovolume.h12
2 files changed, 43 insertions, 9 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 72c03b395f..cb58c173d9 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4773,7 +4773,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- updateRiggedVolume(true);
+ updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES);
volume = mRiggedVolume;
transform = false;
}
@@ -4848,6 +4848,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
continue;
}
+ // 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);
@@ -4971,13 +4974,13 @@ void LLVOVolume::clearRiggedVolume()
}
}
-void LLVOVolume::updateRiggedVolume(bool force_update)
+void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
//Update mRiggedVolume to match current animation frame of avatar.
//Also update position/size in octree.
- if ((!force_update) && (!treatAsRigged()))
+ if ((!force_treat_as_rigged) && (!treatAsRigged()))
{
clearRiggedVolume();
@@ -5006,10 +5009,15 @@ void LLVOVolume::updateRiggedVolume(bool force_update)
updateRelativeXform();
}
- mRiggedVolume->update(skin, avatar, volume);
+ mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees);
}
-void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume)
+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;
@@ -5040,7 +5048,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
if (is_paused)
{
S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame();
- if (frames_paused > 2)
+ if (frames_paused > 1)
{
return;
}
@@ -5059,7 +5067,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
S32 rigged_vert_count = 0;
S32 rigged_face_count = 0;
LLVector4a box_min, box_max;
- for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+ S32 face_begin;
+ S32 face_end;
+ if (face_index == DO_NOT_UPDATE_FACES)
+ {
+ face_begin = 0;
+ face_end = 0;
+ }
+ else if (face_index == UPDATE_ALL_FACES)
+ {
+ face_begin = 0;
+ face_end = volume->getNumVolumeFaces();
+ }
+ else
+ {
+ face_begin = face_index;
+ face_end = face_begin + 1;
+ }
+ for (S32 i = face_begin; i < face_end; ++i)
{
const LLVolumeFace& vol_face = volume->getVolumeFace(i);
@@ -5144,6 +5169,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
+ if (rebuild_face_octrees)
{
dst_face.destroyOctree();
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 77e7043f40..003ab38d64 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -68,7 +68,12 @@ 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);
+ 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;
};
@@ -385,7 +390,10 @@ public:
// 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_treat_as_rigged);
+ void updateRiggedVolume(
+ bool force_treat_as_rigged,
+ 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