summaryrefslogtreecommitdiff
path: root/indra/llprimitive
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2010-12-30 16:46:56 -0600
committerDave Parks <davep@lindenlab.com>2010-12-30 16:46:56 -0600
commitf41b53059ee76903177b21f2b0d8767b4216f010 (patch)
tree8003fab9b0672e31e3436eb39d1561636d2744aa /indra/llprimitive
parent13ec64e0e6a107d21108e817c5f9e33b6c929525 (diff)
SH-508 Fix for frame stalls when adjusting skin weights.
Diffstat (limited to 'indra/llprimitive')
-rwxr-xr-xindra/llprimitive/llmodel.cpp54
1 files changed, 45 insertions, 9 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 28f152f49c..1869e1dd47 100755
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -1878,21 +1878,57 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)
}
else
{ //no exact match found, get closest point
- iter = mSkinWeights.begin();
- weight_map::iterator best = iter;
+ const F32 epsilon = 2.f/65536;
+ weight_map::iterator iter_up = mSkinWeights.lower_bound(pos);
+ weight_map::iterator iter_down = ++iter_up;
+
+ weight_map::iterator best = iter_up;
F32 min_dist = (iter->first - pos).magVecSquared();
- while (++iter != mSkinWeights.end())
- {
- F32 dist = (iter->first - pos).magVecSquared();
- if (dist < min_dist)
+ bool done = false;
+ while (!done)
+ { //search up and down mSkinWeights from lower bound of pos until a
+ //match is found within epsilon. If no match is found within epsilon,
+ //return closest match
+ done = true;
+ if (iter_up != mSkinWeights.end() && ++iter_up != mSkinWeights.end())
{
- best = iter;
- min_dist = dist;
+ done = false;
+ F32 dist = (iter_up->first - pos).magVecSquared();
+
+ if (dist < epsilon)
+ {
+ return iter_up->second;
+ }
+
+ if (dist < min_dist)
+ {
+ best = iter_up;
+ min_dist = dist;
+ }
}
- }
+ if (iter_down != mSkinWeights.begin() && --iter_down != mSkinWeights.begin())
+ {
+ done = false;
+
+ F32 dist = (iter_down->first - pos).magVecSquared();
+
+ if (dist < epsilon)
+ {
+ return iter_down->second;
+ }
+
+ if (dist < min_dist)
+ {
+ best = iter_down;
+ min_dist = dist;
+ }
+
+ }
+ }
+
return best->second;
}
}