diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2023-01-03 14:35:27 +0200 | 
|---|---|---|
| committer | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2023-01-03 14:36:11 +0200 | 
| commit | 9ef48676d45dcb90f282cc304135a9f023f4630b (patch) | |
| tree | d992f703f7c94acde9fc9ae71c246504eaeb1fcc /indra | |
| parent | 796d97d1903fb27628a47db447f3463219b649bd (diff) | |
SL-18874 Rigged mesh upload crash when using Bounding Box physics
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llprimitive/llmodel.cpp | 114 | 
1 files changed, 65 insertions, 49 deletions
| diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 805af55299..220e0fbe84 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -832,55 +832,69 @@ LLSD LLModel::writeModel(  				if (skinning)  				{ -					//write out skin weights - -					//each influence list entry is up to 4 24-bit values -					// first 8 bits is bone index -					// last 16 bits is bone influence weight -					// a bone index of 0xFF signifies no more influences for this vertex - -					std::stringstream ostr; - -					for (U32 j = 0; j < face.mNumVertices; ++j) -					{ -						LLVector3 pos(face.mPositions[j].getF32ptr()); - -						weight_list& weights = model[idx]->getJointInfluences(pos); - -						S32 count = 0; -						for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) -						{ -							// Note joint index cannot exceed 255. -							if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) -							{ -								U8 idx = (U8) iter->mJointIdx; -								ostr.write((const char*) &idx, 1); - -								U16 influence = (U16) (iter->mWeight*65535); -								ostr.write((const char*) &influence, 2); - -								++count; -							}		 -						} -						U8 end_list = 0xFF; -						if (count < 4) -						{ -							ostr.write((const char*) &end_list, 1); -						} -					} - -					//copy ostr to binary buffer -					std::string data = ostr.str(); -					const U8* buff = (U8*) data.data(); -					U32 bytes = data.size(); - -					LLSD::Binary w(bytes); -					for (U32 j = 0; j < bytes; ++j) -					{ -						w[j] = buff[j]; -					} - -					mdl[model_names[idx]][i]["Weights"] = w; +                    if (!model[idx]->mSkinWeights.empty()) +                    { +                        //write out skin weights + +                        //each influence list entry is up to 4 24-bit values +                        // first 8 bits is bone index +                        // last 16 bits is bone influence weight +                        // a bone index of 0xFF signifies no more influences for this vertex + +                        std::stringstream ostr; +                        for (U32 j = 0; j < face.mNumVertices; ++j) +                        { +                            LLVector3 pos(face.mPositions[j].getF32ptr()); + +                            weight_list& weights = model[idx]->getJointInfluences(pos); + +                            S32 count = 0; +                            for (weight_list::iterator iter = weights.begin(); iter != weights.end(); ++iter) +                            { +                                // Note joint index cannot exceed 255. +                                if (iter->mJointIdx < 255 && iter->mJointIdx >= 0) +                                { +                                    U8 idx = (U8)iter->mJointIdx; +                                    ostr.write((const char*)&idx, 1); + +                                    U16 influence = (U16)(iter->mWeight * 65535); +                                    ostr.write((const char*)&influence, 2); + +                                    ++count; +                                } +                            } +                            U8 end_list = 0xFF; +                            if (count < 4) +                            { +                                ostr.write((const char*)&end_list, 1); +                            } +                        } + +                        //copy ostr to binary buffer +                        std::string data = ostr.str(); +                        const U8* buff = (U8*)data.data(); +                        U32 bytes = data.size(); + +                        LLSD::Binary w(bytes); +                        for (U32 j = 0; j < bytes; ++j) +                        { +                            w[j] = buff[j]; +                        } + +                        mdl[model_names[idx]][i]["Weights"] = w; +                    } +                    else +                    { +                        if (idx == LLModel::LOD_PHYSICS) +                        { +                            // Ex: using "bounding box" +                            LL_DEBUGS("MESHSKININFO") << "Using physics model without skin weights" << LL_ENDL; +                        } +                        else +                        { +                            LL_WARNS("MESHSKININFO") << "Attempting to use skinning without having skin weights" << LL_ENDL; +                        } +                    }  				}  			}  		} @@ -982,6 +996,8 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos)  	//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(); + +    llassert(!mSkinWeights.empty());  	for ( ; iterPos!=iterEnd; ++iterPos )  	{ | 
