summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2018-06-04 14:43:06 +0100
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2018-06-04 14:43:06 +0100
commit228525aa27b05cc1aa8be27de4ae59f5ec590ae3 (patch)
treedde50d01034b34b0c4f15a6ed2fd13efe30eb1e8
parente86839fac19753d0fa4006296c7f8909fe781013 (diff)
SL-915 - tracking joint is rigged state
-rw-r--r--indra/llcharacter/lljoint.cpp53
-rw-r--r--indra/llcharacter/lljoint.h22
-rw-r--r--indra/llmath/CMakeLists.txt2
-rw-r--r--indra/llmath/llrigginginfo.cpp96
-rw-r--r--indra/llmath/llrigginginfo.h55
-rw-r--r--indra/newview/llskinningutil.cpp25
-rw-r--r--indra/newview/llskinningutil.h4
-rw-r--r--indra/newview/llviewerobject.h5
-rw-r--r--indra/newview/llvoavatar.cpp91
-rw-r--r--indra/newview/llvoavatar.h6
-rw-r--r--indra/newview/llvovolume.cpp15
-rw-r--r--indra/newview/llvovolume.h3
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