From 493d3b36517fdc82b6a9e99c1ff66742557b971e Mon Sep 17 00:00:00 2001
From: Todd Stinson <stinson@lindenlab.com>
Date: Mon, 6 Aug 2012 17:08:57 -0700
Subject: [PATCH] PATH-842, VWR-29431: BUGFIX Correcting a regression
 introduced by the fix for PATH-542.  The viewer calculated rotation resulting
 from an object's angular velocity was being incorrectly reset when the
 corresponding object update was received.  With this bugfix, the rotation
 resulting from the angular velocity is accumulated separately and is
 re-appplied when the object update resets the object's rotation.

---
 indra/newview/llviewerobject.cpp | 20 +++++++++++++++-----
 indra/newview/llviewerobject.h   |  1 +
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 31e4fd1ed55..fc8192f14b4 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -236,6 +236,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mNumFaces(0),
 	mTimeDilation(1.f),
 	mRotTime(0.f),
+	mAngularVelocityRot(),
 	mJointInfo(NULL),
 	mState(0),
 	mMedia(NULL),
@@ -266,6 +267,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	{
 		mPositionAgent = mRegionp->getOriginAgent();
 	}
+	resetRot();
 
 	LLViewerObject::sNumObjects++;
 }
@@ -2071,14 +2073,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 	if (new_rot != getRotation()
 		|| new_angv != old_angv)
 	{
-		if (new_rot != getRotation())
+		if (new_angv != old_angv)
 		{
-			setRotation(new_rot);
+			resetRot();
 		}
-		
+
+		// Set the rotation of the object followed by adjusting for the accumulated angular velocity (llSetTargetOmega)
+		setRotation(new_rot * mAngularVelocityRot);
 		setChanged(ROTATED | SILHOUETTE);
-		
-		resetRot();
 	}
 
 
@@ -5533,8 +5535,13 @@ void LLViewerObject::applyAngularVelocity(F32 dt)
 
 		ang_vel *= 1.f/omega;
 		
+		// calculate the delta increment based on the object's angular velocity
 		dQ.setQuat(angle, ang_vel);
+
+		// accumulate the angular velocity rotations to re-apply in the case of an object update
+		mAngularVelocityRot *= dQ;
 		
+		// Just apply the delta increment to the current rotation
 		setRotation(getRotation()*dQ);
 		setChanged(MOVED | SILHOUETTE);
 	}
@@ -5543,6 +5550,9 @@ void LLViewerObject::applyAngularVelocity(F32 dt)
 void LLViewerObject::resetRot()
 {
 	mRotTime = 0.0f;
+
+	// Reset the accumulated angular velocity rotation
+	mAngularVelocityRot.loadIdentity(); 
 }
 
 U32 LLViewerObject::getPartitionType() const
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index f8f63277504..530d6531f3f 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -735,6 +735,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 
 	F32				mTimeDilation;				// Time dilation sent with the object.
 	F32				mRotTime;					// Amount (in seconds) that object has rotated according to angular velocity (llSetTargetOmega)
+	LLQuaternion	mAngularVelocityRot;		// accumulated rotation from the angular velocity computations
 
 	LLVOJointInfo*  mJointInfo;
 	U8				mState;	// legacy
-- 
GitLab