summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2017-09-08 16:05:49 +0100
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2017-09-08 16:05:49 +0100
commit2aa890da0bd8b42493745daa736c5ed9451bbf91 (patch)
treeff1af773b8300a7e804c4bb90d3ef2a2e59ab8ba
parent943a1f3e802ee75683266a9a5d24ae4610207232 (diff)
SL-718 - better support for transforms of animated attachments
-rw-r--r--indra/newview/llcontrolavatar.cpp46
-rw-r--r--indra/newview/lldrawable.cpp5
-rw-r--r--indra/newview/llviewerobject.cpp9
-rw-r--r--indra/newview/llviewerobjectlist.cpp6
-rw-r--r--indra/newview/llvoavatar.cpp59
-rw-r--r--indra/newview/llvoavatar.h2
6 files changed, 89 insertions, 38 deletions
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index d458e2951b..172816b3e3 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -50,6 +50,8 @@ LLControlAvatar::~LLControlAvatar()
void LLControlAvatar::matchVolumeTransform()
{
+#if 0
+ // AXON - should we be using bind_shape?
{
LLVolume *volume = mRootVolp->getVolume();
if (volume)
@@ -63,16 +65,40 @@ void LLControlAvatar::matchVolumeTransform()
}
}
}
-
- setPositionAgent(mRootVolp->getRenderPosition());
- //slamPosition();
-
- LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1));
- LLQuaternion obj_rot = mRootVolp->getRotation();
- LLQuaternion result_rot = fix_axes_rot * obj_rot;
- setRotation(result_rot);
- mRoot->setWorldRotation(result_rot);
- mRoot->setPosition(mRootVolp->getRenderPosition());
+#endif
+
+
+ if (mRootVolp)
+ {
+ if (mRootVolp->isAttachment())
+ {
+ LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
+ if (attached_av)
+ {
+ LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp);
+ setPositionAgent(mRootVolp->getRenderPosition());
+ LLVector3 pos = attach->getParent()->getWorldPosition();
+ mRoot->setWorldPosition(pos);
+ mRoot->setRotation(attach->getParent()->getWorldRotation());
+ }
+ else
+ {
+ LL_WARNS_ONCE() << "can't find attached av!" << LL_ENDL;
+ }
+ }
+ else
+ {
+ setPositionAgent(mRootVolp->getRenderPosition());
+ //slamPosition();
+
+ LLQuaternion fix_axes_rot(-F_PI_BY_TWO, LLVector3(0,0,1));
+ LLQuaternion obj_rot = mRootVolp->getRotation();
+ LLQuaternion result_rot = fix_axes_rot * obj_rot;
+ setRotation(result_rot);
+ mRoot->setWorldRotation(result_rot);
+ mRoot->setPosition(mRootVolp->getRenderPosition());
+ }
+ }
}
void LLControlAvatar::setGlobalScale(F32 scale)
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 8001486b53..6799c3f862 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -698,11 +698,6 @@ F32 LLDrawable::updateXform(BOOL undamped)
mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
mXform.updateMatrix();
- if (mVObjp && mVObjp->isRootEdit() && mVObjp->getControlAvatar())
- {
- mVObjp->getControlAvatar()->matchVolumeTransform();
- }
-
if (mSpatialBridge)
{
gPipeline.markMoved(mSpatialBridge, FALSE);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index e2fbac023a..34e7bc0fad 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5188,10 +5188,15 @@ LLVOAvatar* LLViewerObject::asAvatar()
return NULL;
}
-// If this object is directly or indirectly parented by an avatar, return it.
+// If this object is directly or indirectly parented by an avatar,
+// return it. Normally getAvatar() is the correct function to call;
+// it will give the avatar used for skinning. The exception is with
+// animated objects that are also attachments; in that case,
+// getAvatar() will return the control avatar, used for skinning, and
+// getAvatarAncestor will return the avatar to which the object is
+// attached.
LLVOAvatar* LLViewerObject::getAvatarAncestor()
{
- LL_ERRS("AXON") << "this method has been targetted for termination. Use getAvatar()." << LL_ENDL;
LLViewerObject *pobj = (LLViewerObject*) getParent();
while (pobj)
{
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 1f99119d82..63e6560d98 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -862,8 +862,8 @@ void LLViewerObjectList::update(LLAgent &agent)
{
if (idle_count >= idle_list.size())
{
- idle_list.push_back( objectp );
- }
+ idle_list.push_back( objectp );
+ }
else
{
idle_list[idle_count] = objectp;
@@ -900,7 +900,7 @@ void LLViewerObjectList::update(LLAgent &agent)
{
objectp = *idle_iter;
llassert(objectp->isActive());
- objectp->idleUpdate(agent, frame_time);
+ objectp->idleUpdate(agent, frame_time);
}
//update flexible objects
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index eab5206828..34ca69d6e0 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -110,6 +110,8 @@
#include "llcallstack.h"
#include "llrendersphere.h"
+#include <boost/lexical_cast.hpp>
+
extern F32 SPEED_ADJUST_MAX;
extern F32 SPEED_ADJUST_MAX_SEC;
extern F32 ANIM_SPEED_MAX;
@@ -3518,6 +3520,17 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
BOOL visible = isVisible();
+ bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing
+ bool is_attachment = false;
+ if (is_control_avatar)
+ {
+ LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
+ is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects
+ }
+
+ LLScopedContextString str("updateCharacter " + getFullname() + " is_control_avatar "
+ + boost::lexical_cast<std::string>(is_control_avatar)
+ + " is_attachment " + boost::lexical_cast<std::string>(is_attachment));
// For fading out the names above heads, only let the timer
// run if we're visible.
@@ -3532,21 +3545,25 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
bool visually_muted = isVisuallyMuted();
// AXON FIXME this expression is a crawling horror
- if (mDrawable.notNull() && visible && (!isSelf() || visually_muted) &&
- !mIsDummy && sUseImpostors && !mNeedsAnimUpdate && !sFreezeCounter)
+ if (mDrawable.notNull()
+ && visible
+ && (!isSelf() || visually_muted) // AXON would the self ever be visually muted?
+ && !mIsDummy
+ && sUseImpostors
+ && !mNeedsAnimUpdate
+ && !sFreezeCounter)
{
const LLVector4a* ext = mDrawable->getSpatialExtents();
LLVector4a size;
size.setSub(ext[1],ext[0]);
F32 mag = size.getLength3().getF32()*0.5f;
-
F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
if (visually_muted)
{ // visually muted avatars update at 16 hz
mUpdatePeriod = 16;
}
- else if ( ! shouldImpostor()
+ else if (! shouldImpostor()
|| mDrawable->mDistanceWRTCamera < 1.f + mag)
{ // first 25% of max visible avatars are not impostored
// also, don't impostor avatars whose bounding box may be penetrating the
@@ -3590,7 +3607,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
// change animation time quanta based on avatar render load
// AXON how should control avs be handled here?
- bool is_pure_dummy = mIsDummy && !isControlAvatar();
+ bool is_pure_dummy = mIsDummy && !is_control_avatar;
if (!isSelf() && !is_pure_dummy)
{
F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f);
@@ -3602,6 +3619,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
stopMotion(ANIM_AGENT_WALK_ADJUST);
removeAnimationData("Walk Speed");
}
+ // AXON: see SL-763 - playback with altered time step does not
+ // appear to work correctly, odd behavior for distant avatars.
mMotionController.setTimeStep(time_step);
// LL_INFOS() << "Setting timestep to " << time_quantum * pixel_area_scale << LL_ENDL;
}
@@ -3698,23 +3717,28 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
root_pos += LLVector3d(getHoverOffset());
}
-
- LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
-
-
- if (newPosition != mRoot->getXform()->getWorldPosition())
- {
- mRoot->touch();
- // SL-315
- mRoot->setWorldPosition( newPosition ); // regular update
- }
+ LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
+ if (cav)
+ {
+ cav->matchVolumeTransform();
+ }
+ else
+ {
+ LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
+ if (newPosition != mRoot->getXform()->getWorldPosition())
+ {
+ mRoot->touch();
+ // SL-315
+ mRoot->setWorldPosition( newPosition ); // regular update
+ }
+ }
//--------------------------------------------------------------------
// Propagate viewer object rotation to root of avatar
//--------------------------------------------------------------------
- // AXON - also skip for control avatars
- if (!isControlAvatar() && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS))
+ // AXON - also skip for control avatars? Rotation fixups for avatars in motion, some may be relevant.
+ if (!is_control_avatar && !isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS))
{
LLQuaternion iQ;
LLVector3 upDir( 0.0f, 0.0f, 1.0f );
@@ -3868,6 +3892,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
else if (mDrawable.notNull())
{
+ // Sitting on an object - mRoot is slaved to mDrawable orientation.
LLVector3 pos = mDrawable->getPosition();
pos += getHoverOffset() * mDrawable->getRotation();
// SL-315
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 8b22024e0a..acecc6118c 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -749,9 +749,9 @@ public:
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
+ LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
protected:
- LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
void lazyAttach();
void rebuildRiggedAttachments( void );