summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2014-11-15 14:29:39 -0500
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2014-11-15 14:29:39 -0500
commitb1884d40f5ba74d1d39be1abad7dc416905c6caf (patch)
treeb3b35a6f4aebe3292caf2700d86dcfbb2a4a2774
parent9c4397b6ee6d1a2a2c43d5d886b178753a4833d8 (diff)
MAINT-4537 WIP - more joint position management during outfit changes
-rwxr-xr-xindra/llcharacter/lljoint.cpp17
-rwxr-xr-xindra/llcharacter/lljoint.h2
-rwxr-xr-xindra/newview/llagentwearables.cpp21
-rwxr-xr-xindra/newview/llagentwearables.h2
-rwxr-xr-xindra/newview/llappearancemgr.cpp14
-rwxr-xr-xindra/newview/llvoavatar.cpp93
-rwxr-xr-xindra/newview/llvoavatar.h2
-rwxr-xr-xindra/newview/llvovolume.cpp59
8 files changed, 136 insertions, 74 deletions
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index cab3a7d619..6615a430ab 100755
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -89,6 +89,11 @@ bool LLPosOverrideMap::remove(const LLUUID& mesh_id)
return (remove_count > 0);
}
+void LLPosOverrideMap::clear()
+{
+ m_map.clear();
+}
+
//-----------------------------------------------------------------------------
// LLJoint()
// Class Constructor
@@ -368,6 +373,18 @@ bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const
}
//--------------------------------------------------------------------
+// clearAttachmentPosOverrides()
+//--------------------------------------------------------------------
+void LLJoint::clearAttachmentPosOverrides()
+{
+ if (m_attachmentOverrides.count())
+ {
+ m_attachmentOverrides.clear();
+ setPosition(m_posBeforeOverrides);
+ }
+}
+
+//--------------------------------------------------------------------
// updatePos()
//--------------------------------------------------------------------
void LLJoint::updatePos(const std::string& av_info)
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index 56da8e83b2..2abe1d6db1 100755
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -55,6 +55,7 @@ public:
U32 count() const;
void add(const LLUUID& mesh_id, const LLVector3& pos);
bool remove(const LLUUID& mesh_id);
+ void clear();
private:
typedef std::map<LLUUID,LLVector3> map_type;
map_type m_map;
@@ -202,6 +203,7 @@ public:
void addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh_id, const std::string& av_info );
void removeAttachmentPosOverride( const LLUUID& mesh_id, const std::string& av_info );
bool hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const;
+ void clearAttachmentPosOverrides();
//Accessor for the joint id
LLUUID getId( void ) { return mId; }
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 964c5110d1..585f14df3d 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1257,6 +1257,7 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty
// removed, and what additional inventory items need to be added.
void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
llvo_vec_t& objects_to_remove,
+ llvo_vec_t& objects_to_retain,
LLInventoryModel::item_array_t& items_to_add)
{
// Possible cases:
@@ -1310,6 +1311,7 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array
{
// LL_INFOS() << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL;
current_item_ids.insert(object_item_id);
+ objects_to_retain.push_back(objectp);
}
}
}
@@ -1335,23 +1337,6 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array
// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL;
}
-// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to
-// get attachments into desired state with minimal number of adds/removes.
-void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
-{
- llvo_vec_t objects_to_remove;
- LLInventoryModel::item_array_t items_to_add;
- findAttachmentsAddRemoveInfo(obj_item_array,
- objects_to_remove,
- items_to_add);
-
- // Remove everything in objects_to_remove
- userRemoveMultipleAttachments(objects_to_remove);
-
- // Add everything in items_to_add
- userAttachMultipleAttachments(items_to_add);
-}
-
void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
{
if (!isAgentAvatarValid()) return;
@@ -1369,7 +1354,7 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
++it)
{
LLViewerObject *objectp = *it;
- gAgentAvatarp->resetJointPositionsOnDetach(objectp);
+ //gAgentAvatarp->resetJointPositionsOnDetach(objectp);
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
}
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 10e3dbf8c6..1004482020 100755
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -180,8 +180,8 @@ public:
static void findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array,
llvo_vec_t& objects_to_remove,
+ llvo_vec_t& objects_to_retain,
LLInventoryModel::item_array_t& items_to_add);
- static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 69efb20f79..943190e7b1 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -809,22 +809,34 @@ void LLWearableHoldingPattern::onAllComplete()
LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL;
LLAgentWearables::llvo_vec_t objects_to_remove;
+ LLAgentWearables::llvo_vec_t objects_to_retain;
LLInventoryModel::item_array_t items_to_add;
if (isAgentAvatarValid())
{
LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems,
objects_to_remove,
+ objects_to_retain,
items_to_add);
LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size()
<< " attachments" << LL_ENDL;
+ gAgentAvatarp->clearAttachmentPosOverrides();
LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
}
// Update wearables.
LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with " << mResolved << " wearable items " << LL_ENDL;
LLAppearanceMgr::instance().updateAgentWearables(this);
-
+
+ // Restore attachment pos overrides for the attachments that aren't going away.
+ for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin();
+ it != objects_to_retain.end();
+ ++it)
+ {
+ LLViewerObject *objectp = *it;
+ gAgentAvatarp->addAttachmentPosOverridesForObject(objectp);
+ }
+
// Update attachments to match those requested.
if (isAgentAvatarValid())
{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 646ca25a0e..835c4e6176 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5061,6 +5061,99 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id)
return false;
}
+void LLVOAvatar::clearAttachmentPosOverrides()
+{
+ //Subsequent joints are relative to pelvis
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+
+ for (; iter != end; ++iter)
+ {
+ LLJoint* pJoint = (*iter);
+ pJoint->clearAttachmentPosOverrides();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// addAttachmentPosOverridesForObject
+//-----------------------------------------------------------------------------
+void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)
+{
+ LLVOAvatar *av = vo->getAvatarAncestor();
+ if (!av || (av != this))
+ {
+ LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
+ }
+
+ // Process all children
+ LLViewerObject::const_child_list_t& children = vo->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
+ it != children.end(); ++it)
+ {
+ LLViewerObject *childp = *it;
+ addAttachmentPosOverridesForObject(childp);
+ }
+
+ LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo);
+ bool pelvisGotSet = false;
+
+ if (!vobj)
+ {
+ return;
+ }
+ if (vobj->isMesh() &&
+ ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
+ {
+ return;
+ }
+ LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
+
+ if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData )
+ {
+ const int bindCnt = pSkinData->mAlternateBindMatrix.size();
+ if ( bindCnt > 0 )
+ {
+ const int jointCnt = pSkinData->mJointNames.size();
+ const F32 pelvisZOffset = pSkinData->mPelvisOffset;
+ const LLUUID& mesh_id = pSkinData->mMeshID;
+ bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
+ if ( fullRig )
+ {
+ for ( int i=0; i<jointCnt; ++i )
+ {
+ std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
+ LLJoint* pJoint = getJoint( lookingForJoint );
+ if ( pJoint && pJoint->getId() != currentId )
+ {
+ pJoint->setId( currentId );
+ const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
+ //Set the joint position
+ pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() );
+
+ //If joint is a pelvis then handle old/new pelvis to foot values
+ if ( lookingForJoint == "mPelvis" )
+ {
+ pelvisGotSet = true;
+ }
+ }
+ }
+ if (pelvisZOffset != 0.0F)
+ {
+ addPelvisFixup( pelvisZOffset, mesh_id );
+ pelvisGotSet = true;
+ }
+ }
+ }
+ }
+
+ //Rebuild body data if we altered joints/pelvis
+ if ( pelvisGotSet )
+ {
+ postPelvisSetRecalc();
+ }
+}
+
//-----------------------------------------------------------------------------
// resetJointPositionsOnDetach
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index ce1f0dd152..9a2aaf8aa3 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -199,8 +199,10 @@ public:
virtual LLJoint* getJoint(const std::string &name);
+ void addAttachmentPosOverridesForObject(LLViewerObject *vo);
void resetJointPositionsOnDetach(const LLUUID& mesh_id);
void resetJointPositionsOnDetach(LLViewerObject *vo);
+ void clearAttachmentPosOverrides();
/*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 aebd9f470d..5707d373bf 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4517,7 +4517,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//Determine if we've received skininfo that contains an
//alternate bind matrix - if it does then apply the translational component
//to the joints of the avatar.
+#if 0
bool pelvisGotSet = false;
+#endif
{
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_FACE_LIST);
@@ -4602,55 +4604,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
//get drawpool of avatar with rigged face
LLDrawPoolAvatar* pool = get_avatar_drawpool(vobj);
+ // FIXME should this be inside the face loop?
+ // doesn't seem to depend on any per-face state.
if ( pAvatarVO )
{
- LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
- const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
- if ( pSkinData )
- {
- const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
- {
- const int jointCnt = pSkinData->mJointNames.size();
- const F32 pelvisZOffset = pSkinData->mPelvisOffset;
- const LLUUID& mesh_id = pSkinData->mMeshID;
- bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
- if ( fullRig )
- {
- for ( int i=0; i<jointCnt; ++i )
- {
- std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
- LLJoint* pJoint = pAvatarVO->getJoint( lookingForJoint );
- if ( pJoint && pJoint->getId() != currentId )
- {
- pJoint->setId( currentId );
- const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
-
- //Set the joint position
- pJoint->addAttachmentPosOverride( jointPos, mesh_id, pAvatarVO->avString() );
-
- //If joint is a pelvis then handle old/new pelvis to foot values
- if ( lookingForJoint == "mPelvis" )
- {
- pelvisGotSet = true;
- }
- }
- }
- if (pelvisZOffset != 0.0F)
- {
- pAvatarVO->addPelvisFixup( pelvisZOffset, mesh_id );
- pelvisGotSet = true;
- }
- }
- }
- }
+ pAvatarVO->addAttachmentPosOverridesForObject(vobj);
}
-
- //Rebuild body data if we altered joints/pelvis
- if ( pelvisGotSet && pAvatarVO )
- {
- pAvatarVO->postPelvisSetRecalc();
- }
if (pool)
{
@@ -5008,14 +4967,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
-
-
-
-
-
-
-
-
}
group->mBufferUsage = useage;