diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2018-06-04 14:43:06 +0100 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2018-06-04 14:43:06 +0100 |
commit | 228525aa27b05cc1aa8be27de4ae59f5ec590ae3 (patch) | |
tree | dde50d01034b34b0c4f15a6ed2fd13efe30eb1e8 | |
parent | e86839fac19753d0fa4006296c7f8909fe781013 (diff) |
SL-915 - tracking joint is rigged state
-rw-r--r-- | indra/llcharacter/lljoint.cpp | 53 | ||||
-rw-r--r-- | indra/llcharacter/lljoint.h | 22 | ||||
-rw-r--r-- | indra/llmath/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/llmath/llrigginginfo.cpp | 96 | ||||
-rw-r--r-- | indra/llmath/llrigginginfo.h | 55 | ||||
-rw-r--r-- | indra/newview/llskinningutil.cpp | 25 | ||||
-rw-r--r-- | indra/newview/llskinningutil.h | 4 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 5 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 91 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 6 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 15 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 3 |
12 files changed, 295 insertions, 82 deletions
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 68355cbbdc..07fcd99701 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -97,46 +97,6 @@ void LLVector3OverrideMap::clear() } //----------------------------------------------------------------------------- -// LLJointRiggingInfo -//----------------------------------------------------------------------------- -LLJointRiggingInfo::LLJointRiggingInfo() -{ - mRiggedExtents[0].clear(); - mRiggedExtents[1].clear(); - mIsRiggedTo = false; -} - -bool LLJointRiggingInfo::isRiggedTo() const -{ - return mIsRiggedTo; -} - -void LLJointRiggingInfo::setIsRiggedTo(bool val) -{ - mIsRiggedTo = val; -} - -LLVector4a *LLJointRiggingInfo::getRiggedExtents() -{ - return mRiggedExtents; -} - -const LLVector4a *LLJointRiggingInfo::getRiggedExtents() const -{ - return mRiggedExtents; -} - -// Combine two rigging info states. -// - isRiggedTo if either of the source infos are rigged to -// - box is union of the two sources -void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) -{ - mIsRiggedTo = mIsRiggedTo || other.mIsRiggedTo; - update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[0]); - update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[1]); -} - -//----------------------------------------------------------------------------- // LLJoint() // Class Constructor //----------------------------------------------------------------------------- @@ -638,19 +598,6 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const } //-------------------------------------------------------------------- -// getRiggingInfo() -//-------------------------------------------------------------------- -LLJointRiggingInfo& LLJoint::getRiggingInfo() -{ - return mRiggingInfo; -} - -const LLJointRiggingInfo& LLJoint::getRiggingInfo() const -{ - return mRiggingInfo; -} - -//-------------------------------------------------------------------- // updatePos() //-------------------------------------------------------------------- void LLJoint::updatePos(const std::string& av_info) diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index ff1e967188..8112d246f2 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -70,23 +70,6 @@ private: map_type m_map; }; -// Stores information related to associated rigged mesh vertices -// Extents are in joint space -// isRiggedTo is based on the state of all currently associated rigged meshes -class LLJointRiggingInfo -{ -public: - LLJointRiggingInfo(); - bool isRiggedTo() const; - void setIsRiggedTo(bool val); - LLVector4a *getRiggedExtents(); - const LLVector4a *getRiggedExtents() const; - void merge(const LLJointRiggingInfo& other); -private: - LL_ALIGN_16(LLVector4a mRiggedExtents[2]); - bool mIsRiggedTo; -}; - inline bool operator==(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b) { return a.getMap() == b.getMap(); @@ -175,11 +158,6 @@ public: LLVector3OverrideMap m_attachmentScaleOverrides; LLVector3 m_scaleBeforeOverrides; - // Rigging Info - LLJointRiggingInfo mRiggingInfo; - LLJointRiggingInfo& getRiggingInfo(); - const LLJointRiggingInfo& getRiggingInfo() const; - void updatePos(const std::string& av_info); void updateScale(const std::string& av_info); diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index dab566da56..379c3ee9ea 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -25,6 +25,7 @@ set(llmath_SOURCE_FILES lloctree.cpp llperlin.cpp llquaternion.cpp + llrigginginfo.cpp llrect.cpp llsphere.cpp llvector4a.cpp @@ -71,6 +72,7 @@ set(llmath_HEADER_FILES llquaternion2.h llquaternion2.inl llrect.h + llrigginginfo.h llsimdmath.h llsimdtypes.h llsimdtypes.inl diff --git a/indra/llmath/llrigginginfo.cpp b/indra/llmath/llrigginginfo.cpp new file mode 100644 index 0000000000..925179c2ba --- /dev/null +++ b/indra/llmath/llrigginginfo.cpp @@ -0,0 +1,96 @@ +/** +* @file llrigginginfo.cpp +* @brief Functions for tracking rigged box extents +* +* $LicenseInfo:firstyear=2018&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llmath.h" +#include "llrigginginfo.h" + +//----------------------------------------------------------------------------- +// LLJointRiggingInfo +//----------------------------------------------------------------------------- +LLJointRiggingInfo::LLJointRiggingInfo() +{ + mRiggedExtents[0].clear(); + mRiggedExtents[1].clear(); + mIsRiggedTo = false; +} + +bool LLJointRiggingInfo::isRiggedTo() const +{ + return mIsRiggedTo; +} + +void LLJointRiggingInfo::setIsRiggedTo(bool val) +{ + mIsRiggedTo = val; +} + +LLVector4a *LLJointRiggingInfo::getRiggedExtents() +{ + return mRiggedExtents; +} + +const LLVector4a *LLJointRiggingInfo::getRiggedExtents() const +{ + return mRiggedExtents; +} + +// Combine two rigging info states. +// - isRiggedTo if either of the source infos are rigged to +// - box is union of the two sources +void LLJointRiggingInfo::merge(const LLJointRiggingInfo& other) +{ + if (other.mIsRiggedTo) + { + if (mIsRiggedTo) + { + // Combine existing boxes + update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[0]); + update_min_max(mRiggedExtents[0], mRiggedExtents[1], other.mRiggedExtents[1]); + } + else + { + // Initialize box + mIsRiggedTo = true; + mRiggedExtents[0] = other.mRiggedExtents[0]; + mRiggedExtents[1] = other.mRiggedExtents[1]; + } + } +} + +void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src) +{ + // 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()) + { + dst.resize(src.size()); + } + S32 size = llmin(src.size(), dst.size()); + for (S32 i=0; i<size; i++) + { + dst[i].merge(src[i]); + } +} diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h new file mode 100644 index 0000000000..18da905abb --- /dev/null +++ b/indra/llmath/llrigginginfo.h @@ -0,0 +1,55 @@ +/** +* @file llrigginginfo.h +* @brief Functions for tracking rigged box extents +* +* $LicenseInfo:firstyear=2018&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2018, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +// Stores information related to associated rigged mesh vertices +// This lives in llmath because llvolume lives in llmath. + +#ifndef LL_LLRIGGINGINFO_H +#define LL_LLRIGGINGINFO_H + +// Extents are in joint space +// isRiggedTo is based on the state of all currently associated rigged meshes +class LLJointRiggingInfo +{ +public: + LLJointRiggingInfo(); + bool isRiggedTo() const; + void setIsRiggedTo(bool val); + LLVector4a *getRiggedExtents(); + const LLVector4a *getRiggedExtents() const; + void merge(const LLJointRiggingInfo& other); +private: + LL_ALIGN_16(LLVector4a mRiggedExtents[2]); + bool mIsRiggedTo; +}; + +// 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; + +void mergeRigInfoTab(joint_rig_info_tab& dst, const joint_rig_info_tab& src); + +#endif diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index dba690242a..7adb2fa8d2 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -216,3 +216,28 @@ void LLSkinningUtil::getPerVertexSkinMatrix( llassert(valid_weights); } +//static +void LLSkinningUtil::initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab) +{ + S32 rigged_count = 0; + rig_info_tab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); + 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(); + } + } + S32 joint_num = skin->mJointNums[j]; + if (joint_num != -1) + { + rig_info_tab[joint_num].setIsRiggedTo(true); + rigged_count++; + } + } + //LL_INFOS() << "rigged_count " << rigged_count << LL_ENDL; +} diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h index 135b25d4d2..3eba3dc93a 100644 --- a/indra/newview/llskinningutil.h +++ b/indra/newview/llskinningutil.h @@ -31,6 +31,9 @@ class LLVOAvatar; class LLMeshSkinInfo; class LLMatrix4a; +#include "llrigginginfo.h" + +// This should probably just be a namespace class LLSkinningUtil { public: @@ -42,6 +45,7 @@ public: static void checkSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); static void scrubSkinWeights(LLVector4a* weights, U32 num_vertices, const LLMeshSkinInfo* skin); static void getPerVertexSkinMatrix(F32* weights, LLMatrix4a* mat, bool handle_bad_scale, LLMatrix4a& final_mat, U32 max_joints); + static void initIsRiggedTo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, joint_rig_info_tab& rig_info_tab); }; #endif diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 9552d4e99e..b9840f629b 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -42,6 +42,7 @@ #include "v3math.h" #include "llvertexbuffer.h" #include "llbbox.h" +#include "llrigginginfo.h" class LLAgent; // TODO: Get rid of this. class LLAudioSource; @@ -877,6 +878,10 @@ public: BOOL getLastUpdateCached() const; void setLastUpdateCached(BOOL last_update_cached); + virtual void updateRiggingInfo() {} + + joint_rig_info_tab mJointRiggingInfoTab; + private: LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory. EObjectUpdateType mLastUpdateType; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 277f8e4533..50a012ad82 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1355,17 +1355,23 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) } // Stretch bounding box by rigged mesh joint boxes + updateRiggingInfo(); for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { LLJoint *joint = getJoint(joint_num); - - // FIXME TEMP HACK FOR TESTING - if (joint) + LLJointRiggingInfo *rig_info = NULL; + if (joint_num < mJointRiggingInfoTab.size()) { - joint->getRiggingInfo().setIsRiggedTo(true); + rig_info = &mJointRiggingInfoTab[joint_num]; } - if (joint && joint->getRiggingInfo().isRiggedTo()) + // FIXME TEMP HACK FOR TESTING + //if (joint) + //{ + // rig_info.setIsRiggedTo(true); + //} + + if (joint && rig_info && rig_info->isRiggedTo()) { LLViewerJointAttachment *as_joint_attach = dynamic_cast<LLViewerJointAttachment*>(joint); if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) @@ -1376,7 +1382,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) LLMatrix4a mat; LLVector4a new_extents[2]; mat.loadu(joint->getWorldMatrix()); - matMulBoundBox(mat, joint->getRiggingInfo().getRiggedExtents(), new_extents); + matMulBoundBox(mat, rig_info->getRiggedExtents(), new_extents); update_min_max(newMin, newMax, new_extents[0]); update_min_max(newMin, newMax, new_extents[1]); //if (isSelf()) @@ -5777,6 +5783,7 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) return false; } +// AXON update to use LLRiggingInfo bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name) { for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -5798,6 +5805,7 @@ bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name) return false; } +// AXON update to use LLRiggingInfo bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo) { // Process all children @@ -9420,11 +9428,80 @@ BOOL LLVOAvatar::updateLOD() return res; } -void LLVOAvatar::updateLODRiggedAttachments( void ) +void LLVOAvatar::updateLODRiggedAttachments() { updateLOD(); 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; +} + +// virtual +void LLVOAvatar::updateRiggingInfo() +{ + mJointRiggingInfoTab.clear(); + //LL_INFOS() << "starting update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + for ( attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter ) + { + LLViewerJointAttachment* attachment = iter->second; + LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_end = attachment->mAttachedObjects.end(); + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attach_iter = attachment->mAttachedObjects.begin(); + attach_iter != attach_end; ++attach_iter) + { + LLViewerObject* attached_object = *attach_iter; + attached_object->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, attached_object->mJointRiggingInfoTab); + //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + + + LLViewerObject::const_child_list_t& children = attached_object->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) + { + LLViewerObject *childp = *it; + childp->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + //LL_INFOS() << "after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + } + } + } + LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this); + if (control_av) + { + LLVOVolume *volp = control_av->mRootVolp; + if (volp && !volp->isAttachment()) + { + volp->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, volp->mJointRiggingInfoTab); + //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + + LLViewerObject::const_child_list_t& children = volp->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) + { + LLViewerObject *childp = *it; + childp->updateRiggingInfo(); + mergeRigInfoTab(mJointRiggingInfoTab, childp->mJointRiggingInfoTab); + //LL_INFOS() << "cav after merge rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; + } + } + } + + //LL_INFOS() << "done update rig count is " << countRigInfoTab(mJointRiggingInfoTab) << LL_ENDL; +} + 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 cccf857eba..59f88490d0 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -49,6 +49,7 @@ #include "lldriverparam.h" #include "llviewertexlayer.h" #include "material_codes.h" // LL_MCODE_END +#include "llrigginginfo.h" #include "llviewerstats.h" #include "llvovolume.h" #include "llavatarrendernotifier.h" @@ -216,7 +217,12 @@ public: void getAttachmentOverrideNames(std::set<std::string>& pos_names, std::set<std::string>& scale_names) const; + // virtual + void updateRiggingInfo(); + std::set<LLUUID> mActiveOverrideMeshes; + + /*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 b60ff6d280..321ea22ff9 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3565,6 +3565,21 @@ void LLVOVolume::afterReparent() } //---------------------------------------------------------------------------- +void LLVOVolume::updateRiggingInfo() +{ + if (isRiggedMesh()) + { + const LLMeshSkinInfo* skin = getSkinInfo(); + LLVOAvatar *avatar = getAvatar(); + if (skin && avatar) + { + LLSkinningUtil::initIsRiggedTo(skin, avatar, mJointRiggingInfoTab); + } + // AXON add bbox processing from volume faces. + } +} + +//---------------------------------------------------------------------------- void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point) { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index ebf92acc4f..d77c2f231b 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -282,6 +282,9 @@ public: virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent); virtual void afterReparent(); + //virtual + void updateRiggingInfo(); + // Functions that deal with media, or media navigation // Update this object's media data with the given media data array |