diff options
| -rwxr-xr-x | indra/llmath/llvolume.cpp | 10 | ||||
| -rwxr-xr-x | indra/llprimitive/llmodel.cpp | 3 | ||||
| -rwxr-xr-x | indra/newview/llfloatermodelpreview.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/llskinningutil.cpp | 9 | 
4 files changed, 19 insertions, 8 deletions
| diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 725e50ee2b..e5b1cf536d 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2544,7 +2544,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)  						U16 influence = weights[idx++];  						influence |= ((U16) weights[idx++] << 8); -						F32 w = llclamp((F32) influence / 65535.f, 0.f, 0.99999f); +						F32 w = llclamp((F32) influence / 65535.f, 0.001f, 0.999f);  						wght.mV[cur_influence] = w;  						joints[cur_influence] = joint;  						cur_influence++; @@ -2561,11 +2561,13 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)                      F32 wsum = wght.mV[VX] + wght.mV[VY] + wght.mV[VZ] + wght.mV[VW];                      if (wsum <= 0.f)                      { -                        wght = LLVector4(0.99999f,0.f,0.f,0.f); +                        wght = LLVector4(0.999f,0.f,0.f,0.f);                      } -                    for (U32 k=0; k<4; k++) +                    for (U32 k=0; k<cur_influence; k++)                      { -                        joints_with_weights[k] = (F32) joints[k] + wght[k]; +                        F32 f_combined = (F32) joints[k] + wght[k]; +                        llassert(f_combined-(S32)f_combined>0); // If this fails, we have a floating point precision error. +                        joints_with_weights[k] = f_combined;                      }  					face.mWeights[cur_vertex].loadua(joints_with_weights.mV); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index adf392fa21..398f0997f3 100755 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1001,7 +1001,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO  LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)  { -	//1. If a vertex has been weighted then we'll find it via pos and return it's weight list +	//1. If a vertex has been weighted then we'll find it via pos and return its weight list  	weight_map::iterator iterPos = mSkinWeights.begin();  	weight_map::iterator iterEnd = mSkinWeights.end(); @@ -1224,7 +1224,6 @@ bool LLModel::loadModel(std::istream& is)  	}  	return false; -  }  bool LLModel::isMaterialListSubset( LLModel* ref ) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index ceb3566d95..cda704f47b 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -3317,14 +3317,17 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)  					LLVector3 pos(vf.mPositions[i].getF32ptr());  					const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos); +                    llassert(weight_list.size()>0 && weight_list.size() <= 4); // LLModel::loadModel() should guarantee this  					LLVector4 w(0,0,0,0);  					for (U32 i = 0; i < weight_list.size(); ++i)  					{ -						F32 wght = llmin(weight_list[i].mWeight, 0.999999f); +						F32 wght = llclamp(weight_list[i].mWeight, 0.001f, 0.999f);  						F32 joint = (F32) weight_list[i].mJointIdx;  						w.mV[i] = joint + wght; +                        llassert(w.mV[i]-(S32)w.mV[i]>0.0f); // because weights are non-zero, and range of wt values +                                                             //should not cause floating point precision issues.  					}  					*(weights_strider++) = w; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index fbe45c8ea6..732afdfa9a 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -291,12 +291,15 @@ void LLSkinningUtil::checkSkinWeights(LLVector4a* weights, U32 num_vertices, con          {              F32 *w = weights[j].getF32ptr(); +            F32 wsum = 0.0;              for (U32 k=0; k<4; ++k)              {                  S32 i = llfloor(w[k]);                  llassert(i>=0);                  llassert(i<max_joints); +                wsum += w[k]-i;              } +            llassert(wsum > 0.0f);          }      }  #endif @@ -310,7 +313,7 @@ void LLSkinningUtil::getPerVertexSkinMatrix(      LLMatrix4a& final_mat,      U32 max_joints)  { - +    bool valid_weights = true;      final_mat.clear();      S32 idx[4]; @@ -336,6 +339,7 @@ void LLSkinningUtil::getPerVertexSkinMatrix(      if (handle_bad_scale && scale <= 0.f)      {          wght = LLVector4(1.0f, 0.0f, 0.0f, 0.0f); +        valid_weights = false;      }      else      { @@ -353,5 +357,8 @@ void LLSkinningUtil::getPerVertexSkinMatrix(          final_mat.add(src);      } +    // SL-366 - with weight validation/cleanup code, it should no longer be +    // possible to hit the bad scale case. +    llassert(valid_weights);  } | 
