summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llappearance/llavatarappearance.cpp1
-rw-r--r--indra/llappearance/llavatarappearance.h2
-rw-r--r--indra/llappearance/llpolyskeletaldistortion.cpp2
-rw-r--r--indra/llcharacter/lljoint.cpp232
-rw-r--r--indra/llcharacter/lljoint.h31
-rw-r--r--indra/llprimitive/lldaeloader.cpp33
-rw-r--r--indra/llprimitive/llmodel.cpp27
-rw-r--r--indra/llprimitive/llmodel.h11
-rw-r--r--indra/newview/llappearancemgr.cpp4
-rw-r--r--indra/newview/llfloatermodelpreview.cpp57
-rw-r--r--indra/newview/llfloatermodelpreview.h4
-rw-r--r--indra/newview/llmeshrepository.cpp14
-rw-r--r--indra/newview/llmeshrepository.h10
-rw-r--r--indra/newview/llviewerobject.cpp2
-rw-r--r--indra/newview/llvoavatar.cpp133
-rw-r--r--indra/newview/llvoavatar.h15
-rw-r--r--indra/newview/llvovolume.cpp4
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml7
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"