diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index c78c38c3a7e103d62b4b3e2d90366ef921c01f26..f6e95fdc8d4b9c5c70897c915665b41d50c1448e 100755 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -52,7 +52,6 @@ void LLJoint::init() mOldXform.setScale(LLVector3(1.0f, 1.0f, 1.0f)); mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY; mUpdateXform = TRUE; - mResetAfterRestoreOldXform = false; } LLJoint::LLJoint() : @@ -245,7 +244,7 @@ void LLJoint::setPosition( const LLVector3& pos ) //-------------------------------------------------------------------- -// setPosition() +// setDefaultFromCurrentXform() //-------------------------------------------------------------------- void LLJoint::setDefaultFromCurrentXform( void ) { @@ -253,14 +252,62 @@ void LLJoint::setDefaultFromCurrentXform( void ) } //-------------------------------------------------------------------- -// storeCurrentXform() +// addAttachmentPosOverride() //-------------------------------------------------------------------- -void LLJoint::storeCurrentXform( const LLVector3& pos ) -{ - mOldXform = mXform; - mResetAfterRestoreOldXform = true; - setPosition( pos ); - touch(ALL_DIRTY); +void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const std::string& attachment_name ) +{ + if (attachment_name.empty()) + { + return; + } + if (m_attachmentOverrides.empty()) + { + LL_WARNS() << "saving m_posBeforeOverrides " << getPosition() << LL_ENDL; + m_posBeforeOverrides = getPosition(); + } + AttachmentOverrideRecord rec; + rec.name = attachment_name; + rec.pos = pos; + m_attachmentOverrides[attachment_name] = rec; + LL_WARNS() << "addAttachmentPosOverride for " << attachment_name << " pos " << pos << LL_ENDL; + updatePos(); +} + +//-------------------------------------------------------------------- +// removeAttachmentPosOverride() +//-------------------------------------------------------------------- +void LLJoint::removeAttachmentPosOverride( const std::string& attachment_name ) +{ + if (attachment_name.empty()) + { + return; + } + attachment_map_t::iterator it = m_attachmentOverrides.find(attachment_name); + if (it != m_attachmentOverrides.end()) + { + LL_WARNS() << "removeAttachmentPosOverride for " << attachment_name << LL_ENDL; + m_attachmentOverrides.erase(it); + } + updatePos(); +} + +void LLJoint::updatePos() +{ + LLVector3 pos; + attachment_map_t::iterator it = std::max_element(m_attachmentOverrides.begin(), + m_attachmentOverrides.end()); + if (it != m_attachmentOverrides.end()) + { + AttachmentOverrideRecord& rec = it->second; + LL_WARNS() << "updatePos, winner is attachment " << rec.name << " pos " << rec.pos << LL_ENDL; + pos = rec.pos; + } + else + { + LL_WARNS() << "updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL; + pos = m_posBeforeOverrides; + } + setPosition(pos); } //-------------------------------------------------------------------- @@ -276,7 +323,6 @@ void LLJoint::storeScaleForReset( const LLVector3& scale ) void LLJoint::restoreOldXform( void ) { mXform = mOldXform; - mResetAfterRestoreOldXform = false; mDirtyFlags = ALL_DIRTY; } //-------------------------------------------------------------------- @@ -325,7 +371,7 @@ void LLJoint::setWorldPosition( const LLVector3& pos ) //-------------------------------------------------------------------- -// mXform.getRotation() +// getRotation() //-------------------------------------------------------------------- const LLQuaternion& LLJoint::getRotation() { @@ -548,20 +594,6 @@ void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot) break; } } - - // 2003.03.26 - This code was just using up cpu cycles. AB - -// LLVector3 old_axis = main_axis * old_rot; -// LLVector3 new_axis = main_axis * new_rot; - -// for (S32 i = 0; i < mConstraintSilhouette.size() - 1; i++) -// { -// LLVector3 vert1 = mConstraintSilhouette[i]; -// LLVector3 vert2 = mConstraintSilhouette[i + 1]; - - // figure out how to clamp rotation to line on 3-sphere - -// } } // End diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index b65d6979d4ab72f8d5abafe45d80c0690ee8faf1..f6f1cd2fe46f73de4c6b67d587f06608bcc2372d 100755 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -88,8 +88,6 @@ class LLJoint U32 mDirtyFlags; BOOL mUpdateXform; - BOOL mResetAfterRestoreOldXform; - // describes the skin binding pose LLVector3 mSkinOffset; @@ -103,6 +101,25 @@ class LLJoint static S32 sNumTouches; static S32 sNumUpdates; + struct AttachmentOverrideRecord + { + AttachmentOverrideRecord() + { + } + LLVector3 pos; + std::string name; + + bool operator<(const AttachmentOverrideRecord& other) const + { + return name < other.name; + } + }; + typedef std::map<std::string,AttachmentOverrideRecord> attachment_map_t; + attachment_map_t m_attachmentOverrides; + LLVector3 m_posBeforeOverrides; + + void updatePos(); + public: LLJoint(); LLJoint(S32 joint_num); @@ -188,15 +205,13 @@ class LLJoint void setDefaultFromCurrentXform( void ); void storeCurrentXform( const LLVector3& pos ); + void addAttachmentPosOverride( const LLVector3& pos, const std::string& attachment_name ); + void removeAttachmentPosOverride( const std::string& attachment_name ); + //Accessor for the joint id LLUUID getId( void ) { return mId; } //Setter for the joints id void setId( const LLUUID& id ) { mId = id;} - - //If the old transform flag has been set, then the reset logic in avatar needs to be aware(test) of it - const BOOL doesJointNeedToBeReset( void ) const { return mResetAfterRestoreOldXform; } - void setJointResetFlag( bool val ) { mResetAfterRestoreOldXform = val; } - }; #endif // LL_LLJOINT_H diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index b17ce97a2e694099532670b4042a22e3e596d2ba..039ff848cb3dbf138a6d55c15291f594fb490678 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1935,7 +1935,8 @@ bool LLModelLoader::doLoadModel() LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint ); if ( pJoint ) { - pJoint->storeCurrentXform( jointTransform.getTranslation() ); + LL_WARNS() << "Aieee, now what!" << LL_ENDL; + //pJoint->storeCurrentXform( jointTransform.getTranslation() ); } else { diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 80592f01ce659ce5e41c6c24eb2d1eccffcd4480..2d42c683575e91a9c189cac1e42776b6bcd4b9a9 100755 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -6190,6 +6190,17 @@ const LLUUID &LLViewerObject::extractAttachmentItemID() return getAttachmentItemID(); } +const std::string& LLViewerObject::getAttachmentItemName() +{ + static std::string empty; + LLInventoryItem *item = gInventory.getItem(getAttachmentItemID()); + if (isAttachment() && item) + { + return item->getName(); + } + return empty; +} + //virtual LLVOAvatar* LLViewerObject::getAvatar() const { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bab107cc5709b67b62d9233b829d6adec0074833..22ac4ce0db1868da40c4e494df6353289bd80692 100755 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -170,6 +170,8 @@ class LLViewerObject void setOnActiveList(BOOL on_active) { mOnActiveList = on_active; } virtual BOOL isAttachment() const { return FALSE; } + const std::string& getAttachmentItemName(); + virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment virtual BOOL isHUDAttachment() const { return FALSE; } virtual BOOL isTempAttachment() const; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e5473e92d939625f40ed2fbec75961ec2cfecd2d..fea1c0f52139f06e0c3476a9e31babaf8f3ddcf3 100755 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5058,9 +5058,9 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) return jointp; } //----------------------------------------------------------------------------- -// resetJointPositionsToDefault +// resetJointPositionsOnDetach //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsToDefault( void ) +void LLVOAvatar::resetJointPositionsOnDetach(const std::string& attachment_name) { //Subsequent joints are relative to pelvis avatar_joint_list_t::iterator iter = mSkeleton.begin(); @@ -5072,17 +5072,16 @@ void LLVOAvatar::resetJointPositionsToDefault( void ) { LLJoint* pJoint = (*iter); //Reset joints except for pelvis - if ( pJoint && pJoint != pJointPelvis && pJoint->doesJointNeedToBeReset() ) + if ( pJoint && pJoint != pJointPelvis) { pJoint->setId( LLUUID::null ); - pJoint->restoreOldXform(); + pJoint->removeAttachmentPosOverride(attachment_name); } else - if ( pJoint && pJoint == pJointPelvis && pJoint->doesJointNeedToBeReset() ) + if ( pJoint && pJoint == pJointPelvis) { pJoint->setId( LLUUID::null ); pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); - pJoint->setJointResetFlag( false ); } } @@ -5746,7 +5745,8 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig && pSkinData->mAlternateBindMatrix.size() > 0 ) { - LLVOAvatar::resetJointPositionsToDefault(); + const std::string& attachment_name = pVO->getAttachmentItemName(); + LLVOAvatar::resetJointPositionsOnDetach(attachment_name); //Need to handle the repositioning of the cam, updating rig data etc during outfit editing //This handles the case where we detach a replacement rig. if ( gAgentCamera.cameraCustomizeAvatar() ) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 42ff7bff92fb72a468602a7ec1cc0dfea5fee8d4..66a357ff62899ddef3476438363d81a55c891e8d 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -199,7 +199,7 @@ class LLVOAvatar : virtual LLJoint* getJoint(const std::string &name); - void resetJointPositionsToDefault( void ); + void resetJointPositionsOnDetach(const std::string& attachment_name); /*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 a83e2e020ea012958e2f52ecb281bfc6794a3d8e..0ef48c4c70a9589b9c70c1ca5b65cb40c4e9eaa9 100755 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4626,7 +4626,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation(); //Set the joint position - pJoint->storeCurrentXform( jointPos ); + const std::string& attachment_name = drawablep->getVObj()->getAttachmentItemName(); + //pJoint->storeCurrentXform( jointPos ); + pJoint->addAttachmentPosOverride( jointPos, attachment_name ); //If joint is a pelvis then handle old/new pelvis to foot values if ( lookingForJoint == "mPelvis" )