diff options
-rw-r--r-- | indra/newview/llcontrolavatar.cpp | 46 | ||||
-rw-r--r-- | indra/newview/lldrawable.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llviewerobject.cpp | 9 | ||||
-rw-r--r-- | indra/newview/llviewerobjectlist.cpp | 6 | ||||
-rw-r--r-- | indra/newview/llvoavatar.cpp | 59 | ||||
-rw-r--r-- | indra/newview/llvoavatar.h | 2 |
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 ); |