summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xindra/llappearance/llavatarappearance.cpp2
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.cpp2
-rwxr-xr-xindra/llcharacter/lljoint.cpp110
-rwxr-xr-xindra/llcharacter/lljoint.h30
-rwxr-xr-xindra/newview/llagentwearables.cpp5
-rwxr-xr-xindra/newview/llfloatermodelpreview.cpp2
-rwxr-xr-xindra/newview/llviewerobject.cpp11
-rwxr-xr-xindra/newview/llviewerobject.h2
-rwxr-xr-xindra/newview/llvoavatar.cpp27
-rwxr-xr-xindra/newview/llvoavatar.h2
-rwxr-xr-xindra/newview/llvovolume.cpp3
11 files changed, 125 insertions, 71 deletions
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 6fdf9e2e07..c0ad8315af 100755
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -584,8 +584,6 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
info->mRot.mV[VZ], LLQuaternion::XYZ));
joint->setScale(info->mScale);
- joint->setDefaultFromCurrentXform();
-
if (info->mIsJoint)
{
joint->setSkinOffset( info->mPivot );
diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp
index ea29cbd451..fbc312c426 100644
--- a/indra/llappearance/llpolyskeletaldistortion.cpp
+++ b/indra/llappearance/llpolyskeletaldistortion.cpp
@@ -213,7 +213,7 @@ void LLPolySkeletalDistortion::apply( ESex avatar_sex )
LLVector3 scaleDelta = iter->second;
newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
//An aspect of attached mesh objects (which contain joint offsets) that need to be cleaned up when detached
- joint->storeScaleForReset( newScale );
+ // needed? // joint->storeScaleForReset( newScale );
joint->setScale(newScale);
}
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index dbd6d48a95..bad9c198ad 100755
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -36,6 +36,20 @@
S32 LLJoint::sNumUpdates = 0;
S32 LLJoint::sNumTouches = 0;
+
+//-----------------------------------------------------------------------------
+// LLJoint::AttachmentOverrideRecord::AttachmentOverrideRecord()
+//-----------------------------------------------------------------------------
+LLJoint::AttachmentOverrideRecord::AttachmentOverrideRecord()
+{
+}
+
+template <class T>
+bool attachment_map_iter_compare_name(const T& a, const T& b)
+{
+ return a.second.name < b.second.name;
+}
+
//-----------------------------------------------------------------------------
// LLJoint()
// Class Constructor
@@ -48,11 +62,8 @@ void LLJoint::init()
mParent = NULL;
mXform.setScaleChildOffset(TRUE);
mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
- mOldXform.setScaleChildOffset(TRUE);
- mOldXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
mUpdateXform = TRUE;
- mResetAfterRestoreOldXform = false;
}
LLJoint::LLJoint() :
@@ -243,42 +254,69 @@ void LLJoint::setPosition( const LLVector3& pos )
touch(MATRIX_DIRTY | POSITION_DIRTY);
}
-
//--------------------------------------------------------------------
-// setPosition()
+// addAttachmentPosOverride()
//--------------------------------------------------------------------
-void LLJoint::setDefaultFromCurrentXform( void )
-{
- mDefaultXform = mXform;
+void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const std::string& attachment_name )
+{
+ if (attachment_name.empty())
+ {
+ return;
+ }
+ if (m_attachmentOverrides.empty())
+ {
+ LL_DEBUGS("Avatar") << getName() << " saving m_posBeforeOverrides " << getPosition() << LL_ENDL;
+ m_posBeforeOverrides = getPosition();
+ }
+ AttachmentOverrideRecord rec;
+ rec.name = attachment_name;
+ rec.pos = pos;
+ m_attachmentOverrides[attachment_name] = rec;
+ LL_DEBUGS("Avatar") << getName() << " addAttachmentPosOverride for " << attachment_name << " pos " << pos << LL_ENDL;
+ updatePos();
}
//--------------------------------------------------------------------
-// storeCurrentXform()
+// removeAttachmentPosOverride()
//--------------------------------------------------------------------
-void LLJoint::storeCurrentXform( const LLVector3& pos )
-{
- mOldXform = mXform;
- mResetAfterRestoreOldXform = true;
- setPosition( pos );
- touch(ALL_DIRTY);
+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_DEBUGS("Avatar") << getName() << " removeAttachmentPosOverride for " << attachment_name << LL_ENDL;
+ m_attachmentOverrides.erase(it);
+ }
+ updatePos();
}
//--------------------------------------------------------------------
-// storeScaleForReset()
+// updatePos()
//--------------------------------------------------------------------
-void LLJoint::storeScaleForReset( const LLVector3& scale )
+void LLJoint::updatePos()
{
- mOldXform.setScale( scale );
-}
-//--------------------------------------------------------------------
-// restoreOldXform()
-//--------------------------------------------------------------------
-void LLJoint::restoreOldXform( void )
-{
- mXform = mDefaultXform;
- mResetAfterRestoreOldXform = false;
- mDirtyFlags = ALL_DIRTY;
+ LLVector3 pos;
+ attachment_map_t::iterator it = std::max_element(m_attachmentOverrides.begin(),
+ m_attachmentOverrides.end(),
+ attachment_map_iter_compare_name<LLJoint::attachment_map_t::value_type>);
+ if (it != m_attachmentOverrides.end())
+ {
+ AttachmentOverrideRecord& rec = it->second;
+ LL_DEBUGS("Avatar") << getName() << " updatePos, winner of " << m_attachmentOverrides.size() << " is attachment " << rec.name << " pos " << rec.pos << LL_ENDL;
+ pos = rec.pos;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << getName() << " updatePos, winner is posBeforeOverrides " << m_posBeforeOverrides << LL_ENDL;
+ pos = m_posBeforeOverrides;
+ }
+ setPosition(pos);
}
+
//--------------------------------------------------------------------
// getWorldPosition()
//--------------------------------------------------------------------
@@ -325,7 +363,7 @@ void LLJoint::setWorldPosition( const LLVector3& pos )
//--------------------------------------------------------------------
-// mXform.getRotation()
+// getRotation()
//--------------------------------------------------------------------
const LLQuaternion& LLJoint::getRotation()
{
@@ -432,7 +470,7 @@ const LLMatrix4 &LLJoint::getWorldMatrix()
//--------------------------------------------------------------------
void LLJoint::setWorldMatrix( const LLMatrix4& mat )
{
-LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL;
+ LL_INFOS() << "WARNING: LLJoint::setWorldMatrix() not correctly implemented yet" << LL_ENDL;
// extract global translation
LLVector3 trans( mat.mMatrix[VW][VX],
mat.mMatrix[VW][VY],
@@ -548,20 +586,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 b65d6979d4..0ef054d9c1 100755
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -79,8 +79,6 @@ protected:
// explicit transformation members
LLXformMatrix mXform;
- LLXformMatrix mOldXform;
- LLXformMatrix mDefaultXform;
LLUUID mId;
@@ -88,8 +86,6 @@ public:
U32 mDirtyFlags;
BOOL mUpdateXform;
- BOOL mResetAfterRestoreOldXform;
-
// describes the skin binding pose
LLVector3 mSkinOffset;
@@ -103,6 +99,18 @@ public:
static S32 sNumTouches;
static S32 sNumUpdates;
+ struct AttachmentOverrideRecord
+ {
+ AttachmentOverrideRecord();
+ LLVector3 pos;
+ std::string 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);
@@ -160,7 +168,7 @@ public:
// get/set local scale
const LLVector3& getScale();
void setScale( const LLVector3& scale );
- void storeScaleForReset( const LLVector3& scale );
+
// get/set world matrix
const LLMatrix4 &getWorldMatrix();
void setWorldMatrix( const LLMatrix4& mat );
@@ -183,20 +191,14 @@ public:
virtual BOOL isAnimatable() const { return TRUE; }
S32 getJointNum() const { return mJointNum; }
-
- void restoreOldXform( void );
- 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/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 49fedb8df8..3928bbadc8 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1009,6 +1009,10 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
continue;
}
+ // Don't care about this case - ordering of wearables with the same asset id has no effect.
+ // Causes the two-alphas error case in MAINT-4158.
+ // We should actually disallow wearing two wearables with the same asset id.
+#if 0
if (curr_wearable->getName() != new_item->getName() ||
curr_wearable->getItemID() != new_item->getUUID())
{
@@ -1019,6 +1023,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
mismatched++;
continue;
}
+#endif
// If we got here, everything matches.
matched++;
}
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index b17ce97a2e..195a7f5ffe 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -1935,7 +1935,7 @@ bool LLModelLoader::doLoadModel()
LLJoint* pJoint = mPreview->getPreviewAvatar()->getJoint( lookingForJoint );
if ( pJoint )
{
- pJoint->storeCurrentXform( jointTransform.getTranslation() );
+ pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), mFilename);
}
else
{
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 4f992fc184..97cefaf33c 100755
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -6193,6 +6193,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 bab107cc57..22ac4ce0db 100755
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -170,6 +170,8 @@ public:
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 d6c03b6888..904d08ac73 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -5064,9 +5064,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();
@@ -5078,17 +5078,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 );
}
}
@@ -5631,7 +5630,7 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
}
//-----------------------------------------------------------------------------
-// attachObject()
+// getNumAttachments()
//-----------------------------------------------------------------------------
U32 LLVOAvatar::getNumAttachments() const
{
@@ -5752,7 +5751,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() )
@@ -7682,6 +7682,17 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
}
}
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+ for (; iter != end; ++iter)
+ {
+ LLJoint* pJoint = (*iter);
+ const LLVector3& pos = pJoint->getPosition();
+ const LLVector3& scale = pJoint->getScale();
+ apr_file_printf( file, "\t\t<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+ }
+
apr_file_printf( file, "\t</archetype>\n" );
apr_file_printf( file, "\n</linden_genepool>\n" );
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 42ff7bff92..66a357ff62 100755
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -199,7 +199,7 @@ public:
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 4295ea02d5..9d16ce5a7b 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4637,7 +4637,8 @@ 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->addAttachmentPosOverride( jointPos, attachment_name );
//If joint is a pelvis then handle old/new pelvis to foot values
if ( lookingForJoint == "mPelvis" )