summaryrefslogtreecommitdiff
path: root/indra/newview/llvoavatar.cpp
diff options
context:
space:
mode:
authorOz Linden <oz@lindenlab.com>2016-12-05 15:20:27 -0500
committerOz Linden <oz@lindenlab.com>2016-12-05 15:20:27 -0500
commitc21571474c0022f83a4efc28d59e97fc020fd0e7 (patch)
tree15586cbd2055a1c84dad4ce2f74efe1a885d997d /indra/newview/llvoavatar.cpp
parentfd2ccb16068dfd21307b17e78e384d8ae19fef12 (diff)
parent68413474c4479eee9bdbeb34ea131475ba1d646e (diff)
merge changes for 5.0.0-release
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r--indra/newview/llvoavatar.cpp1135
1 files changed, 900 insertions, 235 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 1425b3d42e..96a1beffbc 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -106,6 +106,8 @@
#include "llsdutil.h"
#include "llscenemonitor.h"
#include "llsdserialize.h"
+#include "llcallstack.h"
+#include "llrendersphere.h"
extern F32 SPEED_ADJUST_MAX;
extern F32 SPEED_ADJUST_MAX_SEC;
@@ -215,26 +217,8 @@ struct LLTextureMaskData
**
**/
-//------------------------------------------------------------------------
-// LLVOAvatarBoneInfo
-// Trans/Scale/Rot etc. info about each avatar bone. Used by LLVOAvatarSkeleton.
-//------------------------------------------------------------------------
-struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo>
-{
- LLVOAvatarCollisionVolumeInfo()
- : name("name"),
- pos("pos"),
- rot("rot"),
- scale("scale")
- {}
- Mandatory<std::string> name;
- Mandatory<LLVector3> pos,
- rot,
- scale;
-};
-
-struct LLAppearanceMessageContents
+struct LLAppearanceMessageContents: public LLRefCount
{
LLAppearanceMessageContents():
mAppearanceVersion(-1),
@@ -254,49 +238,6 @@ struct LLAppearanceMessageContents
bool mHoverOffsetWasSet;
};
-struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
- {
- Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> > bone;
- Alternative<LLVOAvatarCollisionVolumeInfo> collision_volume;
-
- LLVOAvatarChildJoint()
- : bone("bone"),
- collision_volume("collision_volume")
- {}
-};
-
-
-
-struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>
-{
- LLVOAvatarBoneInfo()
- : pivot("pivot")
- {}
-
- Mandatory<LLVector3> pivot;
- Multiple<LLVOAvatarChildJoint> children;
-};
-
-//------------------------------------------------------------------------
-// LLVOAvatarSkeletonInfo
-// Overall avatar skeleton
-//------------------------------------------------------------------------
-struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo>
-{
- LLVOAvatarSkeletonInfo()
- : skeleton_root(""),
- num_bones("num_bones"),
- num_collision_volumes("num_collision_volumes"),
- version("version")
- {}
-
- Mandatory<std::string> version;
- Mandatory<S32> num_bones,
- num_collision_volumes;
- Mandatory<LLVOAvatarChildJoint> skeleton_root;
-};
-
-
//-----------------------------------------------------------------------------
// class LLBodyNoiseMotion
@@ -1112,7 +1053,6 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
{
if (LLViewerTexLayerSet::sHasCaches)
{
- LL_DEBUGS() << "Deleting layer set caches" << LL_ENDL;
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
iter != LLCharacter::sInstances.end(); ++iter)
{
@@ -1143,6 +1083,9 @@ void LLVOAvatar::initClass()
gAnimLibrary.animStateSetString(ANIM_AGENT_PELVIS_FIX,"pelvis_fix");
gAnimLibrary.animStateSetString(ANIM_AGENT_TARGET,"target");
gAnimLibrary.animStateSetString(ANIM_AGENT_WALK_ADJUST,"walk_adjust");
+
+ // Where should this be set initially?
+ LLJoint::setDebugJointNames(gSavedSettings.getString("DebugAvatarJoints"));
}
@@ -1396,18 +1339,78 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
newMax.add(buffer);
}
+void render_sphere_and_line(const LLVector3& begin_pos, const LLVector3& end_pos, F32 sphere_scale, const LLVector3& occ_color, const LLVector3& visible_color)
+{
+ // Unoccluded bone portions
+ LLGLDepthTest normal_depth(GL_TRUE);
+
+ // Draw line segment for unoccluded joint
+ gGL.diffuseColor3f(visible_color[0], visible_color[1], visible_color[2]);
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(begin_pos.mV);
+ gGL.vertex3fv(end_pos.mV);
+ gGL.end();
+
+
+ // Draw sphere representing joint pos
+ gGL.pushMatrix();
+ gGL.scalef(sphere_scale, sphere_scale, sphere_scale);
+ gSphere.renderGGL();
+ gGL.popMatrix();
+
+ LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
+
+ // Occluded bone portions
+ gGL.diffuseColor3f(occ_color[0], occ_color[1], occ_color[2]);
+
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(begin_pos.mV);
+ gGL.vertex3fv(end_pos.mV);
+ gGL.end();
+
+ // Draw sphere representing joint pos
+ gGL.pushMatrix();
+ gGL.scalef(sphere_scale, sphere_scale, sphere_scale);
+ gSphere.renderGGL();
+ gGL.popMatrix();
+}
+
//-----------------------------------------------------------------------------
// renderCollisionVolumes()
//-----------------------------------------------------------------------------
void LLVOAvatar::renderCollisionVolumes()
{
std::ostringstream ostr;
+
for (S32 i = 0; i < mNumCollisionVolumes; i++)
{
- mCollisionVolumes[i].renderCollision();
ostr << mCollisionVolumes[i].getName() << ", ";
- }
+ LLAvatarJointCollisionVolume& collision_volume = mCollisionVolumes[i];
+
+ collision_volume.updateWorldMatrix();
+
+ gGL.pushMatrix();
+ gGL.multMatrix( &collision_volume.getXform()->getWorldMatrix().mMatrix[0][0] );
+
+ LLVector3 begin_pos(0,0,0);
+ LLVector3 end_pos(collision_volume.getEnd());
+ static F32 sphere_scale = 1.0f;
+ static F32 center_dot_scale = 0.05f;
+
+ static LLVector3 CV_COLOR_OCCLUDED(0.0f, 0.0f, 1.0f);
+ static LLVector3 CV_COLOR_VISIBLE(0.5f, 0.5f, 1.0f);
+ static LLVector3 DOT_COLOR_OCCLUDED(1.0f, 1.0f, 1.0f);
+ static LLVector3 DOT_COLOR_VISIBLE(1.0f, 1.0f, 1.0f);
+
+ render_sphere_and_line(begin_pos, end_pos, sphere_scale, CV_COLOR_OCCLUDED, CV_COLOR_VISIBLE);
+ render_sphere_and_line(begin_pos, end_pos, center_dot_scale, DOT_COLOR_OCCLUDED, DOT_COLOR_VISIBLE);
+
+ gGL.popMatrix();
+ }
+
+
if (mNameText.notNull())
{
LLVector4a unused;
@@ -1419,6 +1422,72 @@ void LLVOAvatar::renderCollisionVolumes()
addDebugText(ostr.str());
}
+void LLVOAvatar::renderBones()
+{
+ LLGLEnable blend(GL_BLEND);
+
+ avatar_joint_list_t::iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::iterator end = mSkeleton.end();
+
+ // For bones with position overrides defined
+ static LLVector3 OVERRIDE_COLOR_OCCLUDED(1.0f, 0.0f, 0.0f);
+ static LLVector3 OVERRIDE_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
+ // For bones which are rigged to by at least one attachment
+ static LLVector3 RIGGED_COLOR_OCCLUDED(0.0f, 1.0f, 1.0f);
+ static LLVector3 RIGGED_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
+ // For bones not otherwise colored
+ static LLVector3 OTHER_COLOR_OCCLUDED(0.0f, 1.0f, 0.0f);
+ static LLVector3 OTHER_COLOR_VISIBLE(0.5f, 0.5f, 0.5f);
+
+ static F32 SPHERE_SCALEF = 0.001f;
+
+ for (; iter != end; ++iter)
+ {
+ LLJoint* jointp = *iter;
+ if (!jointp)
+ {
+ continue;
+ }
+
+ jointp->updateWorldMatrix();
+
+ LLVector3 occ_color, visible_color;
+
+ LLVector3 pos;
+ LLUUID mesh_id;
+ if (jointp->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ occ_color = OVERRIDE_COLOR_OCCLUDED;
+ visible_color = OVERRIDE_COLOR_VISIBLE;
+ }
+ else
+ {
+ if (jointIsRiggedTo(jointp->getName()))
+ {
+ occ_color = RIGGED_COLOR_OCCLUDED;
+ visible_color = RIGGED_COLOR_VISIBLE;
+ }
+ else
+ {
+ occ_color = OTHER_COLOR_OCCLUDED;
+ visible_color = OTHER_COLOR_VISIBLE;
+ }
+ }
+ LLVector3 begin_pos(0,0,0);
+ LLVector3 end_pos(jointp->getEnd());
+
+ F32 sphere_scale = SPHERE_SCALEF;
+
+ gGL.pushMatrix();
+ gGL.multMatrix( &jointp->getXform()->getWorldMatrix().mMatrix[0][0] );
+
+ render_sphere_and_line(begin_pos, end_pos, sphere_scale, occ_color, visible_color);
+
+ gGL.popMatrix();
+ }
+}
+
+
void LLVOAvatar::renderJoints()
{
std::ostringstream ostr;
@@ -1526,7 +1595,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
for (S32 i = 0; i < mNumCollisionVolumes; ++i)
{
mCollisionVolumes[i].updateWorldMatrix();
-
+
glh::matrix4f mat((F32*) mCollisionVolumes[i].getXform()->getWorldMatrix().mMatrix);
glh::matrix4f inverse = mat.inverse();
glh::matrix4f norm_mat = inverse.transpose();
@@ -1735,6 +1804,133 @@ void LLVOAvatar::buildCharacter()
mMeshValid = TRUE;
}
+//-----------------------------------------------------------------------------
+// resetVisualParams()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetVisualParams()
+{
+ // Skeletal params
+ {
+ LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
+ for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
+ iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end();
+ ++iter)
+ {
+ LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter;
+ LLPolySkeletalDistortion *param = dynamic_cast<LLPolySkeletalDistortion*>(getVisualParam(info->getID()));
+ *param = LLPolySkeletalDistortion(this);
+ llassert(param);
+ if (!param->setInfo(info))
+ {
+ llassert(false);
+ }
+ }
+ }
+
+ // Driver parameters
+ for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
+ iter != sAvatarXmlInfo->mDriverInfoList.end();
+ ++iter)
+ {
+ LLDriverParamInfo *info = *iter;
+ LLDriverParam *param = dynamic_cast<LLDriverParam*>(getVisualParam(info->getID()));
+ LLDriverParam::entry_list_t driven_list = param->getDrivenList();
+ *param = LLDriverParam(this);
+ llassert(param);
+ if (!param->setInfo(info))
+ {
+ llassert(false);
+ }
+ param->setDrivenList(driven_list);
+ }
+}
+
+//-----------------------------------------------------------------------------
+// resetSkeleton()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetSkeleton(bool reset_animations)
+{
+ LL_DEBUGS("Avatar") << avString() << " reset starts" << LL_ENDL;
+ if (!mLastProcessedAppearance)
+ {
+ LL_WARNS() << "Can't reset avatar; no appearance message has been received yet." << LL_ENDL;
+ return;
+ }
+
+ // Save mPelvis state
+ //LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();
+ //LLQuaternion pelvis_rot = getJoint("mPelvis")->getRotation();
+
+ // Clear all attachment pos and scale overrides
+ clearAttachmentOverrides();
+
+ // Note that we call buildSkeleton twice in this function. The first time is
+ // just to get the right scale for the collision volumes, because
+ // this will be used in setting the mJointScales for the
+ // LLPolySkeletalDistortions of which the CVs are children.
+ if( !buildSkeleton(sAvatarSkeletonInfo) )
+ {
+ LL_ERRS() << "Error resetting skeleton" << LL_ENDL;
+ }
+
+ // Reset some params to default state, without propagating changes downstream.
+ resetVisualParams();
+
+ // Now we have to reset the skeleton again, because its state
+ // got clobbered by the resetVisualParams() calls
+ // above.
+ if( !buildSkeleton(sAvatarSkeletonInfo) )
+ {
+ LL_ERRS() << "Error resetting skeleton" << LL_ENDL;
+ }
+
+ // Reset attachment points (buildSkeleton only does bones and CVs)
+ bool ignore_hud_joints = true;
+ initAttachmentPoints(ignore_hud_joints);
+
+ // Fix up collision volumes
+ for (LLVisualParam *param = getFirstVisualParam();
+ param;
+ param = getNextVisualParam())
+ {
+ LLPolyMorphTarget *poly_morph = dynamic_cast<LLPolyMorphTarget*>(param);
+ if (poly_morph)
+ {
+ // This is a kludgy way to correct for the fact that the
+ // collision volumes have been reset out from under the
+ // poly morph sliders.
+ F32 delta_weight = poly_morph->getLastWeight() - poly_morph->getDefaultWeight();
+ poly_morph->applyVolumeChanges(delta_weight);
+ }
+ }
+
+ // Reset tweakable params to preserved state
+ bool slam_params = true;
+ applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
+ updateVisualParams();
+
+ // Restore attachment pos overrides
+ rebuildAttachmentOverrides();
+
+ // Animations
+ if (reset_animations)
+ {
+ if (isSelf())
+ {
+ // This is equivalent to "Stop Animating Me". Will reset
+ // all animations and propagate the changes to other
+ // viewers.
+ gAgent.stopCurrentAnimations();
+ }
+ else
+ {
+ // Local viewer-side reset for non-self avatars.
+ resetAnimations();
+ }
+ }
+
+ LL_DEBUGS("Avatar") << avString() << " reset ends" << LL_ENDL;
+}
//-----------------------------------------------------------------------------
// releaseMeshData()
@@ -1746,8 +1942,6 @@ void LLVOAvatar::releaseMeshData()
return;
}
- LL_DEBUGS() << "Releasing mesh data" << LL_ENDL;
-
// cleanup mesh data
for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
iter != mMeshLOD.end();
@@ -1957,17 +2151,12 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
- //LLTEContents tec;
- //S32 te_retval = parseTEMessage(mesgsys, _PREHASH_ObjectData, block_num, tec);
-
- LL_DEBUGS("Avatar") << avString() << update_type << LL_ENDL;
-
// Print out arrival information once we have name of avatar.
- if (has_name && getNVPair("FirstName"))
- {
- mDebugExistenceTimer.reset();
- debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived");
- }
+ if (has_name && getNVPair("FirstName"))
+ {
+ mDebugExistenceTimer.reset();
+ debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived");
+ }
if(retval & LLViewerObject::INVALID_UPDATE)
{
@@ -2075,6 +2264,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
return;
}
+ LLScopedContextString str("avatar_idle_update " + getFullname());
+
checkTextureLoading() ;
// force immediate pixel area update on avatars using last frames data (before drawable or camera updates)
@@ -3079,6 +3270,7 @@ void LLVOAvatar::idleUpdateBelowWater()
void LLVOAvatar::slamPosition()
{
gAgent.setPositionAgent(getPositionAgent());
+ // SL-315
mRoot->setWorldPosition(getPositionAgent()); // teleport
setChanged(TRANSLATED);
if (mDrawable.notNull())
@@ -3176,23 +3368,31 @@ void LLVOAvatar::updateDebugText()
{
debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
}
- debug_line += llformat(" bsz-z: %f avofs-z: %f", mBodySize[2], mAvatarOffset[2]);
+ debug_line += llformat(" bsz-z: %.3f", mBodySize[2]);
+ if (mAvatarOffset[2] != 0.0f)
+ {
+ debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]);
+ }
bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled();
debug_line += hover_enabled ? " H" : " h";
const LLVector3& hover_offset = getHoverOffset();
if (hover_offset[2] != 0.0)
{
- debug_line += llformat(" hov_z: %f", hover_offset[2]);
+ debug_line += llformat(" hov_z: %.3f", hover_offset[2]);
debug_line += llformat(" %s", (mIsSitting ? "S" : "T"));
debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
}
- F32 elapsed = mLastAppearanceMessageTimer.getElapsedTimeF32();
- static const char *elapsed_chars = "Xx*...";
- U32 bucket = U32(elapsed*2);
- if (bucket < strlen(elapsed_chars))
- {
- debug_line += llformat(" %c", elapsed_chars[bucket]);
- }
+ LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
+ LLVector3 normal;
+ LLVector3 ankle_right_ground_agent = ankle_right_pos_agent;
+ resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal);
+ F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]);
+ debug_line += llformat(" relev %.3f", rightElev);
+
+ LLVector3 root_pos = mRoot->getPosition();
+ LLVector3 pelvis_pos = mPelvisp->getPosition();
+ debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]);
+
addDebugText(debug_line);
}
if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
@@ -3377,6 +3577,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
mTimeLast = animation_time;
// put the pelvis at slaved position/mRotation
+ // SL-315
mRoot->setWorldPosition( getPositionAgent() ); // first frame
mRoot->setWorldRotation( getRotation() );
}
@@ -3417,6 +3618,13 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
}
mInAir = in_air;
+ // SL-402: with the ability to animate the position of joints
+ // that affect the body size calculation, computed body size
+ // can get stale much more easily. Simplest fix is to update
+ // it frequently.
+ // SL-427: this appears to be too frequent, moving to only do on animation state change.
+ //computeBodySize();
+
// correct for the fact that the pelvis is not necessarily the center
// of the agent's physical representation
root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
@@ -3431,6 +3639,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
if (newPosition != mRoot->getXform()->getWorldPosition())
{
mRoot->touch();
+ // SL-315
mRoot->setWorldPosition( newPosition ); // regular update
}
@@ -3594,6 +3803,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
{
LLVector3 pos = mDrawable->getPosition();
pos += getHoverOffset() * mDrawable->getRotation();
+ // SL-315
mRoot->setPosition(pos);
mRoot->setRotation(mDrawable->getRotation());
}
@@ -3624,6 +3834,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
LLVector3 pos = mRoot->getWorldPosition();
pos.mV[VZ] += off_z;
mRoot->touch();
+ // SL-315
mRoot->setWorldPosition(pos);
}
}
@@ -3739,10 +3950,78 @@ void LLVOAvatar::updateHeadOffset()
mHeadOffset = lerp(midEyePt, mHeadOffset, u);
}
}
+
+void LLVOAvatar::debugBodySize() const
+{
+ LLVector3 pelvis_scale = mPelvisp->getScale();
+
+ // some of the joints have not been cached
+ LLVector3 skull = mSkullp->getPosition();
+ LL_DEBUGS("Avatar") << "skull pos " << skull << LL_ENDL;
+ //LLVector3 skull_scale = mSkullp->getScale();
+
+ LLVector3 neck = mNeckp->getPosition();
+ LLVector3 neck_scale = mNeckp->getScale();
+ LL_DEBUGS("Avatar") << "neck pos " << neck << " neck_scale " << neck_scale << LL_ENDL;
+
+ LLVector3 chest = mChestp->getPosition();
+ LLVector3 chest_scale = mChestp->getScale();
+ LL_DEBUGS("Avatar") << "chest pos " << chest << " chest_scale " << chest_scale << LL_ENDL;
+
+ // the rest of the joints have been cached
+ LLVector3 head = mHeadp->getPosition();
+ LLVector3 head_scale = mHeadp->getScale();
+ LL_DEBUGS("Avatar") << "head pos " << head << " head_scale " << head_scale << LL_ENDL;
+
+ LLVector3 torso = mTorsop->getPosition();
+ LLVector3 torso_scale = mTorsop->getScale();
+ LL_DEBUGS("Avatar") << "torso pos " << torso << " torso_scale " << torso_scale << LL_ENDL;
+
+ LLVector3 hip = mHipLeftp->getPosition();
+ LLVector3 hip_scale = mHipLeftp->getScale();
+ LL_DEBUGS("Avatar") << "hip pos " << hip << " hip_scale " << hip_scale << LL_ENDL;
+
+ LLVector3 knee = mKneeLeftp->getPosition();
+ LLVector3 knee_scale = mKneeLeftp->getScale();
+ LL_DEBUGS("Avatar") << "knee pos " << knee << " knee_scale " << knee_scale << LL_ENDL;
+
+ LLVector3 ankle = mAnkleLeftp->getPosition();
+ LLVector3 ankle_scale = mAnkleLeftp->getScale();
+ LL_DEBUGS("Avatar") << "ankle pos " << ankle << " ankle_scale " << ankle_scale << LL_ENDL;
+
+ LLVector3 foot = mFootLeftp->getPosition();
+ LL_DEBUGS("Avatar") << "foot pos " << foot << LL_ENDL;
+
+ F32 new_offset = (const_cast<LLVOAvatar*>(this))->getVisualParamWeight(AVATAR_HOVER);
+ LL_DEBUGS("Avatar") << "new_offset " << new_offset << LL_ENDL;
+
+ F32 new_pelvis_to_foot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
+ knee.mV[VZ] * hip_scale.mV[VZ] -
+ ankle.mV[VZ] * knee_scale.mV[VZ] -
+ foot.mV[VZ] * ankle_scale.mV[VZ];
+ LL_DEBUGS("Avatar") << "new_pelvis_to_foot " << new_pelvis_to_foot << LL_ENDL;
+
+ LLVector3 new_body_size;
+ new_body_size.mV[VZ] = new_pelvis_to_foot +
+ // the sqrt(2) correction below is an approximate
+ // correction to get to the top of the head
+ F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) +
+ head.mV[VZ] * neck_scale.mV[VZ] +
+ neck.mV[VZ] * chest_scale.mV[VZ] +
+ chest.mV[VZ] * torso_scale.mV[VZ] +
+ torso.mV[VZ] * pelvis_scale.mV[VZ];
+
+ // TODO -- measure the real depth and width
+ new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
+ new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
+
+ LL_DEBUGS("Avatar") << "new_body_size " << new_body_size << LL_ENDL;
+}
+
//------------------------------------------------------------------------
// postPelvisSetRecalc
//------------------------------------------------------------------------
-void LLVOAvatar::postPelvisSetRecalc( void )
+void LLVOAvatar::postPelvisSetRecalc()
{
mRoot->updateWorldMatrixChildren();
computeBodySize();
@@ -4832,6 +5111,12 @@ void LLVOAvatar::processAnimationStateChanges()
//-----------------------------------------------------------------------------
BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL start )
{
+ // SL-402, SL-427 - we need to update body size often enough to
+ // keep appearances in sync, but not so often that animations
+ // cause constant jiggling of the body or camera. Possible
+ // compromise is to do it on animation changes:
+ computeBodySize();
+
BOOL result = FALSE;
if ( start ) // start animation
@@ -5056,18 +5341,52 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
LLJoint* jointp = NULL;
if (iter == mJointMap.end() || iter->second == NULL)
- { //search for joint and cache found joint in lookup table
+ { //search for joint and cache found joint in lookup table
jointp = mRoot->findJoint(name);
mJointMap[name] = jointp;
}
else
- { //return cached pointer
+ { //return cached pointer
jointp = iter->second;
}
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+ if (jointp && jointp->getName()!="mScreen" && jointp->getName()!="mRoot")
+ {
+ llassert(getJoint(jointp->getJointNum())==jointp);
+ }
+#endif
return jointp;
}
+LLJoint *LLVOAvatar::getJoint( S32 joint_num )
+{
+ LLJoint *pJoint = NULL;
+ S32 collision_start = mNumBones;
+ S32 attachment_start = mNumBones + mNumCollisionVolumes;
+ if (joint_num>=attachment_start)
+ {
+ // Attachment IDs start at 1
+ S32 attachment_id = joint_num - attachment_start + 1;
+ attachment_map_t::iterator iter = mAttachmentPoints.find(attachment_id);
+ if (iter != mAttachmentPoints.end())
+ {
+ pJoint = iter->second;
+ }
+ }
+ else if (joint_num>=collision_start)
+ {
+ S32 collision_id = joint_num-collision_start;
+ pJoint = &mCollisionVolumes[collision_id];
+ }
+ else if (joint_num>=0)
+ {
+ pJoint = mSkeleton[joint_num];
+ }
+ llassert(!pJoint || pJoint->getJointNum() == joint_num);
+ return pJoint;
+}
+
//-----------------------------------------------------------------------------
// getRiggedMeshID
//
@@ -5098,37 +5417,121 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id)
return false;
}
-void LLVOAvatar::clearAttachmentPosOverrides()
+bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name)
{
- //Subsequent joints are relative to pelvis
- avatar_joint_list_t::iterator iter = mSkeleton.begin();
- avatar_joint_list_t::iterator end = mSkeleton.end();
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ const LLViewerObject* attached_object = (*attachment_iter);
+ if (attached_object && jointIsRiggedTo(joint_name, attached_object))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
- for (; iter != end; ++iter)
+bool LLVOAvatar::jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo)
+{
+ // 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)
{
- LLJoint* pJoint = (*iter);
- pJoint->clearAttachmentPosOverrides();
+ LLViewerObject *childp = *it;
+ if (jointIsRiggedTo(joint_name,childp))
+ {
+ return true;
+ }
}
+
+ const LLVOVolume *vobj = dynamic_cast<const LLVOVolume*>(vo);
+ if (!vobj)
+ {
+ return false;
+ }
+
+ LLUUID currentId = vobj->getVolume()->getParams().getSculptID();
+ const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
+
+ if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData )
+ {
+ if (std::find(pSkinData->mJointNames.begin(), pSkinData->mJointNames.end(), joint_name) !=
+ pSkinData->mJointNames.end())
+ {
+ return true;
+ }
+ }
+
+ return false;
}
+void LLVOAvatar::clearAttachmentOverrides()
+{
+ LLScopedContextString str("clearAttachmentOverrides " + getFullname());
+
+ for (S32 i=0; i<LL_CHARACTER_MAX_ANIMATED_JOINTS; i++)
+ {
+ LLJoint *pJoint = getJoint(i);
+ if (pJoint)
+ {
+ pJoint->clearAttachmentPosOverrides();
+ pJoint->clearAttachmentScaleOverrides();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// rebuildAttachmentOverrides
+//-----------------------------------------------------------------------------
+void LLVOAvatar::rebuildAttachmentOverrides()
+{
+ LLScopedContextString str("rebuildAttachmentOverrides " + getFullname());
+
+ // Attachment points
+ 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)
+ {
+ addAttachmentOverridesForObject(*at_it);
+ }
+ }
+ }
+}
//-----------------------------------------------------------------------------
// addAttachmentPosOverridesForObject
//-----------------------------------------------------------------------------
-void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)
+void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
{
LLVOAvatar *av = vo->getAvatarAncestor();
if (!av || (av != this))
{
LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
+ return;
}
-
+
+ LLScopedContextString str("addAttachmentOverridesForObject " + av->getFullname());
+
// 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;
- addAttachmentPosOverridesForObject(childp);
+ addAttachmentOverridesForObject(childp);
}
LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo);
@@ -5149,9 +5552,13 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)
if ( vobj && vobj->isAttachment() && vobj->isMesh() && pSkinData )
{
const int bindCnt = pSkinData->mAlternateBindMatrix.size();
- if ( bindCnt > 0 )
+ const int jointCnt = pSkinData->mJointNames.size();
+ if ((bindCnt > 0) && (bindCnt != jointCnt))
+ {
+ LL_WARNS_ONCE() << "invalid mesh, bindCnt " << bindCnt << "!= jointCnt " << jointCnt << ", joint overrides will be ignored." << LL_ENDL;
+ }
+ if ((bindCnt > 0) && (bindCnt == jointCnt))
{
- const int jointCnt = pSkinData->mJointNames.size();
const F32 pelvisZOffset = pSkinData->mPelvisOffset;
const LLUUID& mesh_id = pSkinData->mMeshID;
bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;
@@ -5161,24 +5568,43 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)
{
std::string lookingForJoint = pSkinData->mJointNames[i].c_str();
LLJoint* pJoint = getJoint( lookingForJoint );
- if ( pJoint && pJoint->getId() != currentId )
+ if (pJoint)
{
- pJoint->setId( currentId );
const LLVector3& jointPos = pSkinData->mAlternateBindMatrix[i].getTranslation();
- //Set the joint position
- pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString() );
-
- //If joint is a pelvis then handle old/new pelvis to foot values
- if ( lookingForJoint == "mPelvis" )
- {
- pelvisGotSet = true;
- }
+ if (pJoint->aboveJointPosThreshold(jointPos))
+ {
+ bool override_changed;
+ pJoint->addAttachmentPosOverride( jointPos, mesh_id, avString(), override_changed );
+
+ if (override_changed)
+ {
+ //If joint is a pelvis then handle old/new pelvis to foot values
+ if ( lookingForJoint == "mPelvis" )
+ {
+ pelvisGotSet = true;
+ }
+ }
+ if (pSkinData->mLockScaleIfJointPosition)
+ {
+ // Note that unlike positions, there's no threshold check here,
+ // just a lock at the default value.
+ pJoint->addAttachmentScaleOverride(pJoint->getDefaultScale(), mesh_id, avString());
+ }
+ }
}
}
if (pelvisZOffset != 0.0F)
{
+ F32 pelvis_fixup_before;
+ bool has_fixup_before = hasPelvisFixup(pelvis_fixup_before);
addPelvisFixup( pelvisZOffset, mesh_id );
- pelvisGotSet = true;
+ F32 pelvis_fixup_after;
+ hasPelvisFixup(pelvis_fixup_after); // Don't have to check bool here because we just added it...
+ if (!has_fixup_before || (pelvis_fixup_before != pelvis_fixup_after))
+ {
+ pelvisGotSet = true;
+ }
+
}
}
}
@@ -5192,9 +5618,122 @@ void LLVOAvatar::addAttachmentPosOverridesForObject(LLViewerObject *vo)
}
//-----------------------------------------------------------------------------
-// resetJointPositionsOnDetach
+// getAttachmentOverrideNames
+//-----------------------------------------------------------------------------
+void LLVOAvatar::getAttachmentOverrideNames(std::set<std::string>& pos_names, std::set<std::string>& scale_names) const
+{
+ LLVector3 pos;
+ LLVector3 scale;
+ LLUUID mesh_id;
+
+ // Bones
+ for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
+ iter != mSkeleton.end(); ++iter)
+ {
+ const LLJoint* pJoint = (*iter);
+ if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ pos_names.insert(pJoint->getName());
+ }
+ if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
+ {
+ scale_names.insert(pJoint->getName());
+ }
+ }
+
+ // Attachment points
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment *attachment_pt = (*iter).second;
+ if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ pos_names.insert(attachment_pt->getName());
+ }
+ // Attachment points don't have scales.
+ }
+
+}
+
+//-----------------------------------------------------------------------------
+// showAttachmentOverrides
//-----------------------------------------------------------------------------
-void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo)
+void LLVOAvatar::showAttachmentOverrides(bool verbose) const
+{
+ std::set<std::string> pos_names, scale_names;
+ getAttachmentOverrideNames(pos_names, scale_names);
+ if (pos_names.size())
+ {
+ std::stringstream ss;
+ std::copy(pos_names.begin(), pos_names.end(), std::ostream_iterator<std::string>(ss, ","));
+ LL_INFOS() << getFullname() << " attachment positions defined for joints: " << ss.str() << "\n" << LL_ENDL;
+ }
+ else
+ {
+ LL_DEBUGS("Avatar") << getFullname() << " no attachment positions defined for any joints" << "\n" << LL_ENDL;
+ }
+ if (scale_names.size())
+ {
+ std::stringstream ss;
+ std::copy(scale_names.begin(), scale_names.end(), std::ostream_iterator<std::string>(ss, ","));
+ LL_INFOS() << getFullname() << " attachment scales defined for joints: " << ss.str() << "\n" << LL_ENDL;
+ }
+ else
+ {
+ LL_INFOS() << getFullname() << " no attachment scales defined for any joints" << "\n" << LL_ENDL;
+ }
+
+ if (!verbose)
+ {
+ return;
+ }
+
+ LLVector3 pos, scale;
+ LLUUID mesh_id;
+ S32 count = 0;
+
+ // Bones
+ for (avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
+ iter != mSkeleton.end(); ++iter)
+ {
+ const LLJoint* pJoint = (*iter);
+ if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ pJoint->showAttachmentPosOverrides(getFullname());
+ count++;
+ }
+ if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
+ {
+ pJoint->showAttachmentScaleOverrides(getFullname());
+ count++;
+ }
+ }
+
+ // Attachment points
+ for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ const LLViewerJointAttachment *attachment_pt = (*iter).second;
+ if (attachment_pt && attachment_pt->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ attachment_pt->showAttachmentPosOverrides(getFullname());
+ count++;
+ }
+ }
+
+ if (count)
+ {
+ LL_DEBUGS("Avatar") << avString() << " end of pos, scale overrides" << LL_ENDL;
+ LL_DEBUGS("Avatar") << "=================================" << LL_ENDL;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// resetJointsOnDetach
+//-----------------------------------------------------------------------------
+void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo)
{
LLVOAvatar *av = vo->getAvatarAncestor();
if (!av || (av != this))
@@ -5208,21 +5747,21 @@ void LLVOAvatar::resetJointPositionsOnDetach(LLViewerObject *vo)
it != children.end(); ++it)
{
LLViewerObject *childp = *it;
- resetJointPositionsOnDetach(childp);
+ resetJointsOnDetach(childp);
}
// Process self.
LLUUID mesh_id;
if (getRiggedMeshID(vo,mesh_id))
{
- resetJointPositionsOnDetach(mesh_id);
+ resetJointsOnDetach(mesh_id);
}
}
//-----------------------------------------------------------------------------
-// resetJointPositionsOnDetach
+// resetJointsOnDetach
//-----------------------------------------------------------------------------
-void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id)
+void LLVOAvatar::resetJointsOnDetach(const LLUUID& mesh_id)
{
//Subsequent joints are relative to pelvis
avatar_joint_list_t::iterator iter = mSkeleton.begin();
@@ -5236,12 +5775,14 @@ void LLVOAvatar::resetJointPositionsOnDetach(const LLUUID& mesh_id)
//Reset joints except for pelvis
if ( pJoint )
{
- pJoint->setId( LLUUID::null );
- pJoint->removeAttachmentPosOverride(mesh_id, avString());
+ bool dummy; // unused
+ pJoint->removeAttachmentPosOverride(mesh_id, avString(),dummy);
+ pJoint->removeAttachmentScaleOverride(mesh_id, avString());
}
if ( pJoint && pJoint == pJointPelvis)
{
removePelvisFixup( mesh_id );
+ // SL-315
pJoint->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) );
}
}
@@ -5373,83 +5914,99 @@ BOOL LLVOAvatar::loadSkeletonNode ()
return FALSE;
}
- // ATTACHMENTS
- {
- LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
- for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
- iter != sAvatarXmlInfo->mAttachmentInfoList.end();
- ++iter)
- {
- LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
- if (!isSelf() && info->mJointName == "mScreen")
- { //don't process screen joint for other avatars
- continue;
- }
+ bool ignore_hud_joints = false;
+ initAttachmentPoints(ignore_hud_joints);
- LLViewerJointAttachment* attachment = new LLViewerJointAttachment();
+ return TRUE;
+}
- attachment->setName(info->mName);
- LLJoint *parentJoint = getJoint(info->mJointName);
- if (!parentJoint)
- {
- LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL;
- delete attachment;
- continue;
- }
+//-----------------------------------------------------------------------------
+// initAttachmentPoints(): creates attachment points if needed, sets state based on avatar_lad.xml.
+//-----------------------------------------------------------------------------
+void LLVOAvatar::initAttachmentPoints(bool ignore_hud_joints)
+{
+ LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
+ for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
+ iter != sAvatarXmlInfo->mAttachmentInfoList.end();
+ ++iter)
+ {
+ LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
+ if (info->mIsHUDAttachment && (!isSelf() || ignore_hud_joints))
+ {
+ //don't process hud joint for other avatars, or when doing a skeleton reset.
+ continue;
+ }
- if (info->mHasPosition)
- {
- attachment->setOriginalPosition(info->mPosition);
- }
-
- if (info->mHasRotation)
- {
- LLQuaternion rotation;
- rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD,
- info->mRotationEuler.mV[VY] * DEG_TO_RAD,
- info->mRotationEuler.mV[VZ] * DEG_TO_RAD);
- attachment->setRotation(rotation);
- }
+ S32 attachmentID = info->mAttachmentID;
+ if (attachmentID < 1 || attachmentID > 255)
+ {
+ LL_WARNS() << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << LL_ENDL;
+ continue;
+ }
- int group = info->mGroup;
- if (group >= 0)
- {
- if (group < 0 || group >= 9)
- {
- LL_WARNS() << "Invalid group number (" << group << ") for attachment point " << info->mName << LL_ENDL;
- }
- else
- {
- attachment->setGroup(group);
- }
- }
+ LLViewerJointAttachment* attachment = NULL;
+ bool newly_created = false;
+ if (mAttachmentPoints.find(attachmentID) == mAttachmentPoints.end())
+ {
+ attachment = new LLViewerJointAttachment();
+ newly_created = true;
+ }
+ else
+ {
+ attachment = mAttachmentPoints[attachmentID];
+ }
- S32 attachmentID = info->mAttachmentID;
- if (attachmentID < 1 || attachmentID > 255)
- {
- LL_WARNS() << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << LL_ENDL;
- delete attachment;
- continue;
- }
- if (mAttachmentPoints.find(attachmentID) != mAttachmentPoints.end())
- {
- LL_WARNS() << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << LL_ENDL;
- delete attachment;
- continue;
- }
+ attachment->setName(info->mName);
+ LLJoint *parent_joint = getJoint(info->mJointName);
+ if (!parent_joint)
+ {
+ // If the intended parent for attachment point is unavailable, avatar_lad.xml is corrupt.
+ LL_WARNS() << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << LL_ENDL;
+ LL_ERRS() << "Invalid avatar_lad.xml file" << LL_ENDL;
+ }
- attachment->setPieSlice(info->mPieMenuSlice);
- attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson);
- attachment->setIsHUDAttachment(info->mIsHUDAttachment);
+ if (info->mHasPosition)
+ {
+ attachment->setOriginalPosition(info->mPosition);
+ attachment->setDefaultPosition(info->mPosition);
+ }
+
+ if (info->mHasRotation)
+ {
+ LLQuaternion rotation;
+ rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD,
+ info->mRotationEuler.mV[VY] * DEG_TO_RAD,
+ info->mRotationEuler.mV[VZ] * DEG_TO_RAD);
+ attachment->setRotation(rotation);
+ }
- mAttachmentPoints[attachmentID] = attachment;
+ int group = info->mGroup;
+ if (group >= 0)
+ {
+ if (group < 0 || group > 9)
+ {
+ LL_WARNS() << "Invalid group number (" << group << ") for attachment point " << info->mName << LL_ENDL;
+ }
+ else
+ {
+ attachment->setGroup(group);
+ }
+ }
- // now add attachment joint
- parentJoint->addChild(attachment);
- }
- }
+ attachment->setPieSlice(info->mPieMenuSlice);
+ attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson);
+ attachment->setIsHUDAttachment(info->mIsHUDAttachment);
+ // attachment can potentially be animated, needs a number.
+ attachment->setJointNum(mNumBones + mNumCollisionVolumes + attachmentID - 1);
- return TRUE;
+ if (newly_created)
+ {
+ mAttachmentPoints[attachmentID] = attachment;
+
+ // now add attachment joint
+ parent_joint->addChild(attachment);
+ }
+ }
}
//-----------------------------------------------------------------------------
@@ -5921,7 +6478,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
LLUUID mesh_id;
if (getRiggedMeshID(pVO, mesh_id))
{
- resetJointPositionsOnDetach(mesh_id);
+ resetJointsOnDetach(mesh_id);
if ( gAgentCamera.cameraCustomizeAvatar() )
{
gAgent.unpauseAnimation();
@@ -6018,6 +6575,7 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
// objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655.
sitDown(TRUE);
mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
+ // SL-315
mRoot->setPosition(getPosition());
mRoot->updateWorldMatrixChildren();
@@ -6076,6 +6634,7 @@ void LLVOAvatar::getOffObject()
sitDown(FALSE);
mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject
+ // SL-315
mRoot->setPosition(cur_position_world);
mRoot->setRotation(cur_rotation_world);
mRoot->getXform()->update();
@@ -6119,7 +6678,6 @@ LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj )
return NULL;
}
-// warning: order(N) not order(1)
S32 LLVOAvatar::getAttachmentCount()
{
S32 count = mAttachmentPoints.size();
@@ -7122,11 +7680,10 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)
wtype = vparam->getWearableType();
}
S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight());
- apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\"/>\n",
- viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(),
- LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str()
-// param_location_name(vparam->getParamLocation()).c_str()
- );
+ apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" display=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\" group=\"%d\"/>\n",
+ viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getDisplayName().c_str(), value, u8_value, type_string.c_str(),
+ LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str(),
+ viewer_param->getGroup());
}
@@ -7191,7 +7748,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
U8 av_u8;
mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0);
contents.mAppearanceVersion = av_u8;
- LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL;
+ //LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << LL_ENDL;
mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0);
// For future use:
//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
@@ -7203,7 +7760,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
{
LLVector3 hover;
mesgsys->getVector3Fast(_PREHASH_AppearanceHover, _PREHASH_HoverHeight, hover);
- LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL;
+ //LL_DEBUGS("Avatar") << avString() << " hover received " << hover.mV[ VX ] << "," << hover.mV[ VY ] << "," << hover.mV[ VZ ] << LL_ENDL;
contents.mHoverOffset = hover;
contents.mHoverOffsetWasSet = true;
}
@@ -7213,7 +7770,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
if( num_blocks > 1 && !drop_visual_params_debug)
{
- LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
+ //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
LLVisualParam* param = getFirstVisualParam();
llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
@@ -7274,7 +7831,7 @@ void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMe
{
S32 index = it - contents.mParams.begin();
contents.mParamAppearanceVersion = ll_round(contents.mParamWeights[index]);
- LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL;
+ //LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << LL_ENDL;
}
}
}
@@ -7303,9 +7860,9 @@ bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32
{
appearance_version = 1;
}
- LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion
- << " param: " << contents.mParamAppearanceVersion
- << " final: " << appearance_version << LL_ENDL;
+ //LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion
+ // << " param: " << contents.mParamAppearanceVersion
+ // << " final: " << appearance_version << LL_ENDL;
return true;
}
@@ -7326,17 +7883,15 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
mLastAppearanceMessageTimer.reset();
- ESex old_sex = getSex();
-
- LLAppearanceMessageContents contents;
- parseAppearanceMessage(mesgsys, contents);
+ LLPointer<LLAppearanceMessageContents> contents(new LLAppearanceMessageContents);
+ parseAppearanceMessage(mesgsys, *contents);
if (enable_verbose_dumps)
{
- dumpAppearanceMsgParams(dump_prefix + "appearance_msg", contents);
+ dumpAppearanceMsgParams(dump_prefix + "appearance_msg", *contents);
}
S32 appearance_version;
- if (!resolve_appearance_version(contents, appearance_version))
+ if (!resolve_appearance_version(*contents, appearance_version))
{
LL_WARNS() << "bad appearance version info, discarding" << LL_ENDL;
return;
@@ -7348,7 +7903,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
return;
}
- S32 thisAppearanceVersion(contents.mCOFVersion);
+ S32 thisAppearanceVersion(contents->mCOFVersion);
if (isSelf())
{ // In the past this was considered to be the canonical COF version,
// that is no longer the case. The canonical version is maintained
@@ -7378,7 +7933,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
// SUNSHINE CLEANUP - is this case OK now?
- S32 num_params = contents.mParamWeights.size();
+ S32 num_params = contents->mParamWeights.size();
if (num_params <= 1)
{
// In this case, we have no reliable basis for knowing
@@ -7390,6 +7945,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
// No backsies zone - if we get here, the message should be valid and usable, will be processed.
+ // Note:
+ // RequestAgentUpdateAppearanceResponder::onRequestRequested()
+ // assumes that cof version is only updated with server-bake
+ // appearance messages.
LL_INFOS("Avatar") << "Processing appearance message version " << thisAppearanceVersion << LL_ENDL;
// Note:
@@ -7399,6 +7958,17 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
// of the COF that should be considered canonical.
mLastUpdateReceivedCOFVersion = thisAppearanceVersion;
+ mLastProcessedAppearance = contents;
+
+ bool slam_params = false;
+ applyParsedAppearanceMessage(*contents, slam_params);
+}
+
+void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params)
+{
+ S32 num_params = contents.mParamWeights.size();
+ ESex old_sex = getSex();
+
if (applyParsedTEMessage(contents.mTEContents) > 0 && isChanged(TEXTURE))
{
updateVisualComplexity();
@@ -7428,8 +7998,8 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
mFirstAppearanceMessageReceived = TRUE;
- LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID
- << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
+ //LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID
+ // << " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
if (is_first_appearance_message )
{
@@ -7442,7 +8012,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
// Apply visual params
if( num_params > 1)
{
- LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL;
+ //LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL;
BOOL params_changed = FALSE;
BOOL interp_params = FALSE;
S32 params_changed_count = 0;
@@ -7452,12 +8022,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
LLVisualParam* param = contents.mParams[i];
F32 newWeight = contents.mParamWeights[i];
- if (is_first_appearance_message || (param->getWeight() != newWeight))
+ if (slam_params || is_first_appearance_message || (param->getWeight() != newWeight))
{
params_changed = TRUE;
params_changed_count++;
- if(is_first_appearance_message)
+ if(is_first_appearance_message || slam_params)
{
//LL_DEBUGS("Avatar") << "param slam " << i << " " << newWeight << LL_ENDL;
param->setWeight(newWeight);
@@ -7542,7 +8112,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
}
updateMeshTextures();
- //if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end");
}
// static
@@ -7673,7 +8242,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu
if (selfp)
{
- LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL;
+ //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL;
}
if (!success && selfp)
@@ -7691,14 +8260,14 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success,
LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src,
S32 discard_level, BOOL final, void* userdata)
{
- LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;
+ //LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;
LLUUID id = src_vi->getID();
LLUUID *avatar_idp = (LLUUID *)userdata;
LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
if (selfp)
{
- LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL;
+ //LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << " id " << src_vi->getID() << LL_ENDL;
}
if (selfp && !success)
@@ -7807,6 +8376,40 @@ void dump_sequential_xml(const std::string outprefix, const LLSD& content)
LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL;
}
+void LLVOAvatar::getSortedJointNames(S32 joint_type, std::vector<std::string>& result) const
+{
+ result.clear();
+ if (joint_type==0)
+ {
+ avatar_joint_list_t::const_iterator iter = mSkeleton.begin();
+ avatar_joint_list_t::const_iterator end = mSkeleton.end();
+ for (; iter != end; ++iter)
+ {
+ LLJoint* pJoint = (*iter);
+ result.push_back(pJoint->getName());
+ }
+ }
+ else if (joint_type==1)
+ {
+ for (S32 i = 0; i < mNumCollisionVolumes; i++)
+ {
+ LLAvatarJointCollisionVolume* pJoint = &mCollisionVolumes[i];
+ result.push_back(pJoint->getName());
+ }
+ }
+ else if (joint_type==2)
+ {
+ for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end(); ++iter)
+ {
+ LLViewerJointAttachment* pJoint = iter->second;
+ if (!pJoint) continue;
+ result.push_back(pJoint->getName());
+ }
+ }
+ std::sort(result.begin(), result.end());
+}
+
void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables )
{
std::string outprefix(prefix);
@@ -7886,28 +8489,90 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara
}
}
- avatar_joint_list_t::iterator iter = mSkeleton.begin();
- avatar_joint_list_t::iterator end = mSkeleton.end();
- for (; iter != end; ++iter)
- {
- LLJoint* pJoint = (*iter);
+ // Root joint
+ const LLVector3& pos = mRoot->getPosition();
+ const LLVector3& scale = mRoot->getScale();
+ apr_file_printf( file, "\t\t<root name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ mRoot->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+
+ // Bones
+ std::vector<std::string> bone_names, cv_names, attach_names, all_names;
+ getSortedJointNames(0, bone_names);
+ getSortedJointNames(1, cv_names);
+ getSortedJointNames(2, attach_names);
+ all_names.insert(all_names.end(), bone_names.begin(), bone_names.end());
+ all_names.insert(all_names.end(), cv_names.begin(), cv_names.end());
+ all_names.insert(all_names.end(), attach_names.begin(), attach_names.end());
+
+ for (std::vector<std::string>::iterator name_iter = bone_names.begin();
+ name_iter != bone_names.end(); ++name_iter)
+ {
+ LLJoint *pJoint = getJoint(*name_iter);
const LLVector3& pos = pJoint->getPosition();
const LLVector3& scale = pJoint->getScale();
- apr_file_printf( file, "\t\t<joint name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ apr_file_printf( file, "\t\t<bone name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
- }
+ }
- for (iter = mSkeleton.begin(); iter != end; ++iter)
- {
- LLJoint* pJoint = (*iter);
+ // Collision volumes
+ for (std::vector<std::string>::iterator name_iter = cv_names.begin();
+ name_iter != cv_names.end(); ++name_iter)
+ {
+ LLJoint *pJoint = getJoint(*name_iter);
+ const LLVector3& pos = pJoint->getPosition();
+ const LLVector3& scale = pJoint->getScale();
+ apr_file_printf( file, "\t\t<collision_volume name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+ }
+
+ // Attachment joints
+ for (std::vector<std::string>::iterator name_iter = attach_names.begin();
+ name_iter != attach_names.end(); ++name_iter)
+ {
+ LLJoint *pJoint = getJoint(*name_iter);
+ if (!pJoint) continue;
+ const LLVector3& pos = pJoint->getPosition();
+ const LLVector3& scale = pJoint->getScale();
+ apr_file_printf( file, "\t\t<attachment_point name=\"%s\" position=\"%f %f %f\" scale=\"%f %f %f\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], scale[0], scale[1], scale[2]);
+ }
+
+ // Joint pos overrides
+ for (std::vector<std::string>::iterator name_iter = all_names.begin();
+ name_iter != all_names.end(); ++name_iter)
+ {
+ LLJoint *pJoint = getJoint(*name_iter);
LLVector3 pos;
LLUUID mesh_id;
- if (pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ if (pJoint && pJoint->hasAttachmentPosOverride(pos,mesh_id))
+ {
+ S32 num_pos_overrides;
+ std::set<LLVector3> distinct_pos_overrides;
+ pJoint->getAllAttachmentPosOverrides(num_pos_overrides, distinct_pos_overrides);
+ apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n",
+ pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str(),
+ num_pos_overrides, (S32) distinct_pos_overrides.size());
+ }
+ }
+ // Joint scale overrides
+ for (std::vector<std::string>::iterator name_iter = all_names.begin();
+ name_iter != all_names.end(); ++name_iter)
+ {
+ LLJoint *pJoint = getJoint(*name_iter);
+
+ LLVector3 scale;
+ LLUUID mesh_id;
+
+ if (pJoint && pJoint->hasAttachmentScaleOverride(scale,mesh_id))
{
- apr_file_printf( file, "\t\t<joint_offset name=\"%s\" position=\"%f %f %f\" mesh_id=\"%s\"/>\n",
- pJoint->getName().c_str(), pos[0], pos[1], pos[2], mesh_id.asString().c_str());
+ S32 num_scale_overrides;
+ std::set<LLVector3> distinct_scale_overrides;
+ pJoint->getAllAttachmentPosOverrides(num_scale_overrides, distinct_scale_overrides);
+ apr_file_printf( file, "\t\t<joint_scale name=\"%s\" scale=\"%f %f %f\" mesh_id=\"%s\" count=\"%d\" distinct=\"%d\"/>\n",
+ pJoint->getName().c_str(), scale[0], scale[1], scale[2], mesh_id.asString().c_str(),
+ num_scale_overrides, (S32) distinct_scale_overrides.size());
}
}
F32 pelvis_fixup;
@@ -8504,7 +9169,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
&& (all_textures.find(image_id) == all_textures.end()))
{
// attachment texture not previously seen.
- LL_INFOS() << "attachment_texture: " << image_id.asString() << LL_ENDL;
+ LL_DEBUGS("ARCdetail") << "attachment_texture: " << image_id.asString() << LL_ENDL;
all_textures.insert(image_id);
}
}
@@ -8524,7 +9189,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
continue;
if (all_textures.find(image_id) == all_textures.end())
{
- LL_INFOS() << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL;
+ LL_DEBUGS("ARCdetail") << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL;
all_textures.insert(image_id);
}
}