summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2017-06-28 22:17:28 +0100
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2017-06-28 22:17:28 +0100
commitc2280848e1714329172ea4c0881993aa62f3cd8f (patch)
tree1687e83ef585aca008882df413a3d4491dc7226c /indra/newview
parent0b57379b127b9ef5f925f52176544ac8f447ce1f (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.cpp1
-rw-r--r--indra/newview/llviewerobject.h2
-rw-r--r--indra/newview/llvovolume.cpp107
-rw-r--r--indra/newview/llvovolume.h2
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