diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2017-06-28 22:17:28 +0100 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2017-06-28 22:17:28 +0100 |
commit | c2280848e1714329172ea4c0881993aa62f3cd8f (patch) | |
tree | 1687e83ef585aca008882df413a3d4491dc7226c /indra/newview | |
parent | 0b57379b127b9ef5f925f52176544ac8f447ce1f (diff) |
SL-722 - work on support for animated object state when linkset-altering operations take place
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llviewerobject.cpp | 1 | ||||
-rw-r--r-- | indra/newview/llviewerobject.h | 2 | ||||
-rw-r--r-- | indra/newview/llvovolume.cpp | 107 | ||||
-rw-r--r-- | indra/newview/llvovolume.h | 2 |
4 files changed, 108 insertions, 4 deletions
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 06efb1bc3a..9a6153d3e6 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -377,7 +377,6 @@ void LLViewerObject::markDead() ((LLViewerObject *)getParent())->removeChild(this); } LLUUID mesh_id; - // FIXME AXON - need to do this for control avatars too if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id)) { // This case is needed for indirectly attached mesh objects. diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bef00e2bab..1967841fd9 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -694,7 +694,7 @@ public: // Remove any reference to control av for this prim void unlinkControlAvatar(); -private: +protected: LLPointer<LLControlAvatar> mControlAvatar; protected: diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index da24d9f9c2..b22d1c45a8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1391,7 +1391,8 @@ void LLVOVolume::updateFaceFlags() BOOL LLVOVolume::setParent(LLViewerObject* parent) { BOOL ret = FALSE ; - if (parent != getParent()) + LLViewerObject *old_parent = (LLViewerObject*) getParent(); + if (parent != old_parent) { ret = LLViewerObject::setParent(parent); if (ret && mDrawable) @@ -1399,6 +1400,7 @@ BOOL LLVOVolume::setParent(LLViewerObject* parent) gPipeline.markMoved(mDrawable); gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); } + updateAnimatedObjectState(old_parent, parent); } return ret ; @@ -3328,7 +3330,108 @@ bool LLVOVolume::canBeAnimatedObject() const bool LLVOVolume::isAnimatedObject() const { - return canBeAnimatedObject() && (getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG); + LLVOVolume *root_vol = (LLVOVolume*)getRootEdit(); + bool can_be_animated = canBeAnimatedObject(); + bool root_can_be_animated = root_vol->canBeAnimatedObject(); + bool root_is_animated = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; + if (can_be_animated && root_can_be_animated && root_is_animated) + { + return true; + } + return false; +} + +// Make sure animated objects in a linkset are consistent. The rules are: +// Only the root of a linkset can have the animated object flag set +// Only the root of a linkset can have a control avatar (iff the animated object flag is set) +// Only skinned mesh volumes can have the animated object flag set, or a control avatar +bool LLVOVolume::isAnimatedObjectStateConsistent() const +{ + if (!canBeAnimatedObject()) + { + if ((getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG) || + mControlAvatar.notNull()) + { + LL_WARNS("AXON") << "Non animatable object has mesh enabled flag or mControlAvatar. Flags " + << getExtendedMeshFlags() << " cav " << mControlAvatar.get() << LL_ENDL; + return false; + } + } + if (!isRootEdit()) + { + if ((getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG) || + mControlAvatar.notNull()) + { + LL_WARNS("AXON") << "Non root object has mesh enabled flag or mControlAvatar. Flags " + << getExtendedMeshFlags() << " cav " << mControlAvatar.get() << LL_ENDL; + return false; + } + } + // If we get here, we have a potentially animatable root volume. + bool is_animation_enabled = getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; + bool has_control_avatar = (mControlAvatar.notNull()); + if (is_animation_enabled != has_control_avatar) + { + LL_WARNS("AXON") << "Inconsistent state: animation enabled " << is_animation_enabled + << " has control avatar " << has_control_avatar + << " flags " << getExtendedMeshFlags() << " cav " << mControlAvatar.get() << LL_ENDL; + return false; + } + return true; +} + +// Called any time parenting changes for a volume. Update flags and +// control av accordingly. This is called after parent has been +// changed to new_parent. +void LLVOVolume::updateAnimatedObjectState(LLViewerObject *old_parent, LLViewerObject *new_parent) +{ + LLVOVolume *old_volp = dynamic_cast<LLVOVolume*>(old_parent); + LLVOVolume *new_volp = dynamic_cast<LLVOVolume*>(new_parent); + + if (new_parent) + { + // Object should inherit control avatar and animated mesh flag + // from parent, so clear them out from our own state + if (getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG) + { + setExtendedMeshFlags(getExtendedMeshFlags() & ~LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG); + } + if (mControlAvatar.notNull()) + { + LLControlAvatar *av = mControlAvatar; + mControlAvatar = NULL; + av->markForDeath(); + } + // If this succeeds now, it's because the new_parent is an animated object + if (isAnimatedObject()) + { + getControlAvatar()->addAttachmentOverridesForObject(this); + } + } + if (old_volp && old_volp->isAnimatedObject()) + { + // W have been removed from an animated object, need to do cleanup. + old_volp->getControlAvatar()->resetJointsOnDetach(this); + } + + if (old_volp) + { + if (!old_volp->isAnimatedObjectStateConsistent()) + { + LL_WARNS("AXON") << "old_volp failed consistency check" << LL_ENDL; + } + } + if (new_volp) + { + if (!new_volp->isAnimatedObjectStateConsistent()) + { + LL_WARNS("AXON") << "new_volp failed consistency check" << LL_ENDL; + } + } + if (!isAnimatedObjectStateConsistent()) + { + LL_WARNS("AXON") << "child object failed consistency check" << LL_ENDL; + } } //---------------------------------------------------------------------------- diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 75dabd961a..27a51d100f 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -271,6 +271,8 @@ public: void setExtendedMeshFlags(U32 flags); bool canBeAnimatedObject() const; bool isAnimatedObject() const; + bool isAnimatedObjectStateConsistent() const; + void updateAnimatedObjectState(LLViewerObject *old_parent, LLViewerObject *new_parent); // Functions that deal with media, or media navigation |