diff options
| -rw-r--r-- | indra/llappearance/llavatarappearance.cpp | 1 | ||||
| -rw-r--r-- | indra/llappearance/llavatarappearance.h | 2 | ||||
| -rw-r--r-- | indra/llappearance/llpolyskeletaldistortion.cpp | 2 | ||||
| -rw-r--r-- | indra/llcharacter/lljoint.cpp | 232 | ||||
| -rw-r--r-- | indra/llcharacter/lljoint.h | 31 | ||||
| -rw-r--r-- | indra/llprimitive/lldaeloader.cpp | 33 | ||||
| -rw-r--r-- | indra/llprimitive/llmodel.cpp | 27 | ||||
| -rw-r--r-- | indra/llprimitive/llmodel.h | 11 | ||||
| -rw-r--r-- | indra/newview/llappearancemgr.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 57 | ||||
| -rw-r--r-- | indra/newview/llfloatermodelpreview.h | 4 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.h | 10 | ||||
| -rw-r--r-- | indra/newview/llviewerobject.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.cpp | 133 | ||||
| -rw-r--r-- | indra/newview/llvoavatar.h | 15 | ||||
| -rw-r--r-- | indra/newview/llvovolume.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/floater_model_preview.xml | 7 | 
18 files changed, 452 insertions, 137 deletions
| diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 2bcb449854..af14e3418b 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -660,6 +660,7 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent  	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],  							 info->mRot.mV[VZ], LLQuaternion::XYZ));  	joint->setScale(info->mScale); +	joint->setDefaultScale(info->mScale);      joint->setSupport(info->mSupport);  	joint->setEnd(info->mEnd); diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 6b09e2cbe1..6938ca2dea 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -168,7 +168,7 @@ protected:  	void				clearSkeleton();  	BOOL				mIsBuilt; // state of deferred character building  	avatar_joint_list_t	mSkeleton; -	LLPosOverrideMap	mPelvisFixups; +	LLVector3OverrideMap	mPelvisFixups;      joint_alias_map_t   mJointAliasMap;  	//-------------------------------------------------------------------- diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp index 8d71335175..5662fdd6bc 100644 --- a/indra/llappearance/llpolyskeletaldistortion.cpp +++ b/indra/llappearance/llpolyskeletaldistortion.cpp @@ -217,7 +217,7 @@ void LLPolySkeletalDistortion::apply( ESex avatar_sex )                  ostr << "LLPolySkeletalDistortion::apply, id " << getID() << " " << getName() << " effective wt " << effective_weight << " last wt " << mLastWeight << " scaleDelta " << scaleDelta << " offset " << offset;                  LLScopedContextString str(ostr.str()); -				joint->setScale(newScale); +				joint->setScale(newScale, true);          }          for (iter = mJointOffsets.begin(); diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index 3c61047efc..8d101ff1fc 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -44,7 +44,7 @@ bool attachment_map_iter_compare_key(const T& a, const T& b)  	return a.first < b.first;  } -bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const +bool LLVector3OverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const  {  	pos = LLVector3(0,0,0);  	mesh_id = LLUUID(); @@ -62,7 +62,7 @@ bool LLPosOverrideMap::findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const  	return found;  } -void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const +void LLVector3OverrideMap::showJointVector3Overrides( std::ostringstream& os ) const  {  	map_type::const_iterator max_it = std::max_element(m_map.begin(),  													   m_map.end(), @@ -75,23 +75,23 @@ void LLPosOverrideMap::showJointPosOverrides( std::ostringstream& os ) const  	}  } -U32 LLPosOverrideMap::count() const +U32 LLVector3OverrideMap::count() const  {  	return m_map.size();  } -void LLPosOverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos) +void LLVector3OverrideMap::add(const LLUUID& mesh_id, const LLVector3& pos)  {  	m_map[mesh_id] = pos;  } -bool LLPosOverrideMap::remove(const LLUUID& mesh_id) +bool LLVector3OverrideMap::remove(const LLUUID& mesh_id)  {  	U32 remove_count = m_map.erase(mesh_id);  	return (remove_count > 0);  } -void LLPosOverrideMap::clear() +void LLVector3OverrideMap::clear()  {  	m_map.clear();  } @@ -342,7 +342,7 @@ void LLJoint::setPosition( const LLVector3& requested_pos, bool apply_attachment      LLVector3 active_override;      LLUUID mesh_id; -    if (apply_attachment_overrides && m_attachmentOverrides.findActiveOverride(mesh_id,active_override)) +    if (apply_attachment_overrides && m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override))      {            if (pos != active_override && do_debug_joint(getName()))          { @@ -377,21 +377,47 @@ const LLVector3& LLJoint::getDefaultPosition() const  {      return mDefaultPosition;  } + +void LLJoint::setDefaultScale( const LLVector3& scale ) +{ +    mDefaultScale = scale; +} + +const LLVector3& LLJoint::getDefaultScale() const +{ +    return mDefaultScale; +} +  void showJointPosOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info )  {          std::ostringstream os;          os << joint.m_posBeforeOverrides; -        joint.m_attachmentOverrides.showJointPosOverrides(os); +        joint.m_attachmentPosOverrides.showJointVector3Overrides(os); +        LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL; +} + +void showJointScaleOverrides( const LLJoint& joint, const std::string& note, const std::string& av_info ) +{ +        std::ostringstream os; +        os << joint.m_scaleBeforeOverrides; +        joint.m_attachmentScaleOverrides.showJointVector3Overrides(os);          LL_DEBUGS("Avatar") << av_info << " joint " << joint.getName() << " " << note << " " << os.str() << LL_ENDL;  } -bool above_joint_pos_threshold(const LLVector3& diff) +bool LLJoint::aboveJointPosThreshold(const LLVector3& pos) const  { -	//return !diff.isNull(); +    LLVector3 diff = pos - getDefaultPosition();  	const F32 max_joint_pos_offset = 0.0001f; // 0.1 mm  	return diff.lengthSquared() > max_joint_pos_offset * max_joint_pos_offset;  } +bool LLJoint::aboveJointScaleThreshold(const LLVector3& scale) const +{ +    LLVector3 diff = scale - getDefaultScale(); +	const F32 max_joint_scale_offset = 0.0001f; // 0.1 mm +	return diff.lengthSquared() > max_joint_scale_offset * max_joint_scale_offset; +} +  //--------------------------------------------------------------------  // addAttachmentPosOverride()  //-------------------------------------------------------------------- @@ -408,20 +434,11 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh      //{      //    return;      //} -    if (!above_joint_pos_threshold(pos-getDefaultPosition())) -    { -        if (do_debug_joint(getName())) -        { -            LL_DEBUGS("Avatar") << "Attachment pos override ignored for " << getName() -                                << ", pos " << pos << " is same as default pos" << LL_ENDL; -        } -		return; -    }      LLVector3 before_pos;      LLUUID before_mesh_id;      bool has_active_override_before = hasAttachmentPosOverride( before_pos, before_mesh_id ); -	if (!m_attachmentOverrides.count()) +	if (!m_attachmentPosOverrides.count())  	{  		if (do_debug_joint(getName()))  		{ @@ -429,7 +446,7 @@ void LLJoint::addAttachmentPosOverride( const LLVector3& pos, const LLUUID& mesh  		}  		m_posBeforeOverrides = getPosition();  	} -	m_attachmentOverrides.add(mesh_id,pos); +	m_attachmentPosOverrides.add(mesh_id,pos);      LLVector3 after_pos;      LLUUID after_mesh_id;      hasAttachmentPosOverride(after_pos, after_mesh_id); @@ -457,7 +474,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str      LLVector3 before_pos;      LLUUID before_mesh_id;      hasAttachmentPosOverride( before_pos, before_mesh_id ); -	if (m_attachmentOverrides.remove(mesh_id)) +	if (m_attachmentPosOverrides.remove(mesh_id))  	{          LLVector3 after_pos;          LLUUID after_mesh_id; @@ -481,7 +498,7 @@ void LLJoint::removeAttachmentPosOverride( const LLUUID& mesh_id, const std::str   //--------------------------------------------------------------------  bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const  { -	return m_attachmentOverrides.findActiveOverride(mesh_id,pos); +	return m_attachmentPosOverrides.findActiveOverride(mesh_id,pos);  }  //-------------------------------------------------------------------- @@ -489,9 +506,9 @@ bool LLJoint::hasAttachmentPosOverride( LLVector3& pos, LLUUID& mesh_id ) const  //--------------------------------------------------------------------  void LLJoint::clearAttachmentPosOverrides()  { -	if (m_attachmentOverrides.count()) +	if (m_attachmentPosOverrides.count())  	{ -		m_attachmentOverrides.clear(); +		m_attachmentPosOverrides.clear();  		setPosition(m_posBeforeOverrides);  		setId( LLUUID::null );  	} @@ -505,11 +522,11 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const      LLVector3 active_override;      bool has_active_override;      LLUUID mesh_id; -    has_active_override = m_attachmentOverrides.findActiveOverride(mesh_id,active_override); -    U32 count = m_attachmentOverrides.count(); +    has_active_override = m_attachmentPosOverrides.findActiveOverride(mesh_id,active_override); +    U32 count = m_attachmentPosOverrides.count();      if (count==1)      { -		LLPosOverrideMap::map_type::const_iterator it = m_attachmentOverrides.getMap().begin(); +		LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin();          std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : "";          LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName()                              << " has single attachment pos override " << highlight << "" << it->second << " default " << mDefaultPosition << LL_ENDL; @@ -518,8 +535,8 @@ void LLJoint::showAttachmentPosOverrides(const std::string& av_info) const      {          LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment pos overrides" << LL_ENDL;  		std::set<LLVector3> distinct_offsets; -        LLPosOverrideMap::map_type::const_iterator it = m_attachmentOverrides.getMap().begin(); -        for (; it != m_attachmentOverrides.getMap().end(); ++it) +        LLVector3OverrideMap::map_type::const_iterator it = m_attachmentPosOverrides.getMap().begin(); +        for (; it != m_attachmentPosOverrides.getMap().end(); ++it)          {              distinct_offsets.insert(it->second);          } @@ -547,11 +564,11 @@ void LLJoint::updatePos(const std::string& av_info)  {  	LLVector3 pos, found_pos;  	LLUUID mesh_id; -	if (m_attachmentOverrides.findActiveOverride(mesh_id,found_pos)) +	if (m_attachmentPosOverrides.findActiveOverride(mesh_id,found_pos))  	{          if (do_debug_joint(getName()))          { -            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL; +            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updatePos, winner of " << m_attachmentPosOverrides.count() << " is mesh " << mesh_id << " pos " << found_pos << LL_ENDL;          }  		pos = found_pos;  	} @@ -566,6 +583,142 @@ void LLJoint::updatePos(const std::string& av_info)  	setPosition(pos);  } +//-------------------------------------------------------------------- +// updateScale() +//-------------------------------------------------------------------- +void LLJoint::updateScale(const std::string& av_info) +{ +	LLVector3 scale, found_scale; +	LLUUID mesh_id; +	if (m_attachmentScaleOverrides.findActiveOverride(mesh_id,found_scale)) +	{ +        if (do_debug_joint(getName())) +        { +            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner of " << m_attachmentScaleOverrides.count() << " is mesh " << mesh_id << " scale " << found_scale << LL_ENDL; +        } +		scale = found_scale; +	} +	else +	{ +        if (do_debug_joint(getName())) +        { +            LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " updateScale, winner is scaleBeforeOverrides " << m_scaleBeforeOverrides << LL_ENDL; +        } +		scale = m_scaleBeforeOverrides; +	} +	setScale(scale); +} + +//-------------------------------------------------------------------- +// addAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ) +{ +	if (mesh_id.isNull()) +	{ +		return; +	} +	if (!m_attachmentScaleOverrides.count()) +	{ +		if (do_debug_joint(getName())) +		{ +			LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " saving m_scaleBeforeOverrides " << getScale() << LL_ENDL; +		} +		m_scaleBeforeOverrides = getScale(); +	} +	m_attachmentScaleOverrides.add(mesh_id,scale); +	if (do_debug_joint(getName())) +	{ +		LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " addAttachmentScaleOverride for mesh " << mesh_id << " scale " << scale << LL_ENDL; +	} +	updateScale(av_info); +} + +//-------------------------------------------------------------------- +// removeAttachmentScaleOverride() +//-------------------------------------------------------------------- +void LLJoint::removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ) +{ +	if (mesh_id.isNull()) +	{ +		return; +	} +	if (m_attachmentScaleOverrides.remove(mesh_id)) +	{ +		if (do_debug_joint(getName())) +		{ +			LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() +								<< " removeAttachmentScaleOverride for " << mesh_id << LL_ENDL; +			showJointScaleOverrides(*this, "remove", av_info); +		} +		updateScale(av_info); +	} +} + +//-------------------------------------------------------------------- + // hasAttachmentScaleOverride() + //-------------------------------------------------------------------- +bool LLJoint::hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const +{ +	return m_attachmentScaleOverrides.findActiveOverride(mesh_id,scale); +} + +//-------------------------------------------------------------------- +// clearAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::clearAttachmentScaleOverrides() +{ +	if (m_attachmentScaleOverrides.count()) +	{ +		m_attachmentScaleOverrides.clear(); +		setScale(m_scaleBeforeOverrides); +		setId( LLUUID::null ); +	} +} + +//-------------------------------------------------------------------- +// showAttachmentScaleOverrides() +//-------------------------------------------------------------------- +void LLJoint::showAttachmentScaleOverrides(const std::string& av_info) const +{ +    LLVector3 active_override; +    bool has_active_override; +    LLUUID mesh_id; +    has_active_override = m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override); +    U32 count = m_attachmentScaleOverrides.count(); +    if (count==1) +    { +		LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); +        std::string highlight = (has_active_override && (it->second == active_override)) ? "*" : ""; +        LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() +                            << " has single attachment scale override " << highlight << "" << it->second << " default " << mDefaultScale << LL_ENDL; +    } +    else if (count>1) +    { +        LL_DEBUGS("Avatar") << "av " << av_info << " joint " << getName() << " has " << count << " attachment scale overrides" << LL_ENDL; +		std::set<LLVector3> distinct_offsets; +        LLVector3OverrideMap::map_type::const_iterator it = m_attachmentScaleOverrides.getMap().begin(); +        for (; it != m_attachmentScaleOverrides.getMap().end(); ++it) +        { +            distinct_offsets.insert(it->second); +        } +        if (distinct_offsets.size()>1) +        { +            LL_DEBUGS("Avatar") << "CONFLICTS, " << distinct_offsets.size() << " different values" << LL_ENDL; +        } +        else +        { +            LL_DEBUGS("Avatar") << "no conflicts" << LL_ENDL; +        } +        std::set<LLVector3>::iterator dit = distinct_offsets.begin(); +        for ( ; dit != distinct_offsets.end(); ++dit) +        { +            std::string highlight = (has_active_override && *dit == active_override) ? "*" : ""; +            LL_DEBUGS("Avatar") << "  POS " << highlight << "" << (*dit) << " default " << mDefaultScale << LL_ENDL; +        } +	} +} +  // init static  LLJoint::debug_joint_name_t LLJoint::s_debugJointNames = debug_joint_name_t(); @@ -708,8 +861,21 @@ const LLVector3& LLJoint::getScale()  //--------------------------------------------------------------------  // setScale()  //-------------------------------------------------------------------- -void LLJoint::setScale( const LLVector3& scale ) +void LLJoint::setScale( const LLVector3& requested_scale, bool apply_attachment_overrides )  { +    LLVector3 scale(requested_scale); +    LLUUID mesh_id; +    LLVector3 active_override; +    if (apply_attachment_overrides && m_attachmentScaleOverrides.findActiveOverride(mesh_id,active_override)) +    {   +        if (scale != active_override && do_debug_joint(getName())) +        { +            LLScopedContextString str("setScale"); +            LL_DEBUGS("Avatar") << " joint " << getName() << " requested_scale " << requested_scale +                                << " overriden by attachment " << active_override << LL_ENDL; +        } +        scale = active_override; +    }  	if ((mXform.getScale() != scale) && do_debug_joint(getName()))  	{	          LLScopedContextString str("setScale"); diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index b2736f6c1e..42c2c6f1ad 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -53,12 +53,12 @@ const U32 LL_FACE_JOINT_NUM = (LL_CHARACTER_MAX_ANIMATED_JOINTS-2);  const S32 LL_CHARACTER_MAX_PRIORITY = 7;  const F32 LL_MAX_PELVIS_OFFSET = 5.f; -class LLPosOverrideMap +class LLVector3OverrideMap  {  public: -	LLPosOverrideMap() {} +	LLVector3OverrideMap() {}  	bool findActiveOverride(LLUUID& mesh_id, LLVector3& pos) const; -	void showJointPosOverrides(std::ostringstream& os) const; +	void showJointVector3Overrides(std::ostringstream& os) const;  	U32 count() const;  	void add(const LLUUID& mesh_id, const LLVector3& pos);  	bool remove(const LLUUID& mesh_id); @@ -115,6 +115,7 @@ protected:  	LLUUID				mId;      LLVector3       mDefaultPosition; +    LLVector3       mDefaultScale;  public:  	U32				mDirtyFlags; @@ -141,10 +142,16 @@ public:      static void setDebugJointNames(const debug_joint_name_t& names);      static void setDebugJointNames(const std::string& names_string); -	LLPosOverrideMap m_attachmentOverrides; +    // Position overrides +	LLVector3OverrideMap m_attachmentPosOverrides;  	LLVector3 m_posBeforeOverrides; +    // Scale overrides +	LLVector3OverrideMap m_attachmentScaleOverrides; +	LLVector3 m_scaleBeforeOverrides; +  	void updatePos(const std::string& av_info); +	void updateScale(const std::string& av_info);  public:  	LLJoint(); @@ -216,6 +223,10 @@ public:  	void setDefaultPosition( const LLVector3& pos );  	const LLVector3& getDefaultPosition() const; +    // Tracks the default scale defined by the skeleton +	void setDefaultScale( const LLVector3& scale ); +	const LLVector3& getDefaultScale() const; +  	// get/set world position  	LLVector3 getWorldPosition();  	LLVector3 getLastWorldPosition(); @@ -232,7 +243,7 @@ public:  	// get/set local scale  	const LLVector3& getScale(); -	void setScale( const LLVector3& scale ); +	void setScale( const LLVector3& scale, bool apply_attachment_overrides = false );  	// get/set world matrix  	const LLMatrix4 &getWorldMatrix(); @@ -261,6 +272,16 @@ public:  	void clearAttachmentPosOverrides();      void showAttachmentPosOverrides(const std::string& av_info) const; +	void addAttachmentScaleOverride( const LLVector3& scale, const LLUUID& mesh_id, const std::string& av_info ); +	void removeAttachmentScaleOverride( const LLUUID& mesh_id, const std::string& av_info ); +	bool hasAttachmentScaleOverride( LLVector3& scale, LLUUID& mesh_id ) const; +	void clearAttachmentScaleOverrides(); +    void showAttachmentScaleOverrides(const std::string& av_info) const; + +    // These are used in checks of whether a pos/scale override is considered significant. +    bool aboveJointPosThreshold(const LLVector3& pos) const; +    bool aboveJointScaleThreshold(const LLVector3& scale) const; +      	//Accessor for the joint id  	LLUUID getId( void ) { return mId; }  	//Setter for the joints id diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 37ebdf2cec..c194d677c8 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -1379,6 +1379,16 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do  		if ( !missingSkeletonOrScene )  		{ +            // FIXME: mesh_id is used to determine which mesh gets to +            // set the joint offset, in the event of a conflict. Since +            // we don't know the mesh id yet, we can't guarantee that +            // joint offsets will be applied with the same priority as +            // in the uploaded model. If the file contains multiple +            // meshes with conflicting joint offsets, preview may be +            // incorrect. +            LLUUID fake_mesh_id; +            fake_mesh_id.generate(); +  			//Set the joint translations on the avatar              JointMap :: const_iterator masterJointIt = mJointMap.begin();              JointMap :: const_iterator masterJointItEnd = mJointMap.end(); @@ -1393,19 +1403,16 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do                      LLJoint* pJoint = mJointLookupFunc(lookingForJoint,mOpaqueData);                      if ( pJoint )                      {    -                        // FIXME: mesh_id is used to determine which -                        // mesh gets to set the joint offset, in the -                        // event of a conflict. Since we don't know -                        // the mesh id yet, we can't guarantee that -                        // joint offsets will be applied with the same -                        // priority as in the uploaded model. If the -                        // file contains multiple meshes with -                        // conflicting joint offsets, preview may be -                        // incorrect. -                        LLUUID fake_mesh_id; -                        fake_mesh_id.generate(); -                        bool dummy; // not used -                        pJoint->addAttachmentPosOverride( jointTransform.getTranslation(), fake_mesh_id, "", dummy); +                        const LLVector3& joint_pos = jointTransform.getTranslation(); +                        if (pJoint->aboveJointPosThreshold(joint_pos)) +                        { +                            bool override_changed; // not used +                            pJoint->addAttachmentPosOverride(joint_pos, fake_mesh_id, "", override_changed); +                            if (model->mSkinInfo.mLockScaleIfJointPosition) +                            { +                                pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), fake_mesh_id, ""); +                            } +                        }                      }                      else                      { diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 398f0997f3..6637f41966 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -50,8 +50,12 @@ std::string model_names[] =  const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);  LLModel::LLModel(LLVolumeParams& params, F32 detail) -	: LLVolume(params, detail), mNormalizedScale(1,1,1), mNormalizedTranslation(0,0,0) -	, mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0) +	: LLVolume(params, detail),  +      mNormalizedScale(1,1,1),  +      mNormalizedTranslation(0,0,0),  +      mPelvisOffset( 0.0f ),  +      mStatus(NO_ERRORS),  +      mSubmodelID(0)  {  	mDecompID = -1;  	mLocalID = -1; @@ -667,6 +671,7 @@ LLSD LLModel::writeModel(  	const LLModel::Decomposition& decomp,  	BOOL upload_skin,  	BOOL upload_joints, +    BOOL lock_scale_if_joint_position,  	BOOL nowrite,  	BOOL as_slm,  	int submodel_id) @@ -686,7 +691,7 @@ LLSD LLModel::writeModel(  	if (skinning)  	{ //write skinning block -		mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints); +		mdl["skin"] = high->mSkinInfo.asLLSD(upload_joints, lock_scale_if_joint_position);  	}  	if (!decomp.mBaseHull.empty() || @@ -1446,9 +1451,18 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)  	{  		mPelvisOffset = skin["pelvis_offset"].asReal();  	} + +    if (skin.has("lock_scale_if_joint_position")) +    { +        mLockScaleIfJointPosition = skin["lock_scale_if_joint_position"].asBoolean(); +    } +	else +	{ +		mLockScaleIfJointPosition = false; +	}  } -LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const +LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_position) const  {  	LLSD ret; @@ -1486,6 +1500,11 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints) const  			}  		} +        if (lock_scale_if_joint_position) +        { +            ret["lock_scale_if_joint_position"] = mLockScaleIfJointPosition; +        } +  		ret["pelvis_offset"] = mPelvisOffset;  	} diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 5f98942340..c23d65bc8f 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -42,18 +42,20 @@ class domMesh;  class LLMeshSkinInfo   {  public: +	LLMeshSkinInfo() { } +	LLMeshSkinInfo(LLSD& data); +	void fromLLSD(LLSD& data); +	LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; +  	LLUUID mMeshID;  	std::vector<std::string> mJointNames;  	std::vector<LLMatrix4> mInvBindMatrix;  	std::vector<LLMatrix4> mAlternateBindMatrix;      std::vector<U32> mJointRemap; -	LLMeshSkinInfo() { } -	LLMeshSkinInfo(LLSD& data); -	void fromLLSD(LLSD& data); -	LLSD asLLSD(bool include_joints) const;  	LLMatrix4 mBindShapeMatrix;  	float mPelvisOffset; +    bool mLockScaleIfJointPosition;  };  class LLModel : public LLVolume @@ -138,6 +140,7 @@ public:  		const LLModel::Decomposition& decomp,  		BOOL upload_skin,  		BOOL upload_joints, +        BOOL lock_scale_if_joint_position,  		BOOL nowrite = FALSE,  		BOOL as_slm = FALSE,  		int submodel_id = 0); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index ff5439d610..d403e39329 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -857,7 +857,7 @@ void LLWearableHoldingPattern::onAllComplete()  		// attachments, even those that are not being removed. This is  		// needed to get joint positions all slammed down to their  		// pre-attachment states. -		gAgentAvatarp->clearAttachmentPosOverrides(); +		gAgentAvatarp->clearAttachmentOverrides();  		if (objects_to_remove.size() || items_to_add.size())  		{ @@ -880,7 +880,7 @@ void LLWearableHoldingPattern::onAllComplete()  			 ++it)  		{  			LLViewerObject *objectp = *it; -			gAgentAvatarp->addAttachmentPosOverridesForObject(objectp); +			gAgentAvatarp->addAttachmentOverridesForObject(objectp);  		}  		// Add new attachments to match those requested. diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 93775b62ed..7aae48cf5d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -298,6 +298,7 @@ BOOL LLFloaterModelPreview::postBuild()  	childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);  	childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); +	childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);  	childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL);  	childSetTextArg("status", "[STATUS]", getString("status_idle")); @@ -311,6 +312,7 @@ BOOL LLFloaterModelPreview::postBuild()  	childSetCommitCallback("upload_skin", onUploadSkinCommit, this);  	childSetCommitCallback("upload_joints", onUploadJointsCommit, this); +	childSetCommitCallback("lock_scale_if_joint_position", onUploadJointsCommit, this);  	childSetCommitCallback("import_scale", onImportScaleCommit, this);  	childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); @@ -323,6 +325,7 @@ BOOL LLFloaterModelPreview::postBuild()  	childDisable("upload_skin");  	childDisable("upload_joints"); +	childDisable("lock_scale_if_joint_position");  	initDecompControls(); @@ -488,18 +491,20 @@ void LLFloaterModelPreview::onClickCalculateBtn()  	bool upload_skinweights = childGetValue("upload_skin").asBoolean();  	bool upload_joint_positions = childGetValue("upload_joints").asBoolean(); +    bool lock_scale_if_joint_position = childGetValue("lock_scale_if_joint_position").asBoolean();      if (upload_joint_positions)      {          // Diagnostic message showing list of joints for which joint offsets are defined.          // FIXME - given time, would be much better to put this in the UI, in updateStatusMessages(). -		mModelPreview->getPreviewAvatar()->showAttachmentPosOverrides(); +		mModelPreview->getPreviewAvatar()->showAttachmentOverrides();      }  	mUploadModelUrl.clear();  	gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, -                          childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, +                          childGetValue("upload_textures").asBoolean(),  +                          upload_skinweights, upload_joint_positions, lock_scale_if_joint_position,                            mUploadModelUrl, false,  						  getWholeModelFeeObserverHandle()); @@ -1324,9 +1329,10 @@ U32 LLModelPreview::calcResourceCost()  					   decomp,  					   mFMP->childGetValue("upload_skin").asBoolean(),  					   mFMP->childGetValue("upload_joints").asBoolean(), +					   mFMP->childGetValue("lock_scale_if_joint_position").asBoolean(),  					   TRUE, -						FALSE, -						instance.mModel->mSubmodelID); +					   FALSE, +					   instance.mModel->mSubmodelID);  			num_hulls += decomp.mHull.size();  			for (U32 i = 0; i < decomp.mHull.size(); ++i) @@ -1651,7 +1657,7 @@ void LLModelPreview::rebuildUploadData()  } -void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position)  {  	if (!mLODFile[LLModel::LOD_HIGH].empty())  	{ @@ -1660,12 +1666,13 @@ void LLModelPreview::saveUploadData(bool save_skinweights, bool save_joint_posit          if (LLModelLoader::getSLMFilename(filename, slm_filename))          { -			saveUploadData(slm_filename, save_skinweights, save_joint_positions); +			saveUploadData(slm_filename, save_skinweights, save_joint_positions, lock_scale_if_joint_position);  		}  	}  } -void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions) +void LLModelPreview::saveUploadData(const std::string& filename,  +                                    bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position)  {  	std::set<LLPointer<LLModel> > meshes; @@ -1706,7 +1713,9 @@ void LLModelPreview::saveUploadData(const std::string& filename, bool save_skinw  				instance.mLOD[LLModel::LOD_LOW],   				instance.mLOD[LLModel::LOD_IMPOSTOR],   				decomp,  -				save_skinweights, save_joint_positions, +				save_skinweights,  +                save_joint_positions, +                lock_scale_if_joint_position,                  FALSE, TRUE, instance.mModel->mSubmodelID);  			data["mesh"][instance.mModel->mLocalID] = str.str(); @@ -1946,6 +1955,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)  		bool skin_weights = false;  		bool joint_positions = false; +		bool lock_scale_if_joint_position = false;  		for (S32 lod = 0; lod < LLModel::NUM_LODS; ++lod)  		{ //for each LoD @@ -1993,6 +2003,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)  							{  								joint_positions = true;  							} +							if (list_iter->mModel->mSkinInfo.mLockScaleIfJointPosition) +							{ +								lock_scale_if_joint_position = true; +							}  						}  					}  				} @@ -2016,6 +2030,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)  				mViewOption["show_joint_positions"] = true;  				fmp->childSetValue("upload_joints", true);  			} + +			if (lock_scale_if_joint_position) +			{ +				fmp->enableViewOption("lock_scale_if_joint_position"); +				mViewOption["lock_scale_if_joint_position"] = true; +				fmp->childSetValue("lock_scale_if_joint_position", true); +			}  		}  		//copy high lod to base scene for LoD generation @@ -3645,7 +3666,17 @@ BOOL LLModelPreview::render()  		mFMP->childSetValue("upload_joints", false);  		upload_joints = false;		  	}	 -		 + +    if (upload_skin && upload_joints) +    { +        mFMP->childEnable("lock_scale_if_joint_position"); +    } +    else +    { +        mFMP->childDisable("lock_scale_if_joint_position"); +        mFMP->childSetValue("lock_scale_if_joint_position", false); +    } +      	//Only enable joint offsets if it passed the earlier critiquing  	if ( isRigValidForJointPositionUpload() )    	{ @@ -4239,15 +4270,17 @@ void LLFloaterModelPreview::onUpload(void* user_data)  	bool upload_skinweights = mp->childGetValue("upload_skin").asBoolean();  	bool upload_joint_positions = mp->childGetValue("upload_joints").asBoolean(); - +    bool lock_scale_if_joint_position = mp->childGetValue("lock_scale_if_joint_position").asBoolean();  	if (gSavedSettings.getBOOL("MeshImportUseSLM"))  	{ -        mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions); +        mp->mModelPreview->saveUploadData(upload_skinweights, upload_joint_positions, lock_scale_if_joint_position);      }  	gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, -						  mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, mp->mUploadModelUrl, +						  mp->childGetValue("upload_textures").asBoolean(),  +                          upload_skinweights, upload_joint_positions, lock_scale_if_joint_position,  +                          mp->mUploadModelUrl,  						  true, LLHandle<LLWholeModelFeeObserver>(), mp->getWholeModelUploadObserverHandle());  } diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 217ac35888..a7a5c1b33a 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -270,8 +270,8 @@ public:  	void restoreNormals();  	U32 calcResourceCost();  	void rebuildUploadData(); -	void saveUploadData(bool save_skinweights, bool save_joint_poisitions); -	void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); +	void saveUploadData(bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position); +	void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_positions, bool lock_scale_if_joint_position);  	void clearIncompatible(S32 lod);  	void updateStatusMessages();  	void updateLodControls(S32 lod); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 54f8fb93d0..5f8f42a1d6 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1896,7 +1896,8 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32  }  LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, -									   bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload, +									   bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, +                                       const std::string & upload_url, bool do_upload,  									   LLHandle<LLWholeModelFeeObserver> fee_observer,  									   LLHandle<LLWholeModelUploadObserver> upload_observer)    : LLThread("mesh upload"), @@ -1911,6 +1912,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,  	mUploadTextures = upload_textures;  	mUploadSkin = upload_skin;  	mUploadJoints = upload_joints; +    mLockScaleIfJointPosition = lock_scale_if_joint_position;  	mMutex = new LLMutex(NULL);  	mPendingUploads = 0;  	mFinished = false; @@ -2097,6 +2099,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  				decomp,  				mUploadSkin,  				mUploadJoints, +                mLockScaleIfJointPosition,  				FALSE,  				FALSE,  				data.mBaseModel->mSubmodelID); @@ -2255,6 +2258,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)  				decomp,  				mUploadSkin,  				mUploadJoints, +                mLockScaleIfJointPosition,  				FALSE,  				FALSE,  				data.mBaseModel->mSubmodelID); @@ -3946,11 +3950,13 @@ LLSD& LLMeshRepoThread::getMeshHeader(const LLUUID& mesh_id)  void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, -								   bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload, +								   bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, +                                   std::string upload_url, bool do_upload,  								   LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer)  { -	LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, upload_url,  -														do_upload, fee_observer, upload_observer); +	LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, +                                                        upload_skin, upload_joints, lock_scale_if_joint_position,  +                                                        upload_url, do_upload, fee_observer, upload_observer);  	mUploadWaitList.push_back(thread);  } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index a762042597..30f042845a 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -400,6 +400,7 @@ public:  	bool			mUploadTextures;  	bool			mUploadSkin;  	bool			mUploadJoints; +    bool			mLockScaleIfJointPosition;  	volatile bool	mDiscarded;  	LLHost			mHost; @@ -407,7 +408,8 @@ public:  	std::string		mWholeModelUploadURL;  	LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, -					   bool upload_skin, bool upload_joints, const std::string & upload_url, bool do_upload = true, +					   bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, +                       const std::string & upload_url, bool do_upload = true,  					   LLHandle<LLWholeModelFeeObserver> fee_observer = (LLHandle<LLWholeModelFeeObserver>()),  					   LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>()));  	~LLMeshUploadThread(); @@ -510,8 +512,10 @@ public:  	LLSD& getMeshHeader(const LLUUID& mesh_id);  	void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, -			bool upload_skin, bool upload_joints, std::string upload_url, bool do_upload = true, -					 LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); +                     bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, +                     std::string upload_url, bool do_upload = true, +					 LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()),  +                     LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>()));  	S32 getMeshSize(const LLUUID& mesh_id, S32 lod); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 5edc3c9745..db0adad3c0 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -370,7 +370,7 @@ void LLViewerObject::markDead()  		if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))  		{  			// This case is needed for indirectly attached mesh objects. -			av->resetJointPositionsOnDetach(mesh_id); +			av->resetJointsOnDetach(mesh_id);  		}  		// Mark itself as dead diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index e9f00f04fa..7af15fb351 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1860,8 +1860,8 @@ void LLVOAvatar::resetSkeleton()      //LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();      //LLQuaternion pelvis_rot = getJoint("mPelvis")->getRotation(); -    // Clear all attachment pos overrides -    clearAttachmentPosOverrides(); +    // Clear all attachment pos and scale overrides +    clearAttachmentOverrides();      // Note that we call buildSkeleton twice in this function. The first time is      // just to get the right scale for the collision volumes, because @@ -1910,7 +1910,7 @@ void LLVOAvatar::resetSkeleton()      updateVisualParams();      // Restore attachment pos overrides -    rebuildAttachmentPosOverrides(); +    rebuildAttachmentOverrides();      LL_DEBUGS("Avatar") << avString() << " reset ends" << LL_ENDL;  } @@ -5422,9 +5422,9 @@ bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name, const LLViewerOb      return false;  } -void LLVOAvatar::clearAttachmentPosOverrides() +void LLVOAvatar::clearAttachmentOverrides()  { -    LLScopedContextString str("clearAttachmentPosOverrides " + getFullname()); +    LLScopedContextString str("clearAttachmentOverrides " + getFullname());  	//Subsequent joints are relative to pelvis  	avatar_joint_list_t::iterator iter = mSkeleton.begin(); @@ -5437,6 +5437,10 @@ void LLVOAvatar::clearAttachmentPosOverrides()  		{  			pJoint->clearAttachmentPosOverrides();  		} +		if (pJoint) +		{ +			pJoint->clearAttachmentScaleOverrides(); +		}  	}      // Attachment points @@ -5453,11 +5457,11 @@ void LLVOAvatar::clearAttachmentPosOverrides()  }  //----------------------------------------------------------------------------- -// rebuildAttachmentPosOverrides +// rebuildAttachmentOverrides  //----------------------------------------------------------------------------- -void LLVOAvatar::rebuildAttachmentPosOverrides() +void LLVOAvatar::rebuildAttachmentOverrides()  { -    LLScopedContextString str("rebuildAttachmentPosOverrides " + getFullname()); +    LLScopedContextString str("rebuildAttachmentOverrides " + getFullname());      // Attachment points  	for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); @@ -5470,7 +5474,7 @@ void LLVOAvatar::rebuildAttachmentPosOverrides()              for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();  				 at_it != attachment_pt->mAttachedObjects.end(); ++at_it)              { -                addAttachmentPosOverridesForObject(*at_it); +                addAttachmentOverridesForObject(*at_it);              }          }      } @@ -5478,7 +5482,7 @@ void LLVOAvatar::rebuildAttachmentPosOverrides()  //-----------------------------------------------------------------------------  // addAttachmentPosOverridesForObject  //----------------------------------------------------------------------------- -void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo) +void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)  {  	LLVOAvatar *av = vo->getAvatarAncestor();  	if (!av || (av != this)) @@ -5486,7 +5490,7 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)  		LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;  	} -    LLScopedContextString str("addAttachmentPosOverridesForObject " + av->getFullname()); +    LLScopedContextString str("addAttachmentOverridesForObject " + av->getFullname());  	// Process all children  	LLViewerObject::const_child_list_t& children = vo->getChildren(); @@ -5494,7 +5498,7 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)  		 it != children.end(); ++it)  	{  		LLViewerObject *childp = *it; -		addAttachmentPosOverridesForObject(childp); +		addAttachmentOverridesForObject(childp);  	}  	LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo); @@ -5535,19 +5539,26 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)  					{   									  						pJoint->setId( currentId );  						const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();									 - -                        bool override_changed; -                        pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed ); - -                        if (override_changed) +                        if (pJoint->aboveJointPosThreshold(jointPos))                          { -                            //If joint is a pelvis then handle old/new pelvis to foot values -                            if ( lookingForJoint == "mPelvis" ) -                            {	 -                                pelvisGotSet = true;											 -                            }										 -                        } +                            bool override_changed; +                            pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed ); +                            if (override_changed) +                            { +                                //If joint is a pelvis then handle old/new pelvis to foot values +                                if ( lookingForJoint == "mPelvis" ) +                                {	 +                                    pelvisGotSet = true;											 +                                }										 +                            } +                            if (pSkinData->mLockScaleIfJointPosition) +                            { +                                // Note that unlike positions, there's no threshold check here, +                                // just a lock at the default value. +                                pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), mesh_id, avString()); +                            } +                        }  					}										  				}																  				if (pelvisZOffset != 0.0F) @@ -5577,9 +5588,10 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)  //-----------------------------------------------------------------------------  // getAttachmentOverrideNames  //----------------------------------------------------------------------------- -void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& names) const +void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& pos_names, std::set<std::string>& scale_names) const  {      LLVector3 pos; +    LLVector3 scale;      LLUUID mesh_id;      // Bones @@ -5589,7 +5601,11 @@ void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& names) const  		const LLJoint* pJoint = (*iter);  		if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))  		{ -            names.insert(pJoint->getName()); +            pos_names.insert(pJoint->getName()); +		} +		if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) +		{ +            scale_names.insert(pJoint->getName());  		}  	} @@ -5601,36 +5617,47 @@ void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& names) const  		const LLViewerJointAttachment *attachment_pt = (*iter).second;          if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id))          { -            names.insert(attachment_pt->getName()); +            pos_names.insert(attachment_pt->getName());          } +        // Attachment points don't have scales.      }  }  //----------------------------------------------------------------------------- -// showAttachmentPosOverrides +// showAttachmentOverrides  //----------------------------------------------------------------------------- -void LLVOAvatar::showAttachmentPosOverrides(bool verbose) const +void LLVOAvatar::showAttachmentOverrides(bool verbose) const  { -    std::set<std::string> joint_names; -    getAttachmentOverrideNames(joint_names); -    if (joint_names.size()) +    std::set<std::string> pos_names, scale_names; +    getAttachmentOverrideNames(pos_names, scale_names); +    if (pos_names.size())      {          std::stringstream ss; -        std::copy(joint_names.begin(), joint_names.end(), std::ostream_iterator<std::string>(ss, ",")); -        LL_DEBUGS("Avatar") << getFullname() << " attachment positions defined for joints: " << ss.str() << "\n" << LL_ENDL; +        std::copy(pos_names.begin(), pos_names.end(), std::ostream_iterator<std::string>(ss, ",")); +        LL_INFOS() << getFullname() << " attachment positions defined for joints: " << ss.str() << "\n" << LL_ENDL;      }      else      {          LL_DEBUGS("Avatar") << getFullname() << " no attachment positions defined for any joints" << "\n" << LL_ENDL;      } +    if (scale_names.size()) +    { +        std::stringstream ss; +        std::copy(scale_names.begin(), scale_names.end(), std::ostream_iterator<std::string>(ss, ",")); +        LL_INFOS() << getFullname() << " attachment scales defined for joints: " << ss.str() << "\n" << LL_ENDL; +    } +    else +    { +        LL_INFOS() << getFullname() << " no attachment scales defined for any joints" << "\n" << LL_ENDL; +    }      if (!verbose)      {          return;      } -    LLVector3 pos; +    LLVector3 pos, scale;      LLUUID mesh_id;      S32 count = 0; @@ -5644,6 +5671,11 @@ void LLVOAvatar::showAttachmentPosOverrides(bool verbose) const  			pJoint->showAttachmentPosOverrides(getFullname());              count++;  		} +		if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id)) +		{ +			pJoint->showAttachmentScaleOverrides(getFullname()); +            count++; +        }  	}      // Attachment points @@ -5661,15 +5693,15 @@ void LLVOAvatar::showAttachmentPosOverrides(bool verbose) const      if (count)      { -        LL_DEBUGS("Avatar") << avString() << " end of pos overrides" << LL_ENDL; +        LL_DEBUGS("Avatar") << avString() << " end of pos, scale overrides" << LL_ENDL;          LL_DEBUGS("Avatar") << "=================================" << LL_ENDL;      }  }  //----------------------------------------------------------------------------- -// resetJointPositionsOnDetach +// resetJointsOnDetach  //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo) +void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo)  {  	LLVOAvatar *av = vo->getAvatarAncestor();  	if (!av || (av != this)) @@ -5683,21 +5715,21 @@ void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo)  		 it != children.end(); ++it)  	{  		LLViewerObject *childp = *it; -		resetJointPositionsOnDetach(childp); +		resetJointsOnDetach(childp);  	}  	// Process self.  	LLUUID mesh_id;  	if (getRiggedMeshID(vo,mesh_id))  	{ -		resetJointPositionsOnDetach(mesh_id); +		resetJointsOnDetach(mesh_id);  	}  }  //----------------------------------------------------------------------------- -// resetJointPositionsOnDetach +// resetJointsOnDetach  //----------------------------------------------------------------------------- -void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id) +void LLVOAvatar::resetJointsOnDetach(const LLUUID& mesh_id)  {	  	//Subsequent joints are relative to pelvis  	avatar_joint_list_t::iterator iter = mSkeleton.begin(); @@ -5713,7 +5745,8 @@ void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id)  		{			              bool dummy; // unused  			pJoint->setId( LLUUID::null ); -			pJoint->removeAttachmentPosOverride(mesh_id, avString(), dummy); +			pJoint->removeAttachmentPosOverride(mesh_id, avString(),dummy); +			pJoint->removeAttachmentScaleOverride(mesh_id, avString());  		}		  		if ( pJoint && pJoint == pJointPelvis)  		{ @@ -6414,7 +6447,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )  	LLUUID mesh_id;  	if (getRiggedMeshID(pVO, mesh_id))  	{ -		resetJointPositionsOnDetach(mesh_id); +		resetJointsOnDetach(mesh_id);  		if ( gAgentCamera.cameraCustomizeAvatar() )  		{  			gAgent.unpauseAnimation(); @@ -8448,6 +8481,20 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara  								 pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str());  			}  		} +        // Joint scale overrides +		for (iter = mSkeleton.begin(); iter != end; ++iter) +		{ +			LLJoint* pJoint = (*iter); +		 +			LLVector3 scale; +			LLUUID mesh_id; + +			if (pJoint->hasAttachmentScaleOverride(scale,mesh_id)) +			{ +				apr_file_printf( file, "\t\t<joint_scale name=\"%s\" scale=\"%f %f %f\" mesh_id=\"%s\"/>\n",  +								 pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str()); +			} +		}  		F32 pelvis_fixup;  		LLUUID mesh_id;  		if (hasPelvisFixup(pelvis_fixup, mesh_id)) diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index b67aa62b06..64171e7243 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -200,15 +200,16 @@ public:  	virtual LLJoint*		getJoint(const std::string &name); -	void 					addAttachmentPosOverridesForObject(LLViewerObject *vo); -	void					resetJointPositionsOnDetach(const LLUUID& mesh_id); -	void					resetJointPositionsOnDetach(LLViewerObject *vo); +	void 					addAttachmentOverridesForObject(LLViewerObject *vo); +	void					resetJointsOnDetach(const LLUUID& mesh_id); +	void					resetJointsOnDetach(LLViewerObject *vo);      bool					jointIsRiggedTo(const std::string& joint_name);      bool					jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo); -	void					clearAttachmentPosOverrides(); -	void					rebuildAttachmentPosOverrides(); -    void                    showAttachmentPosOverrides(bool verbose = false) const; -    void                    getAttachmentOverrideNames(std::set<std::string>& names) const; +	void					clearAttachmentOverrides(); +	void					rebuildAttachmentOverrides(); +    void                    showAttachmentOverrides(bool verbose = false) const; +    void                    getAttachmentOverrideNames(std::set<std::string>& pos_names,  +                                                       std::set<std::string>& scale_names) const;  	/*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 c9cd2fd27a..6d3e2e4a39 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4778,11 +4778,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)              if (rigged && pAvatarVO)              { -                pAvatarVO->addAttachmentPosOverridesForObject(vobj); +                pAvatarVO->addAttachmentOverridesForObject(vobj);  				if (pAvatarVO->isSelf())  				{                      bool verbose = true; -					pAvatarVO->showAttachmentPosOverrides(verbose); +					pAvatarVO->showAttachmentOverrides(verbose);  				}              } diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index d2c8dddfe1..2750316f2e 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -1217,6 +1217,13 @@               label_text.text_color="White"               name="upload_joints"               top_pad="15"/> +           <check_box +             follows="top|left" +             height="15" +             label="Lock scale if joint position defined" +             label_text.text_color="White" +             name="lock_scale_if_joint_position" +             top_pad="15"/>             <text               follows="top|left"               height="15" | 
