From 08f35b6a14f4643f8110e3940f061b1319a1bb32 Mon Sep 17 00:00:00 2001
From: Ansariel <none@none>
Date: Thu, 26 Jul 2012 17:07:12 +0200
Subject: STORM-1899: Avatar hand poses randomly get stuck in spread position

---
 doc/contributions.txt              |  1 +
 indra/llcharacter/llhandmotion.cpp | 60 ++++++++++++++++++++++++++++++++++----
 2 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index df504e4a8a..08214fe196 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -174,6 +174,7 @@ Ansariel Hiller
 	VWR-26150
 	STORM-1685
 	STORM-1713
+	STORM-1899
 Aralara Rajal
 Ardy Lay
 	STORM-859
diff --git a/indra/llcharacter/llhandmotion.cpp b/indra/llcharacter/llhandmotion.cpp
index 63937d8255..696dba0d95 100644
--- a/indra/llcharacter/llhandmotion.cpp
+++ b/indra/llcharacter/llhandmotion.cpp
@@ -132,18 +132,68 @@ BOOL LLHandMotion::onUpdate(F32 time, U8* joint_mask)
 	{
 		if (mNewPose != HAND_POSE_RELAXED && mNewPose != mCurrentPose)
 		{
-			mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+			// Only set param weight for poses other than
+			// default (HAND_POSE_SPREAD); HAND_POSE_SPREAD
+			// is not an animatable morph!
+			if (mNewPose != HAND_POSE_SPREAD)
+			{
+				mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+			}
+
+			// Reset morph weight for current pose back to its
+			// full extend or it might be stuck somewhere in the middle if a
+			// pose is requested and the old pose is requested again shortly
+			// after while still blending to the other pose!
+			if (mCurrentPose != HAND_POSE_SPREAD)
+			{
+				mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
+			}
+
+			// Update visual params now if we won't blend
+			if (mCurrentPose == HAND_POSE_RELAXED)
+			{
+				mCharacter->updateVisualParams();
+			}
 		}
 		mNewPose = HAND_POSE_RELAXED;
 	}
 	else
 	{
-		// this is a new morph we didn't know about before
-		if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose && mNewPose != HAND_POSE_SPREAD)
+		// Sometimes we seem to get garbage here, with poses that are out of bounds.
+		// So check for a valid pose first.
+		if (*requestedHandPose >= 0 && *requestedHandPose < NUM_HAND_POSES)
+		{
+			// This is a new morph we didn't know about before:
+			// Reset morph weight for both current and new pose
+			// back their starting values while still blending.
+			if (*requestedHandPose != mNewPose && mNewPose != mCurrentPose)
+			{
+				if (mNewPose != HAND_POSE_SPREAD)
+				{
+					mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+				}
+
+				// Reset morph weight for current pose back to its full extend
+				// or it might be stuck somewhere in the middle if a pose is
+				// requested and the old pose is requested again shortly after
+				// while still blending to the other pose!
+				if (mCurrentPose != HAND_POSE_SPREAD)
+				{
+					mCharacter->setVisualParamWeight(gHandPoseNames[mCurrentPose], 1.f);
+				}
+
+				// Update visual params now if we won't blend
+				if (mCurrentPose == *requestedHandPose)
+				{
+					mCharacter->updateVisualParams();
+				}
+			}
+			mNewPose = *requestedHandPose;
+		}
+		else
 		{
-			mCharacter->setVisualParamWeight(gHandPoseNames[mNewPose], 0.f);
+			llwarns << "Requested hand pose out of range. Ignoring requested pose." << llendl;
 		}
-		mNewPose = *requestedHandPose;
 	}
 
 	mCharacter->removeAnimationData("Hand Pose");
-- 
cgit v1.2.3