diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2018-06-07 22:18:15 +0100 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2018-06-07 22:18:15 +0100 |
commit | 430f9420cf0094635b0b0428a29ff7dfaf5718e8 (patch) | |
tree | 193a6f22541ce4dbe8199fcde5bd5d1f006a09b1 | |
parent | 2a2046fd074ffd8df8503e4a7197fd74e006f296 (diff) |
SL-915 - more on dynamic extent tracking, possible fix for 32-bit crash issues
-rw-r--r-- | indra/llcommon/llerror.cpp | 9 | ||||
-rw-r--r-- | indra/llmath/llrigginginfo.cpp | 78 | ||||
-rw-r--r-- | indra/llmath/llrigginginfo.h | 32 | ||||
-rw-r--r-- | indra/llmath/llvolume.cpp | 12 | ||||
-rw-r--r-- | indra/llmath/llvolume.h | 2 | ||||
-rw-r--r-- | indra/newview/llskinningutil.cpp | 54 | ||||
-rw-r--r-- | indra/newview/llskinningutil.h | 1 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 61 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 4 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 52 |
11 files changed, 245 insertions, 62 deletions
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index f31a054139..916555a71d 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -51,6 +51,10 @@ #include "llstl.h" #include "lltimer.h" +//#if LL_WINDOWS +//#pragma optimize("", off) +//#endif + namespace { #if LL_WINDOWS void debugger_print(const std::string& s) @@ -361,6 +365,7 @@ namespace } } + LL_INFOS("LogControlFile") << "logging reconfiguring from " << filename() << LL_ENDL; LLError::configure(configuration); LL_INFOS("LogControlFile") << "logging reconfigured from " << filename() << LL_ENDL; return true; @@ -1292,7 +1297,7 @@ namespace LLError #if LL_WINDOWS // VC80 was optimizing the error away. - #pragma optimize("", off) +// #pragma optimize("", off) #endif void crashAndLoop(const std::string& message) { @@ -1310,7 +1315,7 @@ namespace LLError exit(EXIT_FAILURE); } #if LL_WINDOWS - #pragma optimize("", on) +// #pragma optimize("", on) #endif std::string utcTime() diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp index 925179c2ba..73e1b096cb 100644 --- a/indra/llmath/llrigginginfo.cpp +++ b/indra/llmath/llrigginginfo.cpp @@ -27,6 +27,10 @@ #include "llmath.h" #include "llrigginginfo.h" +//#if LL_WINDOWS +//#pragma optimize("", off) +//#endif + //----------------------------------------------------------------------------- // LLJointRiggingInfo //----------------------------------------------------------------------------- @@ -80,17 +84,79 @@ void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) } } -void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src) +LLJointRiggingInfoTab::LLJointRiggingInfoTab(): + mRigInfoPtr(NULL), + mSize(0) +{ +} + +LLJointRiggingInfoTab::~LLJointRiggingInfoTab() +{ + clear(); +} + +// This doesn't preserve data if the size changes. In practice +// this doesn't matter because the size is always either +// LL_CHARACTER_MAX_ANIMATED_JOINTS or 0. +void LLJointRiggingInfoTab::resize(S32 size) +{ + if (size != mSize) + { + clear(); + if (size > 0) + { + mRigInfoPtr = new LLJointRiggingInfo[size]; + mSize = size; + } + } +} + +void LLJointRiggingInfoTab::clear() { + if (mRigInfoPtr) + { + delete[](mRigInfoPtr); + mRigInfoPtr = NULL; + mSize = 0; + } +} + +void showDetails(const LLJointRiggingInfoTab& src, const std::string& str) +{ + S32 count_rigged = 0; + S32 count_box = 0; + LLVector4a zero_vec; + zero_vec.clear(); + for (S32 i=0; i<src.size(); i++) + { + if (src[i].isRiggedTo()) + { + count_rigged++; + if ((!src[i].getRiggedExtents()[0].equals3(zero_vec)) || + (!src[i].getRiggedExtents()[1].equals3(zero_vec))) + { + count_box++; + } + } + } + LL_DEBUGS("RigSpammish") << "details: " << str << " has " << count_rigged << " rigged joints, of which " << count_box << " are non-empty" << LL_ENDL; +} + +void LLJointRiggingInfoTab::merge(const LLJointRiggingInfoTab& src) +{ + //showDetails(*this, "input this"); // Size should be either LL_CHARACTER_MAX_ANIMATED_JOINTS, or 0 if // no data. Not necessarily the same for both inputs. - if (src.size() > dst.size()) + if (src.size() > size()) { - dst.resize(src.size()); + resize(src.size()); } - S32 size = llmin(src.size(), dst.size()); - for (S32 i=0; i<size; i++) + S32 min_size = llmin(size(), src.size()); + for (S32 i=0; i<min_size; i++) { - dst[i].merge(src[i]); + (*this)[i].merge(src[i]); } + //showDetails(src, "input src"); + //showDetails(*this, "output this"); + } diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h index 7b36880a39..b09746a5b7 100644 --- a/indra/llmath/llrigginginfo.h +++ b/indra/llmath/llrigginginfo.h @@ -44,6 +44,17 @@ public: LLVector4a *getRiggedExtents(); const LLVector4a *getRiggedExtents() const; void merge(const LLJointRiggingInfo& other); + + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + private: LL_ALIGN_16(LLVector4a mRiggedExtents[2]); bool mIsRiggedTo; @@ -51,8 +62,25 @@ private: // For storing all the rigging info associated with a given avatar or // object, keyed by joint_num. -typedef std::vector<LLJointRiggingInfo> joint_rig_info_tab; +// Using direct memory management instead of std::vector<> to avoid alignment issues. +class LLJointRiggingInfoTab +{ +public: + LLJointRiggingInfoTab(); + ~LLJointRiggingInfoTab(); + void resize(S32 size); + void clear(); + S32 size() const { return mSize; } + void merge(const LLJointRiggingInfoTab& src); + LLJointRiggingInfo& operator[](S32 i) { return mRigInfoPtr[i]; } + const LLJointRiggingInfo& operator[](S32 i) const { return mRigInfoPtr[i]; }; +private: + // Not implemented + LLJointRiggingInfoTab& operator=(const LLJointRiggingInfoTab& src); + LLJointRiggingInfoTab(const LLJointRiggingInfoTab& src); -void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src); + LLJointRiggingInfo *mRigInfoPtr; + S32 mSize; +}; #endif diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 8f08394ce9..2654e204c2 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4644,7 +4644,6 @@ LLVolumeFace::LLVolumeFace() : mNumVertices(0), mNumAllocatedVertices(0), mNumIndices(0), - mJointRiggingInfoTabPtr(NULL), mPositions(NULL), mNormals(NULL), mTangents(NULL), @@ -4676,7 +4675,6 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src) mTangents(NULL), mTexCoords(NULL), mIndices(NULL), - mJointRiggingInfoTabPtr(NULL), mWeights(NULL), mWeightsScrubbed(FALSE), mOctree(NULL) @@ -4791,9 +4789,6 @@ void LLVolumeFace::freeData() ll_aligned_free_16(mWeights); mWeights = NULL; - free(mJointRiggingInfoTabPtr); - mJointRiggingInfoTabPtr = NULL; - delete mOctree; mOctree = NULL; } @@ -4955,7 +4950,7 @@ void LLVolumeFace::optimize(F32 angle_cutoff) // if (new_face.mNumVertices <= mNumVertices) { - llassert(new_face.mNumIndices == mNumIndices); + llassert(new_face.mNumIndices == mNumIndices); swapData(new_face); } @@ -6292,6 +6287,9 @@ void LLVolumeFace::resizeVertices(S32 num_verts) mNumVertices = num_verts; mNumAllocatedVertices = num_verts; + + // Force update + mJointRiggingInfoTab.clear(); } void LLVolumeFace::pushVertex(const LLVolumeFace::VertexData& cv) @@ -6413,6 +6411,8 @@ void LLVolumeFace::fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, } } +// AXON appendFace/appendFaces not used - referenced by corresponding functions in +// LLModel but these are not called anywhere. void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMatrix4& norm_mat_in) { U16 offset = mNumVertices; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index d518bcf3ef..f92b43e77d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -962,7 +962,7 @@ public: // Which joints are rigged to, and the bounding box of any rigged // vertices per joint. - joint_rig_info_tab *mJointRiggingInfoTabPtr; + LLJointRiggingInfoTab mJointRiggingInfoTab; LLOctreeNode<LLVolumeTriangle>* mOctree; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 14abe9d89a..6484775c40 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -34,6 +34,10 @@ #include "llvolume.h" #include "llrigginginfo.h" +//#if LL_WINDOWS +//#pragma optimize("", off) +//#endif + void LLSkinningUtil::initClass() { } @@ -211,15 +215,36 @@ void LLSkinningUtil::getPerVertexSkinMatrix( llassert(valid_weights); } +// AXON need to remember this has been done +void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar) +{ + for (U32 j = 0; j < skin->mJointNames.size(); ++j) + { + LLJoint *joint = NULL; + if (skin->mJointNums[j] == -1) + { + joint = avatar->getJoint(skin->mJointNames[j]); + if (joint) + { + skin->mJointNums[j] = joint->getJointNum(); + } + } + } +} + void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face) { + // AXON cast + initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar); S32 num_verts = vol_face.mNumVertices; if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0)) { - if (!vol_face.mJointRiggingInfoTabPtr) + if (vol_face.mJointRiggingInfoTab.size()==0) { - vol_face.mJointRiggingInfoTabPtr = new joint_rig_info_tab(LL_CHARACTER_MAX_ANIMATED_JOINTS); - joint_rig_info_tab& rig_info_tab = *vol_face.mJointRiggingInfoTabPtr; + std::set<S32> active_joints; + S32 active_verts = 0; + vol_face.mJointRiggingInfoTab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); + LLJointRiggingInfoTab &rig_info_tab = vol_face.mJointRiggingInfoTab; for (S32 i=0; i<vol_face.mNumVertices; i++) { LLVector4a& pos = vol_face.mPositions[i]; @@ -228,11 +253,13 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a { S32 joint_index = llfloor(w[k]); S32 joint_num = skin->mJointNums[joint_index]; - if (joint_num != -1) + if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) { rig_info_tab[joint_num].setIsRiggedTo(true); + active_joints.insert(joint_num); + active_verts++; - // AXON can precompute that matMuls. + // AXON can precompute these matMuls. LLMatrix4a bind_shape; bind_shape.loadu(skin->mBindShapeMatrix); LLMatrix4a inv_bind; @@ -246,8 +273,21 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a } } } - LL_DEBUGS("RigSpammish") << "updated rigging info for vf " << &vol_face - << " num_verts " << vol_face.mNumVertices << LL_ENDL; + LL_DEBUGS("RigSpammish") << "built rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices + << " active joints " << active_joints.size() + << " active verts " << active_verts + << LL_ENDL; } } + if (vol_face.mJointRiggingInfoTab.size()!=0) + { + LL_DEBUGS("RigSpammish") << "we have rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices << LL_ENDL; + } + else + { + LL_DEBUGS("RigSpammish") << "no rigging info for vf " << &vol_face + << " num_verts " << vol_face.mNumVertices << LL_ENDL; + } } diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 47e12f8adc..e730ef014b 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -42,6 +42,7 @@ namespace LLSkinningUtil void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); + void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar); void updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face); }; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index eac3f1bbe8..d6c8b76147 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -881,7 +881,7 @@ public: virtual void updateRiggingInfo() {} - joint_rig_info_tab mJointRiggingInfoTab; + LLJointRiggingInfoTab mJointRiggingInfoTab; private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 93e470e0fb..8c3a180570 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -671,7 +671,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mCachedInMuteList(false), mIsControlAvatar(false), mIsUIAvatar(false), - mEnableDefaultMotions(true) + mEnableDefaultMotions(true), + mRiggingInfoNeedsUpdate(true) { LL_DEBUGS("AvatarRender") << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << LL_ENDL; @@ -1279,8 +1280,12 @@ void LLVOAvatar::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax) } } +static LLTrace::BlockTimerStatHandle FTM_AVATAR_EXTENT_UPDATE("Avatar Update Extent"); + void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { + LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE); + S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity"); LLVector4a buffer(0.0); LLVector4a pos; @@ -1364,7 +1369,13 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) // Stretch bounding box by rigged mesh joint boxes if (box_detail>=3) { - updateRiggingInfo(); + // AXON try to cache unless something has changed about attached rigged meshes. + // Needs more logic based on volume states. + //if (mRiggingInfoNeedsUpdate) + { + updateRiggingInfo(); + mRiggingInfoNeedsUpdate = false; + } for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { LLJoint *joint = getJoint(joint_num); @@ -5854,8 +5865,6 @@ void LLVOAvatar::clearAttachmentOverrides() { LLScopedContextString str("clearAttachmentOverrides " + getFullname()); - mActiveOverrideMeshes.clear(); - for (S32 i=0; i<LL_CHARACTER_MAX_ANIMATED_JOINTS; i++) { LLJoint *pJoint = getJoint(i); @@ -5876,6 +5885,9 @@ void LLVOAvatar::clearAttachmentOverrides() } postPelvisSetRecalc(); } + + mActiveOverrideMeshes.clear(); + onActiveOverrideMeshesChanged(); } //----------------------------------------------------------------------------- @@ -6130,8 +6142,6 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false; if ( fullRig && !mesh_overrides_loaded ) { - mActiveOverrideMeshes.insert(mesh_id); - for ( int i=0; i<jointCnt; ++i ) { std::string lookingForJoint = pSkinData->mJointNames[i].c_str(); @@ -6174,6 +6184,8 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL } } + mActiveOverrideMeshes.insert(mesh_id); + onActiveOverrideMeshesChanged(); } } } @@ -6335,8 +6347,6 @@ void LLVOAvatar::removeAttachmentOverridesForObject(LLViewerObject *vo) //----------------------------------------------------------------------------- void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id) { - mActiveOverrideMeshes.erase(mesh_id); - LLJoint* pJointPelvis = getJoint("mPelvis"); const std::string av_string = avString(); for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) @@ -6357,6 +6367,9 @@ void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id) } postPelvisSetRecalc(); + + mActiveOverrideMeshes.erase(mesh_id); + onActiveOverrideMeshesChanged(); } //----------------------------------------------------------------------------- // getCharacterPosition() @@ -9444,20 +9457,7 @@ void LLVOAvatar::updateLODRiggedAttachments() rebuildRiggedAttachments(); } -S32 countRigInfoTab(joint_rig_info_tab& tab) -{ - S32 count=0; - for (S32 i=0; i<tab.size(); i++) - { - if (tab[i].isRiggedTo()) - { - count++; - } - } - return count; -} - -void showRigInfoTabExtents(LLVOAvatar *avatar, joint_rig_info_tab& tab, S32& count_rigged, S32& count_box) +void showRigInfoTabExtents(LLVOAvatar *avatar, LLJointRiggingInfoTab& tab, S32& count_rigged, S32& count_box) { count_rigged = count_box = 0; LLVector4a zero_vec; @@ -9494,7 +9494,7 @@ void LLVOAvatar::updateRiggingInfo() { LLViewerObject* attached_object = *attach_iter; attached_object->updateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, attached_object->mJointRiggingInfoTab); + mJointRiggingInfoTab.merge(attached_object->mJointRiggingInfoTab); //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; @@ -9504,7 +9504,7 @@ void LLVOAvatar::updateRiggingInfo() { LLViewerObject *childp = *it; childp->updateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + mJointRiggingInfoTab.merge(childp->mJointRiggingInfoTab); //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; } } @@ -9515,9 +9515,8 @@ void LLVOAvatar::updateRiggingInfo() LLVOVolume *volp = control_av->mRootVolp; if (volp && !volp->isAttachment()) { - volp->updateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, volp->mJointRiggingInfoTab); - LL_DEBUGS("RigSpammish") << getFullname() << " after cav update rig tab:" << LL_ENDL; + mJointRiggingInfoTab.merge(volp->mJointRiggingInfoTab); + LL_DEBUGS("RigSpammish") << getFullname() << " mRootVolp " << control_av->mRootVolp << " after cav update rig tab:" << LL_ENDL; S32 joint_count, box_count; showRigInfoTabExtents(this, mJointRiggingInfoTab, joint_count, box_count); LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; @@ -9529,7 +9528,7 @@ void LLVOAvatar::updateRiggingInfo() { LLViewerObject *childp = *it; childp->updateRiggingInfo(); - mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + mJointRiggingInfoTab.merge(childp->mJointRiggingInfoTab); LL_DEBUGS("RigSpammish") << getFullname() << " after cav child update rig tab:" << LL_ENDL; S32 joint_count, box_count; @@ -9547,6 +9546,12 @@ void LLVOAvatar::updateRiggingInfo() LL_DEBUGS("RigSpammish") << "uses " << joint_count << " joints " << " nonzero boxes: " << box_count << LL_ENDL; } +// virtual +void LLVOAvatar::onActiveOverrideMeshesChanged() +{ + mRiggingInfoNeedsUpdate = true; +} + U32 LLVOAvatar::getPartitionType() const { // Avatars merely exist as drawables in the bridge partition diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 59f88490d0..924b361f59 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -219,10 +219,10 @@ public: // virtual void updateRiggingInfo(); + bool mRiggingInfoNeedsUpdate; std::set<LLUUID> mActiveOverrideMeshes; - - + virtual void onActiveOverrideMeshesChanged(); /*virtual*/ const LLUUID& getID() const; /*virtual*/ void addDebugText(const std::string& text); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2f2a28daff..70c4efb5b8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3597,26 +3597,64 @@ void LLVOVolume::updateRiggingInfo() { const LLMeshSkinInfo* skin = getSkinInfo(); LLVOAvatar *avatar = getAvatar(); - if (skin && avatar && getLOD()>mLastRiggingInfoLOD) + LLVolume *volume = getVolume(); + if (skin && avatar && volume) { - LLVolume *volume = getVolume(); - if (volume) + LL_DEBUGS("RigSpammish") << "starting, vovol " << this << " lod " << getLOD() << " last " << mLastRiggingInfoLOD << LL_ENDL; + // AXON SPAM + for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) { + LLVolumeFace& vol_face = volume->getVolumeFace(f); + if (vol_face.mJointRiggingInfoTab.size()>0) + { + LL_DEBUGS("RigSpammish") << "vovol " << this << " lod " << getLOD() << " face " << f << " vf " << &vol_face << " has rig info" << LL_ENDL; + } + else + { + LL_DEBUGS("RigSpammish") << "vovol " << this << " lod " << getLOD() << " face " << f << " vf " << &vol_face << " needs update" << LL_ENDL; + } + } + // We maintain rigging info based on the highest LOD + // handled so far. Need to update if either the LOD is + // the same but some faces need to be updated, or if + // the LOD has increased. + bool any_face_needs_rebuild = false; + if (getLOD()==mLastRiggingInfoLOD) + { + // See if any volume face needs its rigging info built. + for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) + { + LLVolumeFace& vol_face = volume->getVolumeFace(f); + if (vol_face.mJointRiggingInfoTab.size()==0) + { + // AXON this is overkill since some faces don't contain any valid weights/rigged verts. + any_face_needs_rebuild = true; + break; + } + } + } + + //if (getLOD()>mLastRiggingInfoLOD || + // (getLOD()==mLastRiggingInfoLOD && any_face_needs_rebuild)) + if (getLOD()==3) + { + // Rigging info has changed mJointRiggingInfoTab.clear(); for (S32 f = 0; f < volume->getNumVolumeFaces(); ++f) { LLVolumeFace& vol_face = volume->getVolumeFace(f); LLSkinningUtil::updateRiggingInfo(skin, avatar, vol_face); - if (vol_face.mJointRiggingInfoTabPtr) + if (vol_face.mJointRiggingInfoTab.size()>0) { - mergeRigInfoTab(mJointRiggingInfoTab, *vol_face.mJointRiggingInfoTabPtr); + mJointRiggingInfoTab.merge(vol_face.mJointRiggingInfoTab); } } // Keep the highest LOD info available. - // AXON would this ever need to be forced to refresh? Set to -1 if so. mLastRiggingInfoLOD = getLOD(); LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " - << this << " lod " << mLastRiggingInfoLOD << LL_ENDL; + << this << " lod " << mLastRiggingInfoLOD + << " any faces rebuilt? " << any_face_needs_rebuild + << LL_ENDL; } } } |