summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2018-04-13 14:28:19 +0100
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2018-04-13 14:28:19 +0100
commitf7134144a6ed8f5710d02a84ad3ad5dc29cb0bd5 (patch)
tree74e5b64a835e388f7dcc4ff66133a8c226b00d8c
parentcc73a1958d14be9094c4bc301e61ed45f4c575e8 (diff)
MAINT-8239 - joint offsets
-rw-r--r--indra/llcharacter/lljoint.h10
-rw-r--r--indra/newview/llviewerobject.cpp6
-rw-r--r--indra/newview/llvoavatar.cpp177
-rw-r--r--indra/newview/llvoavatar.h5
-rw-r--r--indra/newview/llvovolume.cpp16
5 files changed, 184 insertions, 30 deletions
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index 0c8fbfebb0..8112d246f2 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -70,6 +70,16 @@ private:
map_type m_map;
};
+inline bool operator==(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b)
+{
+ return a.getMap() == b.getMap();
+}
+
+inline bool operator!=(const LLVector3OverrideMap& a, const LLVector3OverrideMap& b)
+{
+ return !(a == b);
+}
+
//-----------------------------------------------------------------------------
// class LLJoint
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 9446e5ddac..72cb1d4cf6 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -394,7 +394,7 @@ void LLViewerObject::markDead()
if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
{
// This case is needed for indirectly attached mesh objects.
- av->rebuildAttachmentOverrides();
+ av->updateAttachmentOverrides();
}
}
if (getControlAvatar())
@@ -3010,7 +3010,7 @@ void LLViewerObject::linkControlAvatar()
}
if (getControlAvatar())
{
- getControlAvatar()->rebuildAttachmentOverrides();
+ getControlAvatar()->updateAttachmentOverrides();
getControlAvatar()->updateAnimations();
getControlAvatar()->mPlaying = true;
}
@@ -3024,7 +3024,7 @@ void LLViewerObject::unlinkControlAvatar()
{
if (getControlAvatar())
{
- getControlAvatar()->rebuildAttachmentOverrides();
+ getControlAvatar()->updateAttachmentOverrides();
}
if (isRootEdit())
{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 810fcdce1e..b8646d42e7 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -742,8 +742,15 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
std::string LLVOAvatar::avString() const
{
- std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
- return " Avatar '" + getFullname() + "' " + viz_string + " ";
+ if (isControlAvatar())
+ {
+ return getFullname();
+ }
+ else
+ {
+ std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
+ return " Avatar '" + getFullname() + "' " + viz_string + " ";
+ }
}
void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment)
@@ -1952,7 +1959,7 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
updateVisualParams();
// Restore attachment pos overrides
- rebuildAttachmentOverrides();
+ updateAttachmentOverrides();
// Animations
if (reset_animations)
@@ -5867,9 +5874,134 @@ void LLVOAvatar::rebuildAttachmentOverrides()
}
//-----------------------------------------------------------------------------
+// updateAttachmentOverrides
+//
+// This is intended to give the same results as
+// rebuildAttachmentOverrides(), while avoiding redundant work.
+// -----------------------------------------------------------------------------
+void LLVOAvatar::updateAttachmentOverrides()
+{
+ const bool paranoid_checking = false; // AXON remove when testing done
+
+ if (paranoid_checking)
+ {
+ //dumpArchetypeXML(getFullname() + "_paranoid_before");
+ }
+
+ LLScopedContextString str("updateAttachmentOverrides " + getFullname());
+
+ LL_DEBUGS("AnimatedObjects") << "updating" << LL_ENDL;
+ dumpStack("AnimatedObjectsStack");
+
+ std::set<LLUUID> meshes_seen;
+
+ // Handle the case that we're updating the skeleton of an animated object.
+ LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this);
+ if (control_av)
+ {
+ LLVOVolume *volp = control_av->mRootVolp;
+ if (volp)
+ {
+ LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count "
+ << (S32) (1+volp->numChildren()) << LL_ENDL;
+ addAttachmentOverridesForObject(volp, &meshes_seen);
+ }
+ }
+
+ // Attached objects
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment *attachment_pt = (*iter).second;
+ if (attachment_pt)
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = attachment_pt->mAttachedObjects.begin();
+ at_it != attachment_pt->mAttachedObjects.end(); ++at_it)
+ {
+ LLViewerObject *vo = *at_it;
+ // Attached animated objects affect joints in their control
+ // avs, not the avs to which they are attached.
+ if (!vo->isAnimatedObject())
+ {
+ addAttachmentOverridesForObject(vo, &meshes_seen);
+ }
+ }
+ }
+ }
+ // Remove meshes that are no longer present on the skeleton
+
+ // have to work with a copy because removeAttachmentOverrides() will change mActiveOverrideMeshes.
+ std::set<LLUUID> active_override_meshes = mActiveOverrideMeshes;
+ for (std::set<LLUUID>::iterator it = active_override_meshes.begin(); it != active_override_meshes.end(); ++it)
+ {
+ if (meshes_seen.find(*it) == meshes_seen.end())
+ {
+ removeAttachmentOverridesForObject(*it);
+ }
+ }
+
+
+ if (paranoid_checking)
+ {
+ std::vector<LLVector3OverrideMap> pos_overrides_by_joint;
+ std::vector<LLVector3OverrideMap> scale_overrides_by_joint;
+ LLVector3OverrideMap pelvis_fixups;
+
+ // Capture snapshot of override state after update
+ for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
+ {
+ LLVector3OverrideMap pos_overrides;
+ LLJoint *joint = getJoint(joint_num);
+ if (joint)
+ {
+ pos_overrides_by_joint.push_back(joint->m_attachmentPosOverrides);
+ scale_overrides_by_joint.push_back(joint->m_attachmentScaleOverrides);
+ }
+ else
+ {
+ // No joint, use default constructed empty maps
+ pos_overrides_by_joint.push_back(LLVector3OverrideMap());
+ scale_overrides_by_joint.push_back(LLVector3OverrideMap());
+ }
+ }
+ pelvis_fixups = mPelvisFixups;
+ //dumpArchetypeXML(getFullname() + "_paranoid_updated");
+
+ // Rebuild and compare
+ rebuildAttachmentOverrides();
+ //dumpArchetypeXML(getFullname() + "_paranoid_rebuilt");
+ bool mismatched = false;
+ for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
+ {
+ LLJoint *joint = getJoint(joint_num);
+ if (joint)
+ {
+ if (pos_overrides_by_joint[joint_num] != joint->m_attachmentPosOverrides)
+ {
+ mismatched = true;
+ }
+ if (scale_overrides_by_joint[joint_num] != joint->m_attachmentScaleOverrides)
+ {
+ mismatched = true;
+ }
+ }
+ }
+ if (pelvis_fixups != mPelvisFixups)
+ {
+ mismatched = true;
+ }
+ if (mismatched)
+ {
+ LL_WARNS() << "MISMATCHED ATTACHMENT OVERRIDES, compare paranoid log files" << LL_ENDL;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
// addAttachmentOverridesForObject
//-----------------------------------------------------------------------------
-void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
+void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LLUUID>* meshes_seen, bool recursive)
{
if (vo->getAvatar() != this && vo->getAvatarAncestor() != this)
{
@@ -5883,13 +6015,16 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
dumpStack("AnimatedObjectsStack");
// Process all children
- LLViewerObject::const_child_list_t& children = vo->getChildren();
- for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
- it != children.end(); ++it)
- {
- LLViewerObject *childp = *it;
- addAttachmentOverridesForObject(childp);
- }
+ if (recursive)
+ {
+ LLViewerObject::const_child_list_t& children = vo->getChildren();
+ for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
+ it != children.end(); ++it)
+ {
+ LLViewerObject *childp = *it;
+ addAttachmentOverridesForObject(childp, meshes_seen, true);
+ }
+ }
LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo);
bool pelvisGotSet = false;
@@ -5922,6 +6057,10 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
const F32 pelvisZOffset = pSkinData->mPelvisOffset;
const LLUUID& mesh_id = pSkinData->mMeshID;
+ if (meshes_seen)
+ {
+ meshes_seen->insert(mesh_id);
+ }
bool mesh_overrides_loaded = (mActiveOverrideMeshes.find(mesh_id) != mActiveOverrideMeshes.end());
if (mesh_overrides_loaded)
{
@@ -6151,15 +6290,17 @@ void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id)
LLJoint* pJointPelvis = getJoint("mPelvis");
- for (; iter != end; ++iter)
- {
- LLJoint* pJoint = (*iter);
+ const std::string av_string = avString();
+
+ for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
+ {
+ LLJoint *pJoint = getJoint(joint_num);
//Reset joints except for pelvis
if ( pJoint )
{
bool dummy; // unused
- pJoint->removeAttachmentPosOverride(mesh_id, avString(),dummy);
- pJoint->removeAttachmentScaleOverride(mesh_id, avString());
+ pJoint->removeAttachmentPosOverride(mesh_id, av_string, dummy);
+ pJoint->removeAttachmentScaleOverride(mesh_id, av_string);
}
if ( pJoint && pJoint == pJointPelvis)
{
@@ -6730,7 +6871,7 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o
if (!viewer_object->isAnimatedObject())
{
- rebuildAttachmentOverrides();
+ updateAttachmentOverrides();
}
updateVisualComplexity();
@@ -6939,7 +7080,7 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
attachment->removeObject(viewer_object);
if (!is_animated_object)
{
- rebuildAttachmentOverrides();
+ updateAttachmentOverrides();
}
LL_DEBUGS() << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << LL_ENDL;
return TRUE;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 92ea40affd..f00f855160 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -203,14 +203,15 @@ public:
virtual LLJoint* getJoint(const std::string &name);
LLJoint* getJoint(S32 num);
-
- void addAttachmentOverridesForObject(LLViewerObject *vo);
+
+ void addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LLUUID>* meshes_seen = NULL, bool recursive = true);
void removeAttachmentOverridesForObject(const LLUUID& mesh_id);
void removeAttachmentOverridesForObject(LLViewerObject *vo);
bool jointIsRiggedTo(const std::string& joint_name);
bool jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo);
void clearAttachmentOverrides();
void rebuildAttachmentOverrides();
+ void updateAttachmentOverrides();
void showAttachmentOverrides(bool verbose = false) const;
void getAttachmentOverrideNames(std::set<std::string>& pos_names,
std::set<std::string>& scale_names) const;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 9d0f300bac..ba733f9387 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3427,12 +3427,12 @@ void LLVOVolume::onSetExtendedMeshFlags(U32 flags)
if (flags & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG)
{
// Making a rigged mesh into an animated object
- getAvatarAncestor()->rebuildAttachmentOverrides();
+ getAvatarAncestor()->updateAttachmentOverrides();
}
else
{
// Making an animated object into a rigged mesh
- getAvatarAncestor()->rebuildAttachmentOverrides();
+ getAvatarAncestor()->updateAttachmentOverrides();
}
}
}
@@ -3501,7 +3501,7 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare
if (old_volp->getControlAvatar())
{
// We have been removed from an animated object, need to do cleanup.
- old_volp->getControlAvatar()->rebuildAttachmentOverrides();
+ old_volp->getControlAvatar()->updateAttachmentOverrides();
old_volp->getControlAvatar()->updateAnimations();
}
}
@@ -3919,8 +3919,8 @@ F32 LLVOVolume::getStreamingCost(S32* bytes, S32* visible_bytes, F32* unscaled_v
F32 radius = getScale().length()*0.5f;
// AXON make sure this is consistent with the final simulator-side values.
- const F32 ANIMATED_OBJECT_BASE_COST = 15.0f; // placeholder
- const F32 ANIMATED_OBJECT_COST_PER_KTRI = 1.5f; //placeholder
+ const F32 ANIMATED_OBJECT_BASE_COST = 15.0f;
+ const F32 ANIMATED_OBJECT_COST_PER_KTRI = 1.5f;
F32 linkset_base_cost = 0.f;
if (isAnimatedObject() && isRootEdit())
@@ -5152,9 +5152,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
drawablep->clearState(LLDrawable::HAS_ALPHA);
- if (vobj->isRiggedMesh() && vobj->getAvatar())
+ if (vobj->isRiggedMesh() &&
+ ((vobj->isAnimatedObject() && vobj->getControlAvatar()) ||
+ (!vobj->isAnimatedObject() && vobj->getAvatar())))
{
- vobj->getAvatar()->addAttachmentOverridesForObject(vobj);
+ vobj->getAvatar()->addAttachmentOverridesForObject(vobj, NULL, false);
}
// Standard rigged mesh attachments: