diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 5dd42152061d906b569d37de669e6a7775df626f..68b5a3401e6d0883bed98683b34e31e0734fff37 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -296,7 +296,6 @@ void LLAgent::cleanup()
 {
 	mAvatarObject = NULL;
 	mRegionp = NULL;
-	gAgentCamera.cleanup();
 }
 
 //-----------------------------------------------------------------------------
@@ -1645,24 +1644,8 @@ void LLAgent::setAvatarObject(LLVOAvatarSelf *avatar)
 		llinfos << "Setting LLAgent::mAvatarObject to NULL" << llendl;
 		return;
 	}
-
-	if (!gAgentCamera.mLookAt)
-	{
-		gAgentCamera.mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
-	}
-	if (!gAgentCamera.mPointAt)
-	{
-		gAgentCamera.mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
-	}
 	
-	if (!gAgentCamera.mLookAt.isNull())
-	{
-		gAgentCamera.mLookAt->setSourceObject(avatar);
-	}
-	if (!gAgentCamera.mPointAt.isNull())
-	{
-		gAgentCamera.mPointAt->setSourceObject(avatar);
-	}
+	gAgentCamera.setCameraAvatarObject(avatar);
 }
 
 // TRUE if your own avatar needs to be rendered.  Usually only
@@ -1863,8 +1846,7 @@ void LLAgent::endAnimationUpdateUI()
 			}
 		}
 	}
-	else
-	if(gAgentCamera.mLastCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
+	else if(gAgentCamera.mLastCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
 		// make sure we ask to save changes
 
@@ -2028,83 +2010,6 @@ void LLAgent::heardChat(const LLUUID& id)
 	mChatTimer.reset();
 }
 
-//-----------------------------------------------------------------------------
-// lookAtLastChat()
-//-----------------------------------------------------------------------------
-void LLAgent::lookAtLastChat()
-{
-	// Block if camera is animating or not in normal third person camera mode
-	if (gAgentCamera.mCameraAnimating || !gAgentCamera.cameraThirdPerson())
-	{
-		return;
-	}
-
-	LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
-	if (chatter)
-	{
-		LLVector3 delta_pos;
-		if (chatter->isAvatar())
-		{
-			LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
-			if (mAvatarObject.notNull() && chatter_av->mHeadp)
-			{
-				delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition();
-			}
-			else
-			{
-				delta_pos = chatter->getPositionAgent() - getPositionAgent();
-			}
-			delta_pos.normalize();
-
-			setControlFlags(AGENT_CONTROL_STOP);
-
-			gAgentCamera.changeCameraToThirdPerson();
-
-			LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
-			LLVector3 left = delta_pos % LLVector3::z_axis;
-			left.normalize();
-			LLVector3 up = left % delta_pos;
-			up.normalize();
-			new_camera_pos -= delta_pos * 0.4f;
-			new_camera_pos += left * 0.3f;
-			new_camera_pos += up * 0.2f;
-			if (chatter_av->mHeadp)
-			{
-				gAgentCamera.setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), mLastChatterID);
-				gAgentCamera.mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
-			}
-			else
-			{
-				gAgentCamera.setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
-				gAgentCamera.mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
-			}
-			gAgentCamera.setFocusOnAvatar(FALSE, TRUE);
-		}
-		else
-		{
-			delta_pos = chatter->getRenderPosition() - getPositionAgent();
-			delta_pos.normalize();
-
-			setControlFlags(AGENT_CONTROL_STOP);
-
-			gAgentCamera.changeCameraToThirdPerson();
-
-			LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
-			LLVector3 left = delta_pos % LLVector3::z_axis;
-			left.normalize();
-			LLVector3 up = left % delta_pos;
-			up.normalize();
-			new_camera_pos -= delta_pos * 0.4f;
-			new_camera_pos += left * 0.3f;
-			new_camera_pos += up * 0.2f;
-
-			gAgentCamera.setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
-			gAgentCamera.mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
-			gAgentCamera.setFocusOnAvatar(FALSE, TRUE);
-		}
-	}
-}
-
 const F32 SIT_POINT_EXTENTS = 0.2f;
 
 LLSD ll_sdmap_from_vector3(const LLVector3& vec)
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 1b378ef7b286a81571fbe156a098337f47d3882a..891ce799d22be6535f7ac919758e87885532ff1b 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -95,7 +95,6 @@ class LLAgent : public LLOldEvents::LLObservable
 
 public:
 	friend class LLAgentDropGroupViewerNode;
-	friend class LLAgentCamera;
 
 /********************************************************************************
  **                                                                            **
@@ -261,6 +260,10 @@ class LLAgent : public LLOldEvents::LLObservable
 public:
 	S32				getRegionsVisited() const;
 	F64				getDistanceTraveled() const;	
+	void			setDistanceTraveled(F64 dist) { mDistanceTraveled = dist; }
+	
+	const LLVector3d &getLastPositionGlobal() const { return mLastPositionGlobal; }
+	void			setLastPositionGlobal(const LLVector3d &pos) { mLastPositionGlobal = pos; }
 private:
 	std::set<U64>	mRegionsVisited;		// Stat - what distinct regions has the avatar been to?
 	F64				mDistanceTraveled;		// Stat - how far has the avatar moved?
@@ -303,7 +306,6 @@ class LLAgent : public LLOldEvents::LLObservable
 	//--------------------------------------------------------------------
 public:
 	void			heardChat(const LLUUID& id);
-	void			lookAtLastChat();
 	F32				getTypingTime() 		{ return mTypingTimer.getElapsedTimeF32(); }
 	LLUUID			getLastChatter() const 	{ return mLastChatterID; }
 	F32				getNearChatRadius() 	{ return mNearChatRadius; }
@@ -412,6 +414,8 @@ class LLAgent : public LLOldEvents::LLObservable
 	// Send message to simulator to force grabbed controls to be
 	// released, in case of a poorly written script.
 	void			forceReleaseControls();
+	void			setFlagsDirty() { mbFlagsDirty = TRUE; }
+
 private:
 	S32				mControlsTakenCount[TOTAL_CONTROLS];
 	S32				mControlsTakenPassedOnCount[TOTAL_CONTROLS];
@@ -429,6 +433,10 @@ class LLAgent : public LLOldEvents::LLObservable
 	void			sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request);
 	void			sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request);
 	void			endAnimationUpdateUI();
+	void			unpauseAnimation() { mPauseRequest = NULL; }
+	BOOL			getCustomAnim() const { return mCustomAnim; }
+	void			setCustomAnim(BOOL anim) { mCustomAnim = anim; }
+	
 private:
 	BOOL            mCustomAnim; 		// Current animation is ANIM_AGENT_CUSTOMIZE ?
 	LLAnimPauseRequest mPauseRequest;
@@ -656,6 +664,9 @@ class LLAgent : public LLOldEvents::LLObservable
 	LLQuaternion	getHeadRotation();
 	BOOL			needsRenderAvatar(); // TRUE when camera mode is such that your own avatar should draw
 	BOOL			needsRenderHead();
+	void			setShowAvatar(BOOL show) { mShowAvatar = show; }
+	BOOL			getShowAvatar() const { return mShowAvatar; }
+	
 private:
 	BOOL			mShowAvatar; 		// Should we render the avatar?
 	U32				mAppearanceSerialNum;
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index c51edbaf4b3d0b386ec290ed5a8489b8f6ce3ee5..07757c202577f857538421c861385496c5e3681e 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -256,6 +256,27 @@ void LLAgentCamera::cleanup()
 	setFocusObject(NULL);
 }
 
+void LLAgentCamera::setCameraAvatarObject(LLVOAvatarSelf* avatar)
+{
+	if (!mLookAt)
+	{
+		mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
+	}
+	if (!mPointAt)
+	{
+		mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
+	}
+	
+	if (!mLookAt.isNull())
+	{
+		mLookAt->setSourceObject(avatar);
+	}
+	if (!mPointAt.isNull())
+	{
+		mPointAt->setSourceObject(avatar);
+	}	
+}
+
 //-----------------------------------------------------------------------------
 // LLAgent()
 //-----------------------------------------------------------------------------
@@ -273,7 +294,7 @@ LLAgentCamera::~LLAgentCamera()
 //-----------------------------------------------------------------------------
 void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
 {
-	if (gAgent.mAutoPilot)
+	if (gAgent.getAutoPilot())
 	{
 		gAgent.stopAutoPilot(TRUE);
 	}
@@ -351,9 +372,10 @@ void LLAgentCamera::unlockView()
 {
 	if (getFocusOnAvatar())
 	{
-		if (gAgent.mAvatarObject.notNull())
+		LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+		if (avatarp)
 		{
-			setFocusGlobal( LLVector3d::zero, gAgent.mAvatarObject->mID );
+			setFocusGlobal(LLVector3d::zero, avatarp->mID);
 		}
 		setFocusOnAvatar(FALSE, FALSE);	// no animation
 	}
@@ -830,7 +852,7 @@ void LLAgentCamera::cameraOrbitAround(const F32 radians)
 	}
 	else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW))
 	{
-		gAgent.mFrameAgent.rotate(radians, gAgent.getReferenceUpVector());
+		gAgent.getFrameAgent().rotate(radians, gAgent.getReferenceUpVector());
 	}
 	else
 	{
@@ -1070,29 +1092,30 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 {
 	static LLVector3 last_at_axis;
 
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
 
-	if (gAgent.mAvatarObject.isNull())
+	if (!avatarp)
 	{
 		return;
 	}
 
-	LLQuaternion av_inv_rot = ~gAgent.mAvatarObject->mRoot.getWorldRotation();
-	LLVector3 root_at = LLVector3::x_axis * gAgent.mAvatarObject->mRoot.getWorldRotation();
+	LLQuaternion av_inv_rot = ~avatarp->mRoot.getWorldRotation();
+	LLVector3 root_at = LLVector3::x_axis * avatarp->mRoot.getWorldRotation();
 
 	if 	((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
-		(root_at * last_at_axis > 0.95f ))
+		 (root_at * last_at_axis > 0.95f))
 	{
-		LLVector3 vel = gAgent.mAvatarObject->getVelocity();
+		LLVector3 vel = avatarp->getVelocity();
 		if (vel.magVecSquared() > 4.f)
 		{
-			setLookAt(LOOKAT_TARGET_IDLE, gAgent.mAvatarObject, vel * av_inv_rot);
+			setLookAt(LOOKAT_TARGET_IDLE, avatarp, vel * av_inv_rot);
 		}
 		else
 		{
 			// *FIX: rotate mframeagent by sit object's rotation?
-			LLQuaternion look_rotation = gAgent.mAvatarObject->isSitting() ? gAgent.mAvatarObject->getRenderRotation() : gAgent.mFrameAgent.getQuaternion(); // use camera's current rotation
+			LLQuaternion look_rotation = avatarp->isSitting() ? avatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); // use camera's current rotation
 			LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot;
-			setLookAt(LOOKAT_TARGET_IDLE, gAgent.mAvatarObject, look_offset);
+			setLookAt(LOOKAT_TARGET_IDLE, avatarp, look_offset);
 		}
 		last_at_axis = root_at;
 		return;
@@ -1102,7 +1125,7 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 	
 	if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
 	{
-		setLookAt(LOOKAT_TARGET_NONE, gAgent.mAvatarObject, LLVector3(-2.f, 0.f, 0.f));	
+		setLookAt(LOOKAT_TARGET_NONE, avatarp, LLVector3(-2.f, 0.f, 0.f));	
 	}
 	else
 	{
@@ -1131,7 +1154,7 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 		headLookAxis = frameCamera.getAtAxis();
 		// RN: we use world-space offset for mouselook and freelook
 		//headLookAxis = headLookAxis * av_inv_rot;
-		setLookAt(lookAtType, gAgent.mAvatarObject, headLookAxis);
+		setLookAt(lookAtType, avatarp, headLookAxis);
 	}
 }
 
@@ -1152,13 +1175,15 @@ void LLAgentCamera::updateCamera()
 
 	validateFocusObject();
 
-	if (gAgent.mAvatarObject.notNull() && 
-		gAgent.mAvatarObject->isSitting() &&
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+
+	if (avatarp && 
+		avatarp->isSitting() &&
 		camera_mode == CAMERA_MODE_MOUSELOOK)
 	{
 		//Ventrella
 		//changed camera_skyward to the new global "mCameraUpVector"
-		mCameraUpVector = mCameraUpVector * gAgent.mAvatarObject->getRenderRotation();
+		mCameraUpVector = mCameraUpVector * avatarp->getRenderRotation();
 		//end Ventrella
 	}
 
@@ -1266,7 +1291,7 @@ void LLAgentCamera::updateCamera()
 	//Ventrella
 	if ( mCameraMode == CAMERA_MODE_FOLLOW )
 	{
-		if ( gAgent.mAvatarObject.notNull() )
+		if (avatarp)
 		{
 			//--------------------------------------------------------------------------------
 			// this is where the avatar's position and rotation are given to followCam, and 
@@ -1274,13 +1299,13 @@ void LLAgentCamera::updateCamera()
 			// (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent.
 			//--------------------------------------------------------------------------------
 			// *TODO: use combined rotation of frameagent and sit object
-			LLQuaternion avatarRotationForFollowCam = gAgent.mAvatarObject->isSitting() ? gAgent.mAvatarObject->getRenderRotation() : gAgent.mFrameAgent.getQuaternion();
+			LLQuaternion avatarRotationForFollowCam = avatarp->isSitting() ? avatarp->getRenderRotation() : gAgent.getFrameAgent().getQuaternion();
 
 			LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams();
 			if (current_cam)
 			{
 				mFollowCam.copyParams(*current_cam);
-				mFollowCam.setSubjectPositionAndRotation( gAgent.mAvatarObject->getRenderPosition(), avatarRotationForFollowCam );
+				mFollowCam.setSubjectPositionAndRotation( avatarp->getRenderPosition(), avatarRotationForFollowCam );
 				mFollowCam.update();
 				LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
 			}
@@ -1302,7 +1327,7 @@ void LLAgentCamera::updateCamera()
 	mCameraFOVZoomFactor = calcCameraFOVZoomFactor();
 	camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor);
 
-	gAgent.mShowAvatar = TRUE; // can see avatar by default
+	gAgent.setShowAvatar(TRUE); // can see avatar by default
 
 	// Adjust position for animation
 	if (mCameraAnimating)
@@ -1335,7 +1360,7 @@ void LLAgentCamera::updateCamera()
 		{
 			if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction )
 			{
-				gAgent.mShowAvatar = FALSE;
+				gAgent.setShowAvatar(FALSE);
 			}
 
 			// ...adjust position for animation
@@ -1352,19 +1377,19 @@ void LLAgentCamera::updateCamera()
 			mFocusGlobal = focus_target_global;
 
 			gAgent.endAnimationUpdateUI();
-			gAgent.mShowAvatar = TRUE;
+			gAgent.setShowAvatar(TRUE);
 		}
 
-		if (gAgent.getAvatarObject() && mCameraMode != CAMERA_MODE_MOUSELOOK)
+		if (avatarp && (mCameraMode != CAMERA_MODE_MOUSELOOK))
 		{
-			gAgent.getAvatarObject()->updateAttachmentVisibility(mCameraMode);
+			avatarp->updateAttachmentVisibility(mCameraMode);
 		}
 	}
 	else 
 	{
 		camera_pos_global = camera_target_global;
 		mFocusGlobal = focus_target_global;
-		gAgent.mShowAvatar = TRUE;
+		gAgent.setShowAvatar(TRUE);
 	}
 
 	// smoothing
@@ -1448,47 +1473,47 @@ void LLAgentCamera::updateCamera()
 	// this isn't directly related to the camera
 	// but this seemed like the best place to do this
 	LLVector3d global_pos = gAgent.getPositionGlobal(); 
-	if (! gAgent.mLastPositionGlobal.isExactlyZero())
+	if (!gAgent.getLastPositionGlobal().isExactlyZero())
 	{
-		LLVector3d delta = global_pos - gAgent.mLastPositionGlobal;
-		gAgent.mDistanceTraveled += delta.magVec();
+		LLVector3d delta = global_pos - gAgent.getLastPositionGlobal();
+		gAgent.setDistanceTraveled(gAgent.getDistanceTraveled() + delta.magVec());
 	}
-	gAgent.mLastPositionGlobal = global_pos;
+	gAgent.setLastPositionGlobal(global_pos);
 	
-	if (LLVOAvatar::sVisibleInFirstPerson && gAgent.mAvatarObject.notNull() && !gAgent.mAvatarObject->isSitting() && cameraMouselook())
+	if (LLVOAvatar::sVisibleInFirstPerson && avatarp && !avatarp->isSitting() && cameraMouselook())
 	{
-		LLVector3 head_pos = gAgent.mAvatarObject->mHeadp->getWorldPosition() + 
-			LLVector3(0.08f, 0.f, 0.05f) * gAgent.mAvatarObject->mHeadp->getWorldRotation() + 
-			LLVector3(0.1f, 0.f, 0.f) * gAgent.mAvatarObject->mPelvisp->getWorldRotation();
+		LLVector3 head_pos = avatarp->mHeadp->getWorldPosition() + 
+			LLVector3(0.08f, 0.f, 0.05f) * avatarp->mHeadp->getWorldRotation() + 
+			LLVector3(0.1f, 0.f, 0.f) * avatarp->mPelvisp->getWorldRotation();
 		LLVector3 diff = mCameraPositionAgent - head_pos;
-		diff = diff * ~gAgent.mAvatarObject->mRoot.getWorldRotation();
+		diff = diff * ~avatarp->mRoot.getWorldRotation();
 
-		LLJoint* torso_joint = gAgent.mAvatarObject->mTorsop;
-		LLJoint* chest_joint = gAgent.mAvatarObject->mChestp;
+		LLJoint* torso_joint = avatarp->mTorsop;
+		LLJoint* chest_joint = avatarp->mChestp;
 		LLVector3 torso_scale = torso_joint->getScale();
 		LLVector3 chest_scale = chest_joint->getScale();
 
 		// shorten avatar skeleton to avoid foot interpenetration
-		if (!gAgent.mAvatarObject->mInAir)
+		if (!avatarp->mInAir)
 		{
 			LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation();
 			F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f);
 			F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f);
 			torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
 
-			LLJoint* neck_joint = gAgent.mAvatarObject->mNeckp;
+			LLJoint* neck_joint = avatarp->mNeckp;
 			LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation();
 			scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f);
 			chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
 			diff.mV[VZ] = 0.f;
 		}
 
-		gAgent.mAvatarObject->mPelvisp->setPosition(gAgent.mAvatarObject->mPelvisp->getPosition() + diff);
+		avatarp->mPelvisp->setPosition(avatarp->mPelvisp->getPosition() + diff);
 
-		gAgent.mAvatarObject->mRoot.updateWorldMatrixChildren();
+		avatarp->mRoot.updateWorldMatrixChildren();
 
-		for (LLVOAvatar::attachment_map_t::iterator iter = gAgent.mAvatarObject->mAttachmentPoints.begin(); 
-			 iter != gAgent.mAvatarObject->mAttachmentPoints.end(); )
+		for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); 
+			 iter != avatarp->mAttachmentPoints.end(); )
 		{
 			LLVOAvatar::attachment_map_t::iterator curiter = iter++;
 			LLViewerJointAttachment* attachment = curiter->second;
@@ -1525,7 +1550,7 @@ void LLAgentCamera::updateFocusOffset()
 void LLAgentCamera::validateFocusObject()
 {
 	if (mFocusObject.notNull() && 
-		(mFocusObject->isDead()))
+		mFocusObject->isDead())
 	{
 		mFocusObjectOffset.clearVec();
 		clearFocusObject();
@@ -1536,11 +1561,11 @@ void LLAgentCamera::validateFocusObject()
 //-----------------------------------------------------------------------------
 // calcCustomizeAvatarUIOffset()
 //-----------------------------------------------------------------------------
-F32 LLAgentCamera::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global )
+F32 LLAgentCamera::calcCustomizeAvatarUIOffset(const LLVector3d& camera_pos_global)
 {
 	F32 ui_offset = 0.f;
 
-	if( gFloaterCustomize )
+	if (gFloaterCustomize)
 	{
 		const LLRect& rect = gFloaterCustomize->getRect();
 
@@ -1575,8 +1600,10 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 		clearFocusObject();
 	}
 
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+
 	// Ventrella
-	if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
+	if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar)
 	{
 		mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
 		return mFocusTargetGlobal;
@@ -1584,13 +1611,13 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 	else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
 	{
 		LLVector3d at_axis(1.0, 0.0, 0.0);
-		LLQuaternion agent_rot = gAgent.mFrameAgent.getQuaternion();
-		if (gAgent.mAvatarObject.notNull() && gAgent.mAvatarObject->getParent())
+		LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
+		if (avatarp && avatarp->getParent())
 		{
-			LLViewerObject* root_object = (LLViewerObject*)gAgent.mAvatarObject->getRoot();
+			LLViewerObject* root_object = (LLViewerObject*)avatarp->getRoot();
 			if (!root_object->flagCameraDecoupled())
 			{
-				agent_rot *= ((LLViewerObject*)(gAgent.mAvatarObject->getParent()))->getRenderRotation();
+				agent_rot *= ((LLViewerObject*)(avatarp->getParent()))->getRenderRotation();
 			}
 		}
 		at_axis = at_axis * agent_rot;
@@ -1640,7 +1667,7 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 		}
 		return mFocusTargetGlobal;
 	}
-	else if (mSitCameraEnabled && gAgent.mAvatarObject.notNull() && gAgent.mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull())
+	else if (mSitCameraEnabled && avatarp && avatarp->isSitting() && mSitCameraReferenceObject.notNull())
 	{
 		// sit camera
 		LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
@@ -1660,10 +1687,11 @@ LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
 	// ...offset from avatar
 	LLVector3d focus_offset;
 
-	LLQuaternion agent_rot = gAgent.mFrameAgent.getQuaternion();
-	if (!gAgent.mAvatarObject.isNull() && gAgent.mAvatarObject->getParent())
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+	LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
+	if (avatarp && avatarp->getParent())
 	{
-		agent_rot *= ((LLViewerObject*)(gAgent.mAvatarObject->getParent()))->getRenderRotation();
+		agent_rot *= ((LLViewerObject*)(avatarp->getParent()))->getRenderRotation();
 	}
 
 	focus_offset = mFocusOffsetInitial[mCameraPreset] * agent_rot;
@@ -1672,12 +1700,14 @@ LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
 
 void LLAgentCamera::setupSitCamera()
 {
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+
 	// agent frame entering this function is in world coordinates
-	if (gAgent.mAvatarObject.notNull() && gAgent.mAvatarObject->getParent())
+	if (avatarp && avatarp->getParent())
 	{
-		LLQuaternion parent_rot = ((LLViewerObject*)gAgent.mAvatarObject->getParent())->getRenderRotation();
+		LLQuaternion parent_rot = ((LLViewerObject*)avatarp->getParent())->getRenderRotation();
 		// slam agent coordinate frame to proper parent local version
-		LLVector3 at_axis = gAgent.mFrameAgent.getAtAxis();
+		LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis();
 		at_axis.mV[VZ] = 0.f;
 		at_axis.normalize();
 		gAgent.resetAxes(at_axis * ~parent_rot);
@@ -1738,11 +1768,14 @@ F32	LLAgentCamera::calcCameraFOVZoomFactor()
 //-----------------------------------------------------------------------------
 LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 {
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+
 	// Compute base camera position and look-at points.
 	F32			camera_land_height;
-	LLVector3d	frame_center_global = gAgent.mAvatarObject.isNull() ? gAgent.getPositionGlobal() 
-															 : gAgent.getPosGlobalFromAgent(gAgent.mAvatarObject->mRoot.getWorldPosition());
-		
+	LLVector3d	frame_center_global = !avatarp ? 
+		gAgent.getPositionGlobal() :
+		gAgent.getPosGlobalFromAgent(avatarp->mRoot.getWorldPosition());
+	
 	BOOL		isConstrained = FALSE;
 	LLVector3d	head_offset;
 	head_offset.setVec(mThirdPersonHeadOffset);
@@ -1750,38 +1783,38 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 	LLVector3d camera_position_global;
 
 	// Ventrella 
-	if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
+	if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar)
 	{
 		camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
 	}// End Ventrella
 	else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
 	{
-		if (gAgent.mAvatarObject.isNull() || gAgent.mAvatarObject->mDrawable.isNull())
+		if (!avatarp || avatarp->mDrawable.isNull())
 		{
 			llwarns << "Null avatar drawable!" << llendl;
 			return LLVector3d::zero;
 		}
 		head_offset.clearVec();
-		if (gAgent.mAvatarObject->isSitting() && gAgent.mAvatarObject->getParent())
+		if (avatarp->isSitting() && avatarp->getParent())
 		{
-			gAgent.mAvatarObject->updateHeadOffset();
-			head_offset.mdV[VX] = gAgent.mAvatarObject->mHeadOffset.mV[VX];
-			head_offset.mdV[VY] = gAgent.mAvatarObject->mHeadOffset.mV[VY];
-			head_offset.mdV[VZ] = gAgent.mAvatarObject->mHeadOffset.mV[VZ] + 0.1f;
-			const LLMatrix4& mat = ((LLViewerObject*) gAgent.mAvatarObject->getParent())->getRenderMatrix();
+			avatarp->updateHeadOffset();
+			head_offset.mdV[VX] = avatarp->mHeadOffset.mV[VX];
+			head_offset.mdV[VY] = avatarp->mHeadOffset.mV[VY];
+			head_offset.mdV[VZ] = avatarp->mHeadOffset.mV[VZ] + 0.1f;
+			const LLMatrix4& mat = ((LLViewerObject*) avatarp->getParent())->getRenderMatrix();
 			camera_position_global = gAgent.getPosGlobalFromAgent
-								((gAgent.mAvatarObject->getPosition()+
-								 LLVector3(head_offset)*gAgent.mAvatarObject->getRotation()) * mat);
+								((avatarp->getPosition()+
+								 LLVector3(head_offset)*avatarp->getRotation()) * mat);
 		}
 		else
 		{
-			head_offset.mdV[VZ] = gAgent.mAvatarObject->mHeadOffset.mV[VZ];
-			if (gAgent.mAvatarObject->isSitting())
+			head_offset.mdV[VZ] = avatarp->mHeadOffset.mV[VZ];
+			if (avatarp->isSitting())
 			{
 				head_offset.mdV[VZ] += 0.1;
 			}
-			camera_position_global = gAgent.getPosGlobalFromAgent(gAgent.mAvatarObject->getRenderPosition());//frame_center_global;
-			head_offset = head_offset * gAgent.mAvatarObject->getRenderRotation();
+			camera_position_global = gAgent.getPosGlobalFromAgent(avatarp->getRenderPosition());//frame_center_global;
+			head_offset = head_offset * avatarp->getRenderRotation();
 			camera_position_global = camera_position_global + head_offset;
 		}
 	}
@@ -1791,8 +1824,8 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 		F32 camera_distance = 0.f;
 
 		if (mSitCameraEnabled 
-			&& gAgent.mAvatarObject.notNull() 
-			&& gAgent.mAvatarObject->isSitting() 
+			&& avatarp 
+			&& avatarp->isSitting() 
 			&& mSitCameraReferenceObject.notNull())
 		{
 			// sit camera
@@ -1808,23 +1841,23 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 			local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale");
 			
 			// are we sitting down?
-			if (gAgent.mAvatarObject.notNull() && gAgent.mAvatarObject->getParent())
+			if (avatarp && avatarp->getParent())
 			{
-				LLQuaternion parent_rot = ((LLViewerObject*)gAgent.mAvatarObject->getParent())->getRenderRotation();
+				LLQuaternion parent_rot = ((LLViewerObject*)avatarp->getParent())->getRenderRotation();
 				// slam agent coordinate frame to proper parent local version
-				LLVector3 at_axis = gAgent.mFrameAgent.getAtAxis() * parent_rot;
+				LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis() * parent_rot;
 				at_axis.mV[VZ] = 0.f;
 				at_axis.normalize();
 				gAgent.resetAxes(at_axis * ~parent_rot);
 
-				local_camera_offset = local_camera_offset * gAgent.mFrameAgent.getQuaternion() * parent_rot;
+				local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot;
 			}
 			else
 			{
-				local_camera_offset = gAgent.mFrameAgent.rotateToAbsolute( local_camera_offset );
+				local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset );
 			}
 
-			if (!mCameraCollidePlane.isExactlyZero() && (gAgent.mAvatarObject.isNull() || !gAgent.mAvatarObject->isSitting()))
+			if (!mCameraCollidePlane.isExactlyZero() && (!avatarp || !avatarp->isSitting()))
 			{
 				LLVector3 plane_normal;
 				plane_normal.setVec(mCameraCollidePlane.mV);
@@ -1877,11 +1910,11 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 			// set the global camera position
 			LLVector3d camera_offset;
 			
-			LLVector3 av_pos = gAgent.mAvatarObject.isNull() ? LLVector3::zero : gAgent.mAvatarObject->getRenderPosition();
+			LLVector3 av_pos = !avatarp ? LLVector3::zero : avatarp->getRenderPosition();
 			camera_offset.setVec( local_camera_offset );
 			camera_position_global = frame_center_global + head_offset + camera_offset;
 
-			if (gAgent.mAvatarObject.notNull())
+			if (avatarp)
 			{
 				LLVector3d camera_lag_d;
 				F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
@@ -1889,10 +1922,10 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 				LLVector3 vel = gAgent.getVelocity();
 
 				// lag by appropriate amount for flying
-				F32 time_in_air = gAgent.mAvatarObject->mTimeInAir.getElapsedTimeF32();
-				if(!mCameraAnimating && gAgent.mAvatarObject->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
+				F32 time_in_air = avatarp->mTimeInAir.getElapsedTimeF32();
+				if(!mCameraAnimating && avatarp->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
 				{
-					LLVector3 frame_at_axis = gAgent.mFrameAgent.getAtAxis();
+					LLVector3 frame_at_axis = gAgent.getFrameAgent().getAtAxis();
 					frame_at_axis -= projected_vec(frame_at_axis, gAgent.getReferenceUpVector());
 					frame_at_axis.normalize();
 
@@ -1902,7 +1935,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 
 					lag_interp *= u;
 
-					if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == gAgent.mAvatarObject->getID())
+					if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == avatarp->getID())
 					{
 						// disable camera lag when using mouse-directed steering
 						target_lag.clearVec();
@@ -1946,8 +1979,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 
 	if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
 	{
-		LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(
-			camera_position_global);
+		LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
 		bool constrain = true;
 		if(regionp && regionp->canManageEstate())
 		{
@@ -1955,17 +1987,14 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 		}
 		if(constrain)
 		{
-			F32 max_dist = ( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) ?
-				APPEARANCE_MAX_ZOOM : mDrawDistance;
+			F32 max_dist = (CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode) ? APPEARANCE_MAX_ZOOM : mDrawDistance;
 
-			LLVector3d camera_offset = camera_position_global
-				- gAgent.getPositionGlobal();
+			LLVector3d camera_offset = camera_position_global - gAgent.getPositionGlobal();
 			F32 camera_distance = (F32)camera_offset.magVec();
 
 			if(camera_distance > max_dist)
 			{
-				camera_position_global = gAgent.getPositionGlobal() + 
-					(max_dist / camera_distance) * camera_offset;
+				camera_position_global = gAgent.getPositionGlobal() + (max_dist/camera_distance)*camera_offset;
 				isConstrained = TRUE;
 			}
 		}
@@ -2013,12 +2042,12 @@ LLVector3 LLAgentCamera::getCameraOffsetInitial()
 //-----------------------------------------------------------------------------
 void LLAgentCamera::handleScrollWheel(S32 clicks)
 {
-	if ( mCameraMode == CAMERA_MODE_FOLLOW && getFocusOnAvatar())
+	if (mCameraMode == CAMERA_MODE_FOLLOW && getFocusOnAvatar())
 	{
-		if ( ! mFollowCam.getPositionLocked() ) // not if the followCam position is locked in place
+		if (!mFollowCam.getPositionLocked()) // not if the followCam position is locked in place
 		{
-			mFollowCam.zoom( clicks ); 
-			if ( mFollowCam.isZoomedToMinimumDistance() )
+			mFollowCam.zoom(clicks); 
+			if (mFollowCam.isZoomedToMinimumDistance())
 			{
 				changeCameraToMouselook(FALSE);
 			}
@@ -2040,7 +2069,7 @@ void LLAgentCamera::handleScrollWheel(S32 clicks)
 			F32 zoom_factor = (F32)pow(0.8, -clicks);
 			cameraZoomIn(zoom_factor);
 		}
-		else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
+		else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON))
 		{
 			F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
 			
@@ -2087,7 +2116,7 @@ F32 LLAgentCamera::getCameraMinOffGround()
 void LLAgentCamera::resetCamera()
 {
 	// Remove any pitch from the avatar
-	LLVector3 at = gAgent.mFrameAgent.getAtAxis();
+	LLVector3 at = gAgent.getFrameAgent().getAtAxis();
 	at.mV[VZ] = 0.f;
 	at.normalize();
 	gAgent.resetAxes(at);
@@ -2107,18 +2136,20 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate)
 		return;
 	}
 
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+
 	// visibility changes at end of animation
 	gViewerWindow->getWindow()->resetBusyCount();
 
 	// unpause avatar animation
-	gAgent.mPauseRequest = NULL;
+	gAgent.unpauseAnimation();
 
 	LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
 
-	if (gAgent.mAvatarObject.notNull())
+	if (avatarp)
 	{
-		gAgent.mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
-		gAgent.mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
+		avatarp->stopMotion(ANIM_AGENT_BODY_NOISE);
+		avatarp->stopMotion(ANIM_AGENT_BREATHE_ROT);
 	}
 
 	//gViewerWindow->stopGrab();
@@ -2126,17 +2157,17 @@ void LLAgentCamera::changeCameraToMouselook(BOOL animate)
 	gViewerWindow->hideCursor();
 	gViewerWindow->moveCursorToCenter();
 
-	if( mCameraMode != CAMERA_MODE_MOUSELOOK )
+	if (mCameraMode != CAMERA_MODE_MOUSELOOK)
 	{
-		gFocusMgr.setKeyboardFocus( NULL );
+		gFocusMgr.setKeyboardFocus(NULL);
 		
 		mLastCameraMode = mCameraMode;
 		mCameraMode = CAMERA_MODE_MOUSELOOK;
-		U32 old_flags = gAgent.mControlFlags;
+		const U32 old_flags = gAgent.getControlFlags();
 		gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK);
-		if (old_flags != gAgent.mControlFlags)
+		if (old_flags != gAgent.getControlFlags())
 		{
-			gAgent.mbFlagsDirty = TRUE;
+			gAgent.setFlagsDirty();
 		}
 
 		if (animate)
@@ -2184,7 +2215,7 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate)
 		return;
 	}
 
-	if( mCameraMode != CAMERA_MODE_FOLLOW )
+	if(mCameraMode != CAMERA_MODE_FOLLOW)
 	{
 		if (mCameraMode == CAMERA_MODE_MOUSELOOK)
 		{
@@ -2196,28 +2227,29 @@ void LLAgentCamera::changeCameraToFollow(BOOL animate)
 		mCameraMode = CAMERA_MODE_FOLLOW;
 
 		// bang-in the current focus, position, and up vector of the follow cam
-		mFollowCam.reset( mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis );
+		mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis);
 		
 		if (gBasicToolset)
 		{
 			LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
 		}
 
-		if (gAgent.mAvatarObject.notNull())
+		LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+		if (avatarp)
 		{
-			gAgent.mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
-			gAgent.mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
-			gAgent.mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
+			avatarp->mPelvisp->setPosition(LLVector3::zero);
+			avatarp->startMotion( ANIM_AGENT_BODY_NOISE );
+			avatarp->startMotion( ANIM_AGENT_BREATHE_ROT );
 		}
 
 		// unpause avatar animation
-		gAgent.mPauseRequest = NULL;
+		gAgent.unpauseAnimation();
 
-		U32 old_flags = gAgent.mControlFlags;
+		const U32 old_flags = gAgent.getControlFlags();
 		gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
-		if (old_flags != gAgent.mControlFlags)
+		if (old_flags != gAgent.getControlFlags())
 		{
-			gAgent.mbFlagsDirty = TRUE;
+			gAgent.setFlagsDirty();
 		}
 
 		if (animate)
@@ -2246,22 +2278,23 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
 
 	mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
 
-	if (gAgent.mAvatarObject.notNull())
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+	if (avatarp)
 	{
-		if (!gAgent.mAvatarObject->isSitting())
+		if (!avatarp->isSitting())
 		{
-			gAgent.mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
+			avatarp->mPelvisp->setPosition(LLVector3::zero);
 		}
-		gAgent.mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
-		gAgent.mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
+		avatarp->startMotion(ANIM_AGENT_BODY_NOISE);
+		avatarp->startMotion(ANIM_AGENT_BREATHE_ROT);
 	}
 
 	LLVector3 at_axis;
 
 	// unpause avatar animation
-	gAgent.mPauseRequest = NULL;
+	gAgent.unpauseAnimation();
 
-	if( mCameraMode != CAMERA_MODE_THIRD_PERSON )
+	if (mCameraMode != CAMERA_MODE_THIRD_PERSON)
 	{
 		if (gBasicToolset)
 		{
@@ -2277,19 +2310,19 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
 		}
 		mLastCameraMode = mCameraMode;
 		mCameraMode = CAMERA_MODE_THIRD_PERSON;
-		U32 old_flags = gAgent.mControlFlags;
+		const U32 old_flags = gAgent.getControlFlags();
 		gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
-		if (old_flags != gAgent.mControlFlags)
+		if (old_flags != gAgent.getControlFlags())
 		{
-			gAgent.mbFlagsDirty = TRUE;
+			gAgent.setFlagsDirty();
 		}
 
 	}
 
 	// Remove any pitch from the avatar
-	if (gAgent.mAvatarObject.notNull() && gAgent.mAvatarObject->getParent())
+	if (avatarp && avatarp->getParent())
 	{
-		LLQuaternion obj_rot = ((LLViewerObject*)gAgent.mAvatarObject->getParent())->getRenderRotation();
+		LLQuaternion obj_rot = ((LLViewerObject*)avatarp->getParent())->getRenderRotation();
 		at_axis = LLViewerCamera::getInstance()->getAtAxis();
 		at_axis.mV[VZ] = 0.f;
 		at_axis.normalize();
@@ -2297,7 +2330,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
 	}
 	else
 	{
-		at_axis = gAgent.mFrameAgent.getAtAxis();
+		at_axis = gAgent.getFrameAgent().getAtAxis();
 		at_axis.mV[VZ] = 0.f;
 		at_axis.normalize();
 		gAgent.resetAxes(at_axis);
@@ -2339,20 +2372,20 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
 	}
 
 	// Remove any pitch from the avatar
-	//LLVector3 at = gAgent.mFrameAgent.getAtAxis();
+	//LLVector3 at = gAgent.getFrameAgent().getAtAxis();
 	//at.mV[VZ] = 0.f;
 	//at.normalize();
 	//gAgent.resetAxes(at);
 
-	if( mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR )
+	if (mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
 		mLastCameraMode = mCameraMode;
 		mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR;
-		U32 old_flags = gAgent.mControlFlags;
+		const U32 old_flags = gAgent.getControlFlags();
 		gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
-		if (old_flags != gAgent.mControlFlags)
+		if (old_flags != gAgent.getControlFlags())
 		{
-			gAgent.mbFlagsDirty = TRUE;
+			gAgent.setFlagsDirty();
 		}
 
 		gFocusMgr.setKeyboardFocus( NULL );
@@ -2361,20 +2394,21 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
 		LLVOAvatarSelf::onCustomizeStart();
 	}
 
-	if (gAgent.mAvatarObject.notNull())
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+	if (avatarp)
 	{
 		if(avatar_animate)
 		{
 			// Remove any pitch from the avatar
-			LLVector3 at = gAgent.mFrameAgent.getAtAxis();
+			LLVector3 at = gAgent.getFrameAgent().getAtAxis();
 			at.mV[VZ] = 0.f;
 			at.normalize();
 			gAgent.resetAxes(at);
 
 			gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
-			gAgent.mCustomAnim = TRUE;
-			gAgent.mAvatarObject->startMotion(ANIM_AGENT_CUSTOMIZE);
-			LLMotion* turn_motion = gAgent.mAvatarObject->findMotion(ANIM_AGENT_CUSTOMIZE);
+			gAgent.setCustomAnim(TRUE);
+			avatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
+			LLMotion* turn_motion = avatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
 
 			if (turn_motion)
 			{
@@ -2386,9 +2420,6 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
 				mAnimationDuration = gSavedSettings.getF32("ZoomTime");
 			}
 		}
-
-
-
 		setFocusGlobal(LLVector3d::zero);
 	}
 	else
@@ -2396,7 +2427,6 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
 		mCameraAnimating = FALSE;
 		gAgent.endAnimationUpdateUI();
 	}
-
 }
 
 
@@ -2481,15 +2511,16 @@ void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object
 	setFocusObject(gObjectList.findObject(object_id));
 	LLVector3d old_focus = mFocusTargetGlobal;
 	LLViewerObject *focus_obj = mFocusObject;
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
 
 	// if focus has changed
 	if (old_focus != focus)
 	{
 		if (focus.isExactlyZero())
 		{
-			if (gAgent.mAvatarObject.notNull())
+			if (avatarp)
 			{
-				mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgent.mAvatarObject->mHeadp->getWorldPosition());
+				mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(avatarp->mHeadp->getWorldPosition());
 			}
 			else
 			{
@@ -2532,9 +2563,9 @@ void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object
 	{
 		if (focus.isExactlyZero())
 		{
-			if (gAgent.mAvatarObject.notNull())
+			if (avatarp)
 			{
-				mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgent.mAvatarObject->mHeadp->getWorldPosition());
+				mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(avatarp->mHeadp->getWorldPosition());
 			}
 			else
 			{
@@ -2550,8 +2581,7 @@ void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object
 		// for attachments, make offset relative to avatar, not the attachment
 		if (mFocusObject->isAttachment())
 		{
-			while (mFocusObject.notNull()		// DEV-29123 - can crash with a messed-up attachment
-				&& !mFocusObject->isAvatar())
+			while (mFocusObject.notNull() && !mFocusObject->isAvatar())
 			{
 				mFocusObject = (LLViewerObject*) mFocusObject->getParent();
 			}
@@ -2571,11 +2601,11 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con
 
 	F64 focus_delta_squared = (old_focus - focus).magVecSquared();
 	const F64 ANIM_EPSILON_SQUARED = 0.0001;
-	if( focus_delta_squared > ANIM_EPSILON_SQUARED )
+	if (focus_delta_squared > ANIM_EPSILON_SQUARED)
 	{
 		startCameraAnimation();
 
-		if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) 
+		if (CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode) 
 		{
 			// Compensate for the fact that the camera has already been offset to make room for LLFloaterCustomize.
 			mAnimationCameraStartGlobal -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * calcCustomizeAvatarUIOffset( mAnimationCameraStartGlobal ));
@@ -2604,7 +2634,7 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con
 		setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal));
 	}
 
-	if( mCameraAnimating )
+	if (mCameraAnimating)
 	{
 		const F64 ANIM_METERS_PER_SECOND = 10.0;
 		const F64 MIN_ANIM_SECONDS = 0.5;
@@ -2672,9 +2702,10 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
 		if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
 		{
 			LLVector3 at_axis;
-			if (gAgent.mAvatarObject.notNull() && gAgent.mAvatarObject->getParent())
+			LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+			if (avatarp && avatarp->getParent())
 			{
-				LLQuaternion obj_rot = ((LLViewerObject*)gAgent.mAvatarObject->getParent())->getRenderRotation();
+				LLQuaternion obj_rot = ((LLViewerObject*)avatarp->getParent())->getRenderRotation();
 				at_axis = LLViewerCamera::getInstance()->getAtAxis();
 				at_axis.mV[VZ] = 0.f;
 				at_axis.normalize();
@@ -2702,15 +2733,16 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
 
 BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position)
 {
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
 	if(object && object->isAttachment())
 	{
 		LLViewerObject* parent = object;
 		while(parent)
 		{
-			if (parent == gAgent.mAvatarObject)
+			if (parent == avatarp)
 			{
 				// looking at an attachment on ourselves, which we don't want to do
-				object = gAgent.mAvatarObject;
+				object = avatarp;
 				position.clearVec();
 			}
 			parent = (LLViewerObject*)parent->getParent();
@@ -2719,12 +2751,92 @@ BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, L
 	if(!mLookAt || mLookAt->isDead())
 	{
 		mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
-		mLookAt->setSourceObject(gAgent.mAvatarObject);
+		mLookAt->setSourceObject(avatarp);
 	}
 
 	return mLookAt->setLookAt(target_type, object, position);
 }
 
+//-----------------------------------------------------------------------------
+// lookAtLastChat()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::lookAtLastChat()
+{
+	// Block if camera is animating or not in normal third person camera mode
+	if (mCameraAnimating || !cameraThirdPerson())
+	{
+		return;
+	}
+
+	LLViewerObject *chatter = gObjectList.findObject(gAgent.getLastChatter());
+	if (!chatter)
+	{
+		return;
+	}
+
+	LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+	LLVector3 delta_pos;
+	if (chatter->isAvatar())
+	{
+		LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
+		if (avatarp && chatter_av->mHeadp)
+		{
+			delta_pos = chatter_av->mHeadp->getWorldPosition() - avatarp->mHeadp->getWorldPosition();
+		}
+		else
+		{
+			delta_pos = chatter->getPositionAgent() - gAgent.getPositionAgent();
+		}
+		delta_pos.normalize();
+
+		gAgent.setControlFlags(AGENT_CONTROL_STOP);
+
+		changeCameraToThirdPerson();
+
+		LLVector3 new_camera_pos = avatarp->mHeadp->getWorldPosition();
+		LLVector3 left = delta_pos % LLVector3::z_axis;
+		left.normalize();
+		LLVector3 up = left % delta_pos;
+		up.normalize();
+		new_camera_pos -= delta_pos * 0.4f;
+		new_camera_pos += left * 0.3f;
+		new_camera_pos += up * 0.2f;
+		if (chatter_av->mHeadp)
+		{
+			setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), gAgent.getLastChatter());
+			mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
+		}
+		else
+		{
+			setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
+			mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
+		}
+		setFocusOnAvatar(FALSE, TRUE);
+	}
+	else
+	{
+		delta_pos = chatter->getRenderPosition() - gAgent.getPositionAgent();
+		delta_pos.normalize();
+
+		gAgent.setControlFlags(AGENT_CONTROL_STOP);
+
+		changeCameraToThirdPerson();
+
+		LLVector3 new_camera_pos = avatarp->mHeadp->getWorldPosition();
+		LLVector3 left = delta_pos % LLVector3::z_axis;
+		left.normalize();
+		LLVector3 up = left % delta_pos;
+		up.normalize();
+		new_camera_pos -= delta_pos * 0.4f;
+		new_camera_pos += left * 0.3f;
+		new_camera_pos += up * 0.2f;
+
+		setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
+		mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
+		setFocusOnAvatar(FALSE, TRUE);
+	}
+}
+
 BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
 {
 	// disallow pointing at attachments and avatars
@@ -2732,23 +2844,21 @@ BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object,
 	{
 		return FALSE;
 	}
-
-	if(!mPointAt || mPointAt->isDead())
+	if (!mPointAt || mPointAt->isDead())
 	{
 		mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
-		mPointAt->setSourceObject(gAgent.mAvatarObject);
+		LLVOAvatarSelf *avatarp = gAgent.getAvatarObject();
+		mPointAt->setSourceObject(avatarp);
 	}
-
 	return mPointAt->setPointAt(target_type, object, position);
 }
 
 ELookAtType LLAgentCamera::getLookAtType()
-{ 
+{
 	if (mLookAt) 
 	{
 		return mLookAt->getLookAtType();
 	}
-
 	return LOOKAT_TARGET_NONE;
 }
 
@@ -2758,7 +2868,6 @@ EPointAtType LLAgentCamera::getPointAtType()
 	{
 		return mPointAt->getPointAtType();
 	}
-
 	return POINTAT_TARGET_NONE;
 }
 
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index 0b55b917d01f48d03d2c0d7cfe6d0c993f5e3353..f45cf1f5bbab6a2e6dc2a96ef1266acc5cddfe5d 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -94,11 +94,6 @@ class LLAgentCamera
 public:
 	friend class LLAgent;
 
-/********************************************************************************
- **                                                                            **
- **                    INITIALIZATION
- **/
-
 	//--------------------------------------------------------------------
 	// Constructors / Destructors
 	//--------------------------------------------------------------------
@@ -107,9 +102,11 @@ class LLAgentCamera
 	virtual 		~LLAgentCamera();
 	void			init();
 	void			cleanup();
+	void		    setCameraAvatarObject(LLVOAvatarSelf* avatar);
 private:
 	BOOL			mInitialized;
 
+
 	//--------------------------------------------------------------------
 	// Mode
 	//--------------------------------------------------------------------
@@ -148,7 +145,6 @@ class LLAgentCamera
 	/** Initial focus offsets */
 	std::map<ECameraPreset, LLVector3d> mFocusOffsetInitial;
 
-
 	//--------------------------------------------------------------------
 	// Position
 	//--------------------------------------------------------------------
@@ -291,6 +287,7 @@ class LLAgentCamera
 	void			updateLookAt(const S32 mouse_x, const S32 mouse_y);
 	BOOL			setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
 	ELookAtType		getLookAtType();
+	void			lookAtLastChat();
 	void 			slamLookAt(const LLVector3 &look_at); // Set the physics data
 	BOOL			setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
 	EPointAtType	getPointAtType();
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 80c32399ce481fc3a8c9d788948d9e67bf4f7af9..82c64928506e661e8234c53d12fbdcd9cc0361b7 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4093,7 +4093,7 @@ void LLAppViewer::disconnectViewer()
 	LLFloaterInventory::cleanup();
 
 	gAgentWearables.cleanup();
-
+	gAgentCamera.cleanup();
 	// Also writes cached agent settings to gSavedSettings
 	gAgent.cleanup();
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index c440a1b285e457ff234e9f439fe7ec1218de0d08..edd03dc83674afdb488d65319c7e77744e23370d 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2721,6 +2721,8 @@ void LLStartUp::postStartupState()
 
 void reset_login()
 {
+	gAgentWearables.cleanup();
+	gAgentCamera.cleanup();
 	gAgent.cleanup();
 	LLWorld::getInstance()->destroyClass();
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 6294800428a697203be713374f80c81878741b89..37566befb88fd7c56cf0564b8a59aebc881ea0ab 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3751,7 +3751,7 @@ class LLViewLookAtLastChatter : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		gAgent.lookAtLastChat();
+		gAgentCamera.lookAtLastChat();
 		return true;
 	}
 };