diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2018-04-13 14:28:19 +0100 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2018-04-13 14:28:19 +0100 |
commit | f7134144a6ed8f5710d02a84ad3ad5dc29cb0bd5 (patch) | |
tree | 74e5b64a835e388f7dcc4ff66133a8c226b00d8c | |
parent | cc73a1958d14be9094c4bc301e61ed45f4c575e8 (diff) |
MAINT-8239 - joint offsets
-rw-r--r-- | indra/llcharacter/lljoint.h | 10 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 177 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 5 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 16 |
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: |