diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2014-11-15 14:29:39 -0500 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2014-11-15 14:29:39 -0500 |
commit | b1884d40f5ba74d1d39be1abad7dc416905c6caf (patch) | |
tree | b3b35a6f4aebe3292caf2700d86dcfbb2a4a2774 | |
parent | 9c4397b6ee6d1a2a2c43d5d886b178753a4833d8 (diff) |
MAINT-4537 WIP - more joint position management during outfit changes
-rwxr-xr-x | indra/llcharacter/lljoint.cpp | 17 | ||||
-rwxr-xr-x | indra/llcharacter/lljoint.h | 2 | ||||
-rwxr-xr-x | indra/newview/llagentwearables.cpp | 21 | ||||
-rwxr-xr-x | indra/newview/llagentwearables.h | 2 | ||||
-rwxr-xr-x | indra/newview/llappearancemgr.cpp | 14 | ||||
-rwxr-xr-x | indra/newview/llvoavatar.cpp | 93 | ||||
-rwxr-xr-x | indra/newview/llvoavatar.h | 2 | ||||
-rwxr-xr-x | indra/newview/llvovolume.cpp | 59 |
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; |