From fc49539b36adfd4c87d7824db5d94a7858683f3d Mon Sep 17 00:00:00 2001
From: Loren Shih <seraph@lindenlab.com>
Date: Tue, 23 Mar 2010 15:59:52 -0400
Subject: EXT-2959 : Full out camera functions from llagent to llagentcamera

First check-in; only compiles, nothing more.
---
 indra/newview/CMakeLists.txt               |    2 +
 indra/newview/llagent.cpp                  |  321 ++--
 indra/newview/llagent.h                    |   57 +-
 indra/newview/llagentcamera.cpp            | 2806 ++++++++++++++++++++++++++++
 indra/newview/llagentcamera.h              |  370 ++++
 indra/newview/llagentwearables.cpp         |    5 +-
 indra/newview/llappviewer.cpp              |    9 +-
 indra/newview/llaudiosourcevo.cpp          |    4 +-
 indra/newview/llbottomtray.cpp             |    4 +-
 indra/newview/llfloatercamera.cpp          |   20 +-
 indra/newview/llfloaterinventory.cpp       |    4 +-
 indra/newview/llfloatermap.cpp             |    4 +-
 indra/newview/llfloatersnapshot.cpp        |    5 +-
 indra/newview/llfloatertools.cpp           |    8 +-
 indra/newview/llfloaterworldmap.cpp        |    5 +-
 indra/newview/llglsandbox.cpp              |   93 -
 indra/newview/llhudeffectlookat.cpp        |    5 +-
 indra/newview/llhudeffectpointat.cpp       |    3 +-
 indra/newview/llinventorybridge.cpp        |    5 +-
 indra/newview/lljoystickbutton.cpp         |   33 +-
 indra/newview/llmanip.cpp                  |   19 +-
 indra/newview/llmaniprotate.cpp            |   31 +-
 indra/newview/llmanipscale.cpp             |   17 +-
 indra/newview/llmaniptranslate.cpp         |   21 +-
 indra/newview/llmenucommands.cpp           |    4 +-
 indra/newview/llmorphview.cpp              |    5 +-
 indra/newview/llmoveview.cpp               |    3 +-
 indra/newview/llnetmap.cpp                 |   13 +-
 indra/newview/llpanelme.cpp                |    3 +-
 indra/newview/llpanelprimmediacontrols.cpp |    6 +-
 indra/newview/llselectmgr.cpp              |   47 +-
 indra/newview/llsidepanelappearance.cpp    |    3 +-
 indra/newview/llsidetray.cpp               |    4 +-
 indra/newview/llstartup.cpp                |   16 +-
 indra/newview/llstatusbar.cpp              |    3 +-
 indra/newview/llsurface.cpp                |    3 +-
 indra/newview/lltexlayerparams.cpp         |    4 +-
 indra/newview/lltoolcomp.cpp               |    3 +-
 indra/newview/lltooldraganddrop.cpp        |    3 +-
 indra/newview/lltoolfocus.cpp              |   45 +-
 indra/newview/lltoolgrab.cpp               |   49 +-
 indra/newview/lltoolgun.cpp                |    3 +-
 indra/newview/lltoolmgr.cpp                |   19 +-
 indra/newview/lltoolpie.cpp                |    9 +-
 indra/newview/lltoolplacer.cpp             |    3 +-
 indra/newview/lltoolselect.cpp             |    3 +-
 indra/newview/lltracker.cpp                |    5 +-
 indra/newview/llvieweraudio.cpp            |    7 +-
 indra/newview/llviewerdisplay.cpp          |   15 +-
 indra/newview/llviewerinventory.cpp        |    3 +-
 indra/newview/llviewerjoystick.cpp         |    7 +-
 indra/newview/llviewerkeyboard.cpp         |   43 +-
 indra/newview/llviewermediafocus.cpp       |   11 +-
 indra/newview/llviewermenu.cpp             |   93 +-
 indra/newview/llviewermenufile.cpp         |    9 +-
 indra/newview/llviewermessage.cpp          |   33 +-
 indra/newview/llviewerobject.cpp           |    3 +-
 indra/newview/llviewerobjectlist.cpp       |    7 +-
 indra/newview/llviewerparceloverlay.cpp    |    6 +-
 indra/newview/llviewerregion.cpp           |    3 +-
 indra/newview/llviewerstats.cpp            |    5 +-
 indra/newview/llviewerwindow.cpp           |   36 +-
 indra/newview/llvoavatar.cpp               |   35 +-
 indra/newview/llvoavatarself.cpp           |   19 +-
 indra/newview/llvograss.cpp                |    4 +-
 indra/newview/llvopartgroup.cpp            |    4 +-
 indra/newview/llvosky.cpp                  |    5 +-
 indra/newview/llvotree.cpp                 |    4 +-
 indra/newview/llwaterparammanager.cpp      |    3 +-
 indra/newview/llworldmapview.cpp           |    9 +-
 indra/newview/pipeline.cpp                 |    7 +-
 71 files changed, 3828 insertions(+), 650 deletions(-)
 create mode 100644 indra/newview/llagentcamera.cpp
 create mode 100644 indra/newview/llagentcamera.h

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8ad3b2085d..f45237a73c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -66,6 +66,7 @@ include_directories(
 set(viewer_SOURCE_FILES
     llagent.cpp
     llagentaccess.cpp
+    llagentcamera.cpp
     llagentdata.cpp
     llagentlanguage.cpp
     llagentlistener.cpp
@@ -564,6 +565,7 @@ set(viewer_HEADER_FILES
     ViewerInstall.cmake
     llagent.h
     llagentaccess.h
+    llagentcamera.h
     llagentdata.h
     llagentlanguage.h
     llagentlistener.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index c5d7f6f118..5ee026f021 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -35,6 +35,7 @@
 
 #include "pipeline.h"
 
+#include "llagentcamera.h"
 #include "llagentlistener.h"
 #include "llagentwearables.h"
 #include "llagentui.h"
@@ -59,6 +60,7 @@
 #include "llnearbychatbar.h"
 #include "llnotificationsutil.h"
 #include "llparcel.h"
+#include "llrendersphere.h"
 #include "llsdutil.h"
 #include "llsidetray.h"
 #include "llsky.h"
@@ -80,6 +82,8 @@
 #include "llworld.h"
 #include "llworldmap.h"
 
+LLAgentCamera gAgentCameraHACK; // Seraph delete
+
 using namespace LLVOAvatarDefines;
 
 extern LLMenuBarGL* gMenuBarView;
@@ -106,14 +110,18 @@ const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f;		// seconds
 const LLVector3d FACE_EDIT_CAMERA_OFFSET(0.4f, -0.05f, 0.07f);
 const LLVector3d FACE_EDIT_TARGET_OFFSET(0.f, 0.f, 0.05f);
 
+/*
 // Mousewheel camera zoom
 const F32 MIN_ZOOM_FRACTION = 0.25f;
 const F32 INITIAL_ZOOM_FRACTION = 1.f;
 const F32 MAX_ZOOM_FRACTION = 8.f;
+*/
+
 const F32 METERS_PER_WHEEL_CLICK = 1.f;
 
 const F32 MAX_TIME_DELTA = 1.f;
 
+/*
 const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f;	// seconds
 const F32 FOV_ZOOM_HALF_LIFE = 0.07f;	// seconds
 
@@ -141,20 +149,25 @@ const F32 OBJECT_MIN_ZOOM = 0.02f;
 
 const F32 APPEARANCE_MIN_ZOOM = 0.39f;
 const F32 APPEARANCE_MAX_ZOOM = 8.f;
+*/
 
 // fidget constants
 const F32 MIN_FIDGET_TIME = 8.f; // seconds
 const F32 MAX_FIDGET_TIME = 20.f; // seconds
 
 const S32 MAX_NUM_CHAT_POSITIONS = 10;
+/*
 const F32 GROUND_TO_AIR_CAMERA_TRANSITION_TIME = 0.5f;
 const F32 GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME = 0.5f;
+*/
 
 const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
 
 const F32 MAX_FOCUS_OFFSET = 20.f;
 
+/*
 const F32 OBJECT_EXTENTS_PADDING = 0.5f;
+*/
 
 const F32 MIN_RADIUS_ALPHA_SIZZLE = 0.5f;
 
@@ -224,14 +237,14 @@ LLAgent::LLAgent() :
 	mHideGroupTitle(FALSE),
 	mGroupID(),
 
-	mLookAt(NULL),
-	mPointAt(NULL),
+////	mLookAt(NULL),
+////	mPointAt(NULL),
 
-	mHUDTargetZoom(1.f),
-	mHUDCurZoom(1.f),
+////	mHUDTargetZoom(1.f),
+////	mHUDCurZoom(1.f),
 	mInitialized(FALSE),
 	mListener(),
-	mForceMouselook(FALSE),
+////	mForceMouselook(FALSE),
 
 	mDoubleTapRunTimer(),
 	mDoubleTapRunMode(DOUBLETAP_NONE),
@@ -254,47 +267,47 @@ LLAgent::LLAgent() :
 	mRenderState(0),
 	mTypingTimer(),
 
-	mCameraMode( CAMERA_MODE_THIRD_PERSON ),
-	mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
+////	mCameraMode( CAMERA_MODE_THIRD_PERSON ),
+////	mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
 	mViewsPushed(FALSE),
 
-	mCameraPreset(CAMERA_PRESET_REAR_VIEW),
+////	mCameraPreset(CAMERA_PRESET_REAR_VIEW),
 
 	mCustomAnim(FALSE),
 	mShowAvatar(TRUE),
-	mCameraAnimating( FALSE ),
-	mAnimationCameraStartGlobal(),
-	mAnimationFocusStartGlobal(),
-	mAnimationTimer(),
-	mAnimationDuration(0.33f),
+////	mCameraAnimating( FALSE ),
+////	mAnimationCameraStartGlobal(),
+////	mAnimationFocusStartGlobal(),
+////	mAnimationTimer(),
+////	mAnimationDuration(0.33f),
 	
-	mCameraFOVZoomFactor(0.f),
-	mCameraCurrentFOVZoomFactor(0.f),
-	mCameraFocusOffset(),
-	mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
-
-	mCameraCollidePlane(),
-
-	mCurrentCameraDistance(2.f),		// meters, set in init()
-	mTargetCameraDistance(2.f),
-	mCameraZoomFraction(1.f),			// deprecated
-	mThirdPersonHeadOffset(0.f, 0.f, 1.f),
-	mSitCameraEnabled(FALSE),
-	mCameraSmoothingLastPositionGlobal(),
-	mCameraSmoothingLastPositionAgent(),
-	mCameraSmoothingStop(FALSE),
-
-	mCameraUpVector(LLVector3::z_axis), // default is straight up
-
-	mFocusOnAvatar(TRUE),
-	mFocusGlobal(),
-	mFocusTargetGlobal(),
-	mFocusObject(NULL),
-	mFocusObjectDist(0.f),
-	mFocusObjectOffset(),
-	mFocusDotRadius( 0.1f ),			// meters
-	mTrackFocusObject(TRUE),
-	mUIOffset(0.f),
+////	mCameraFOVZoomFactor(0.f),
+////	mCameraCurrentFOVZoomFactor(0.f),
+////	mCameraFocusOffset(),
+////	mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
+
+////	mCameraCollidePlane(),
+
+////	mCurrentCameraDistance(2.f),		// meters, set in init()
+////	mTargetCameraDistance(2.f),
+////	mCameraZoomFraction(1.f),			// deprecated
+////	mThirdPersonHeadOffset(0.f, 0.f, 1.f),
+////	mSitCameraEnabled(FALSE),
+////	mCameraSmoothingLastPositionGlobal(),
+////	mCameraSmoothingLastPositionAgent(),
+////	mCameraSmoothingStop(FALSE),
+
+////	mCameraUpVector(LLVector3::z_axis), // default is straight up
+
+////	mFocusOnAvatar(TRUE),
+////	mFocusGlobal(),
+////	mFocusTargetGlobal(),
+////	mFocusObject(NULL),
+////	mFocusObjectDist(0.f),
+////	mFocusObjectOffset(),
+////	mFocusDotRadius( 0.1f ),			// meters
+////	mTrackFocusObject(TRUE),
+//	mUIOffset(0.f),
 
 	mFrameAgent(),
 
@@ -358,7 +371,7 @@ LLAgent::LLAgent() :
 		mControlsTakenPassedOnCount[i] = 0;
 	}
 
-	mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
+////	mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
 
 	mListener.reset(new LLAgentListener(*this));
 }
@@ -376,6 +389,9 @@ void LLAgent::init()
 
 	// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
 
+	setFlying( gSavedSettings.getBOOL("FlyingAtExit") );
+
+/*
 	LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW);
 	// Leave at 0.1 meters until we have real near clip management
 	LLViewerCamera::getInstance()->setNear(0.1f);
@@ -383,25 +399,24 @@ void LLAgent::init()
 	LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() );		// default, overridden in LLViewerWindow::reshape
 	LLViewerCamera::getInstance()->setViewHeightInPixels(768);			// default, overridden in LLViewerWindow::reshape
 
-	setFlying( gSavedSettings.getBOOL("FlyingAtExit") );
-
-	mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
+////	mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
 	
-	mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
+////	mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
 
-	mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3("CameraOffsetRearView");
-	mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3("CameraOffsetFrontView");
-	mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3("CameraOffsetGroupView");
+////	mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3("CameraOffsetRearView");
+////	mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3("CameraOffsetFrontView");
+////	mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3("CameraOffsetGroupView");
 
-	mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3d("FocusOffsetRearView");
-	mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3d("FocusOffsetFrontView");
-	mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3d("FocusOffsetGroupView");
+////	mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3d("FocusOffsetRearView");
+////	mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3d("FocusOffsetFrontView");
+////	mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3d("FocusOffsetGroupView");
 
-	mCameraCollidePlane.clearVec();
-	mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
-	mTargetCameraDistance = mCurrentCameraDistance;
-	mCameraZoomFraction = 1.f;
-	mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
+////	mCameraCollidePlane.clearVec();
+////	mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
+////	mTargetCameraDistance = mCurrentCameraDistance;
+////	mCameraZoomFraction = 1.f;
+////	mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
+*/
 
 	mEffectColor = LLUIColorTable::instance().getColor("EffectColor");
 
@@ -416,22 +431,9 @@ void LLAgent::init()
 //-----------------------------------------------------------------------------
 void LLAgent::cleanup()
 {
-	setSitCamera(LLUUID::null);
-
 	mAvatarObject = NULL;
-
-	if(mLookAt)
-	{
-		mLookAt->markDead() ;
-		mLookAt = NULL;
-	}
-	if(mPointAt)
-	{
-		mPointAt->markDead() ;
-		mPointAt = NULL;
-	}
 	mRegionp = NULL;
-	setFocusObject(NULL);
+	gAgentCameraHACK.cleanup();
 }
 
 //-----------------------------------------------------------------------------
@@ -444,6 +446,7 @@ LLAgent::~LLAgent()
 	// *Note: this is where LLViewerCamera::getInstance() used to be deleted.
 }
 
+/*
 // Change camera back to third person, stop the autopilot,
 // deselect stuff, etc.
 //-----------------------------------------------------------------------------
@@ -520,6 +523,7 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera)
 
 	mHUDTargetZoom = 1.f;
 }
+*/
 
 // Handle any actions that need to be performed when the main app gains focus
 // (such as through alt-tab).
@@ -528,9 +532,9 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera)
 //-----------------------------------------------------------------------------
 void LLAgent::onAppFocusGained()
 {
-	if (CAMERA_MODE_MOUSELOOK == mCameraMode)
+	if (CAMERA_MODE_MOUSELOOK == gAgentCameraHACK.mCameraMode)
 	{
-		changeCameraToDefault();
+		gAgentCameraHACK.changeCameraToDefault();
 		LLToolMgr::getInstance()->clearSavedTool();
 	}
 }
@@ -547,6 +551,7 @@ void LLAgent::ageChat()
 	}
 }
 
+/*
 // Allow camera to be moved somewhere other than behind avatar.
 //-----------------------------------------------------------------------------
 // unlockView()
@@ -562,7 +567,7 @@ void LLAgent::unlockView()
 		setFocusOnAvatar(FALSE, FALSE);	// no animation
 	}
 }
-
+*/
 
 //-----------------------------------------------------------------------------
 // moveAt()
@@ -585,7 +590,7 @@ void LLAgent::moveAt(S32 direction, bool reset)
 
 	if (reset)
 	{
-		resetView();
+		gAgentCameraHACK.resetView();
 	}
 }
 
@@ -608,7 +613,7 @@ void LLAgent::moveAtNudge(S32 direction)
 		setControlFlags(AGENT_CONTROL_NUDGE_AT_NEG);
 	}
 
-	resetView();
+	gAgentCameraHACK.resetView();
 }
 
 //-----------------------------------------------------------------------------
@@ -630,7 +635,7 @@ void LLAgent::moveLeft(S32 direction)
 		setControlFlags(AGENT_CONTROL_LEFT_NEG | AGENT_CONTROL_FAST_LEFT);
 	}
 
-	resetView();
+	gAgentCameraHACK.resetView();
 }
 
 //-----------------------------------------------------------------------------
@@ -652,7 +657,7 @@ void LLAgent::moveLeftNudge(S32 direction)
 		setControlFlags(AGENT_CONTROL_NUDGE_LEFT_NEG);
 	}
 
-	resetView();
+	gAgentCameraHACK.resetView();
 }
 
 //-----------------------------------------------------------------------------
@@ -674,7 +679,7 @@ void LLAgent::moveUp(S32 direction)
 		setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP);
 	}
 
-	resetView();
+	gAgentCameraHACK.resetView();
 }
 
 //-----------------------------------------------------------------------------
@@ -695,7 +700,7 @@ void LLAgent::moveYaw(F32 mag, bool reset_view)
 
     if (reset_view)
 	{
-        resetView();
+        gAgentCameraHACK.resetView();
 	}
 }
 
@@ -806,7 +811,7 @@ void LLAgent::toggleFlying()
 	BOOL fly = !gAgent.getFlying();
 
 	gAgent.setFlying( fly );
-	gAgent.resetView();
+	gAgentCameraHACK.resetView();
 }
 
 // static
@@ -878,7 +883,8 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 			LLVector3 delta;
 			delta.setVec(regionp->getOriginGlobal());
 
-			setPositionAgent(getPositionAgent() - delta);
+			setPositionAgent
+(getPositionAgent() - delta);
 			LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
 			LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
 
@@ -1028,6 +1034,7 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
 	}
 }
 
+/*
 //-----------------------------------------------------------------------------
 // slamLookAt()
 //-----------------------------------------------------------------------------
@@ -1038,6 +1045,7 @@ void LLAgent::slamLookAt(const LLVector3 &look_at)
 	look_at_norm.normalize();
 	resetAxes(look_at_norm);
 }
+*/
 
 //-----------------------------------------------------------------------------
 // getPositionGlobal()
@@ -1193,7 +1201,7 @@ LLVector3 LLAgent::getReferenceUpVector()
 		mAvatarObject->getParent() &&
 		mAvatarObject->mDrawable.notNull())
 	{
-		U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
+		U32 camera_mode = gAgentCameraHACK.mCameraAnimating ? gAgentCameraHACK.mLastCameraMode : gAgentCameraHACK.mCameraMode;
 		// and in third person...
 		if (camera_mode == CAMERA_MODE_THIRD_PERSON)
 		{
@@ -1292,7 +1300,7 @@ LLQuaternion LLAgent::getQuat() const
 	return mFrameAgent.getQuaternion();
 }
 
-
+/*
 //-----------------------------------------------------------------------------
 // calcFocusOffset()
 //-----------------------------------------------------------------------------
@@ -1845,13 +1853,11 @@ void LLAgent::cameraZoomIn(const F32 fraction)
 	{
 		new_distance = max_distance;
 
-		/*
 		// Unless camera is unlocked
-		if (!LLViewerCamera::sDisableCameraConstraints)
-		{
-			return;
-		}
-		*/
+		//if (!LLViewerCamera::sDisableCameraConstraints)
+		//{
+		//	return;
+		//}
 	}
 
 	if( cameraCustomizeAvatar() )
@@ -1985,6 +1991,7 @@ void LLAgent::cameraPanUp(F32 meters)
 	// NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
 	mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
 }
+*/
 
 //-----------------------------------------------------------------------------
 // setKey()
@@ -2546,9 +2553,10 @@ void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32
 	// Check for water and land collision, set underwater flag
 	//
 
-	updateLookAt(mouse_x, mouse_y);
+	gAgentCameraHACK.updateLookAt(mouse_x, mouse_y);
 }
 
+/*
 //-----------------------------------------------------------------------------
 // updateLookAt()
 //-----------------------------------------------------------------------------
@@ -2620,6 +2628,7 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 		setLookAt(lookAtType, mAvatarObject, headLookAxis);
 	}
 }
+*/
 
 // friends and operators
 
@@ -2652,22 +2661,22 @@ void LLAgent::setAvatarObject(LLVOAvatarSelf *avatar)
 		return;
 	}
 
-	if (!mLookAt)
+	if (!gAgentCameraHACK.mLookAt)
 	{
-		mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
+		gAgentCameraHACK.mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
 	}
-	if (!mPointAt)
+	if (!gAgentCameraHACK.mPointAt)
 	{
-		mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
+		gAgentCameraHACK.mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
 	}
 	
-	if (!mLookAt.isNull())
+	if (!gAgentCameraHACK.mLookAt.isNull())
 	{
-		mLookAt->setSourceObject(avatar);
+		gAgentCameraHACK.mLookAt->setSourceObject(avatar);
 	}
-	if (!mPointAt.isNull())
+	if (!gAgentCameraHACK.mPointAt.isNull())
 	{
-		mPointAt->setSourceObject(avatar);
+		gAgentCameraHACK.mPointAt->setSourceObject(avatar);
 	}
 }
 
@@ -2678,7 +2687,7 @@ void LLAgent::setAvatarObject(LLVOAvatarSelf *avatar)
 //-----------------------------------------------------------------------------
 BOOL LLAgent::needsRenderAvatar()
 {
-	if (cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson)
+	if (gAgentCameraHACK.cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson)
 	{
 		return FALSE;
 	}
@@ -2689,7 +2698,7 @@ BOOL LLAgent::needsRenderAvatar()
 // TRUE if we need to render your own avatar's head.
 BOOL LLAgent::needsRenderHead()
 {
-	return (LLVOAvatar::sVisibleInFirstPerson && LLPipeline::sReflectionRender) || (mShowAvatar && !cameraMouselook());
+	return (LLVOAvatar::sVisibleInFirstPerson && LLPipeline::sReflectionRender) || (mShowAvatar && !gAgentCameraHACK.cameraMouselook());
 }
 
 //-----------------------------------------------------------------------------
@@ -2711,7 +2720,7 @@ void LLAgent::startTyping()
 		LLViewerObject* chatter = gObjectList.findObject(mLastChatterID);
 		if (chatter && chatter->isAvatar())
 		{
-			gAgent.setLookAt(LOOKAT_TARGET_RESPOND, chatter, LLVector3::zero);
+			gAgentCameraHACK.setLookAt(LOOKAT_TARGET_RESPOND, chatter, LLVector3::zero);
 		}
 	}
 
@@ -2790,14 +2799,14 @@ U8 LLAgent::getRenderState()
 //-----------------------------------------------------------------------------
 void LLAgent::endAnimationUpdateUI()
 {
-	if (mCameraMode == mLastCameraMode)
+	if (gAgentCameraHACK.mCameraMode == gAgentCameraHACK.mLastCameraMode)
 	{
 		// We're already done endAnimationUpdateUI for this transition.
 		return;
 	}
 
 	// clean up UI from mode we're leaving
-	if ( mLastCameraMode == CAMERA_MODE_MOUSELOOK )
+	if (gAgentCameraHACK.mLastCameraMode == CAMERA_MODE_MOUSELOOK )
 	{
 		// show mouse cursor
 		gViewerWindow->showCursor();
@@ -2835,7 +2844,7 @@ void LLAgent::endAnimationUpdateUI()
 		}
 
 		
-		gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
+		gAgentCameraHACK.setLookAt(LOOKAT_TARGET_CLEAR);
 		if( gMorphView )
 		{
 			gMorphView->setVisible( FALSE );
@@ -2870,7 +2879,7 @@ void LLAgent::endAnimationUpdateUI()
 		}
 	}
 	else
-	if(	mLastCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR )
+	if(gAgentCameraHACK.mLastCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
 		// make sure we ask to save changes
 
@@ -2892,13 +2901,13 @@ void LLAgent::endAnimationUpdateUI()
 			}
 			
 		}
-		setLookAt(LOOKAT_TARGET_CLEAR);
+		gAgentCameraHACK.setLookAt(LOOKAT_TARGET_CLEAR);
 	}
 
 	//---------------------------------------------------------------------
 	// Set up UI for mode we're entering
 	//---------------------------------------------------------------------
-	if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+	if (gAgentCameraHACK.mCameraMode == CAMERA_MODE_MOUSELOOK)
 	{
 		// hide menus
 		gMenuBarView->setVisible(FALSE);
@@ -2913,7 +2922,7 @@ void LLAgent::endAnimationUpdateUI()
 		LLPanelStandStopFlying::getInstance()->setVisible(FALSE);
 
 		// clear out camera lag effect
-		mCameraLag.clearVec();
+		gAgentCameraHACK.mCameraLag.clearVec();
 
 		// JC - Added for always chat in third person option
 		gFocusMgr.setKeyboardFocus(NULL);
@@ -2983,7 +2992,7 @@ void LLAgent::endAnimationUpdateUI()
 		}
 
 	}
-	else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
+	else if (gAgentCameraHACK.mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
 		LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
 
@@ -3001,18 +3010,18 @@ void LLAgent::endAnimationUpdateUI()
 
 	if (getAvatarObject())
 	{
-		getAvatarObject()->updateAttachmentVisibility(mCameraMode);
+		getAvatarObject()->updateAttachmentVisibility(gAgentCameraHACK.mCameraMode);
 	}
 
 	gFloaterTools->dirty();
 
 	// Don't let this be called more than once if the camera
 	// mode hasn't changed.  --JC
-	mLastCameraMode = mCameraMode;
+	gAgentCameraHACK.mLastCameraMode = gAgentCameraHACK.mCameraMode;
 
 }
 
-
+/*
 //-----------------------------------------------------------------------------
 // updateCamera()
 //-----------------------------------------------------------------------------
@@ -3438,8 +3447,8 @@ F32 LLAgent::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global )
 			ui_offset = -offset;
 		}
 	}
-	F32 range = (F32)dist_vec(camera_pos_global, gAgent.getFocusGlobal());
-	mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f));
+	F32 range = (F32)dist_vec(camera_pos_global, gAgentCamera.getFocusGlobal());
+	gAgentCameraHACK.mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f));
 	return mUIOffset * range;
 }
 
@@ -3885,13 +3894,12 @@ LLVector3 LLAgent::getCameraOffsetInitial()
 	return mCameraOffsetInitial[mCameraPreset];
 }
 
-
 //-----------------------------------------------------------------------------
 // handleScrollWheel()
 //-----------------------------------------------------------------------------
 void LLAgent::handleScrollWheel(S32 clicks)
 {
-	if ( mCameraMode == CAMERA_MODE_FOLLOW && gAgent.getFocusOnAvatar())
+	if ( mCameraMode == CAMERA_MODE_FOLLOW && gAgentCamera.getFocusOnAvatar())
 	{
 		if ( ! mFollowCam.getPositionLocked() ) // not if the followCam position is locked in place
 		{
@@ -3935,7 +3943,6 @@ void LLAgent::handleScrollWheel(S32 clicks)
 	}
 }
 
-
 //-----------------------------------------------------------------------------
 // getCameraMinOffGround()
 //-----------------------------------------------------------------------------
@@ -4267,7 +4274,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
 
 
 
-		gAgent.setFocusGlobal(LLVector3d::zero);
+		gAgentCamera.setFocusGlobal(LLVector3d::zero);
 	}
 	else
 	{
@@ -4576,6 +4583,7 @@ void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
 	
 	mFocusOnAvatar = focus_on_avatar;
 }
+*/
 
 //-----------------------------------------------------------------------------
 // heardChat()
@@ -4592,7 +4600,7 @@ void LLAgent::heardChat(const LLUUID& id)
 	if (ll_rand(2) == 0) 
 	{
 		LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
-		setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero);
+		gAgentCameraHACK.setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero);
 	}			
 
 	mLastChatterID = id;
@@ -4605,7 +4613,7 @@ void LLAgent::heardChat(const LLUUID& id)
 void LLAgent::lookAtLastChat()
 {
 	// Block if camera is animating or not in normal third person camera mode
-	if (mCameraAnimating || !cameraThirdPerson())
+	if (gAgentCameraHACK.mCameraAnimating || !gAgentCameraHACK.cameraThirdPerson())
 	{
 		return;
 	}
@@ -4629,7 +4637,7 @@ void LLAgent::lookAtLastChat()
 
 			setControlFlags(AGENT_CONTROL_STOP);
 
-			changeCameraToThirdPerson();
+			gAgentCameraHACK.changeCameraToThirdPerson();
 
 			LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
 			LLVector3 left = delta_pos % LLVector3::z_axis;
@@ -4641,15 +4649,15 @@ void LLAgent::lookAtLastChat()
 			new_camera_pos += up * 0.2f;
 			if (chatter_av->mHeadp)
 			{
-				setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), mLastChatterID);
-				mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
+				gAgentCameraHACK.setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), mLastChatterID);
+				gAgentCameraHACK.mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
 			}
 			else
 			{
-				setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
-				mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
+				gAgentCameraHACK.setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
+				gAgentCameraHACK.mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
 			}
-			setFocusOnAvatar(FALSE, TRUE);
+			gAgentCameraHACK.setFocusOnAvatar(FALSE, TRUE);
 		}
 		else
 		{
@@ -4658,7 +4666,7 @@ void LLAgent::lookAtLastChat()
 
 			setControlFlags(AGENT_CONTROL_STOP);
 
-			changeCameraToThirdPerson();
+			gAgentCameraHACK.changeCameraToThirdPerson();
 
 			LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
 			LLVector3 left = delta_pos % LLVector3::z_axis;
@@ -4669,9 +4677,9 @@ void LLAgent::lookAtLastChat()
 			new_camera_pos += left * 0.3f;
 			new_camera_pos += up * 0.2f;
 
-			setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
-			mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
-			setFocusOnAvatar(FALSE, TRUE);
+			gAgentCameraHACK.setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
+			gAgentCameraHACK.mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
+			gAgentCameraHACK.setFocusOnAvatar(FALSE, TRUE);
 		}
 	}
 }
@@ -5182,7 +5190,7 @@ LLQuaternion LLAgent::getHeadRotation()
 		return LLQuaternion::DEFAULT;
 	}
 
-	if (!gAgent.cameraMouselook())
+	if (!gAgentCameraHACK.cameraMouselook())
 	{
 		return mAvatarObject->getRotation();
 	}
@@ -5353,10 +5361,11 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
 
 BOOL LLAgent::leftButtonGrabbed() const	
 { 
-	return (!cameraMouselook() && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0) 
-		|| (cameraMouselook() && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
-		|| (!cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
-		|| (cameraMouselook() && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
+	const BOOL camera_mouse_look = gAgentCameraHACK.cameraMouselook();
+	return (!camera_mouse_look && mControlsTakenCount[CONTROL_LBUTTON_DOWN_INDEX] > 0) 
+		|| (camera_mouse_look && mControlsTakenCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0)
+		|| (!camera_mouse_look && mControlsTakenPassedOnCount[CONTROL_LBUTTON_DOWN_INDEX] > 0)
+		|| (camera_mouse_look && mControlsTakenPassedOnCount[CONTROL_ML_LBUTTON_DOWN_INDEX] > 0);
 }
 
 BOOL LLAgent::rotateGrabbed() const		
@@ -5824,7 +5833,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
 		return;
 	}
 
-	if (gAgent.cameraCustomizeAvatar())
+	if (gAgentCameraHACK.cameraCustomizeAvatar())
 	{
 		// ignore baked textures when in customize mode
 		return;
@@ -5981,7 +5990,7 @@ bool LLAgent::teleportCore(bool is_local)
 
 	// Close all pie menus, deselect land, etc.
 	// Don't change the camera until we know teleport succeeded. JC
-	resetView(FALSE);
+	gAgentCameraHACK.resetView(FALSE);
 
 	// local logic
 	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT);
@@ -6282,7 +6291,7 @@ void LLAgent::sendAgentSetAppearance()
 {
 	if (mAvatarObject.isNull()) return;
 
-	if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar()) 
+	if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgentCameraHACK.cameraCustomizeAvatar()) 
 	{
 		return;
 	}
@@ -6500,7 +6509,41 @@ void LLAgent::dumpGroupInfo()
 	//llinfos << "insig   " << gAgent.mGroupInsigniaID << llendl;
 }
 
-/********************************************************************************/
+// Draw a representation of current autopilot target
+void LLAgent::renderAutoPilotTarget()
+{
+	if (mAutoPilot)
+	{
+		F32 height_meters;
+		LLVector3d target_global;
+
+		glMatrixMode(GL_MODELVIEW);
+		gGL.pushMatrix();
+
+		// not textured
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+		// lovely green
+		glColor4f(0.f, 1.f, 1.f, 1.f);
+
+		target_global = mAutoPilotTargetGlobal;
+
+		gGL.translatef((F32)(target_global.mdV[VX]), (F32)(target_global.mdV[VY]), (F32)(target_global.mdV[VZ]));
+
+		height_meters = 1.f;
+
+		glScalef(height_meters, height_meters, height_meters);
+
+		gSphere.render(1500.f);
+
+		gGL.popMatrix();
+	}
+}
+
+/********************************************************************************
+ *
+ */
+
 LLAgentQueryManager gAgentQueryManager;
 
 LLAgentQueryManager::LLAgentQueryManager() :
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index f2df1992e7..d196c1c1c1 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -66,6 +66,11 @@ class LLAgentDropGroupViewerNode;
 //--------------------------------------------------------------------
 // Types
 //--------------------------------------------------------------------
+//--------------------------------------------------------------------
+// Types
+//--------------------------------------------------------------------
+
+/*
 enum ECameraMode
 {
 	CAMERA_MODE_THIRD_PERSON,
@@ -74,18 +79,19 @@ enum ECameraMode
 	CAMERA_MODE_FOLLOW
 };
 
-/** Camera Presets for CAMERA_MODE_THIRD_PERSON */
+// Camera Presets for CAMERA_MODE_THIRD_PERSON
 enum ECameraPreset 
 {
-	/** Default preset, what the Third Person Mode actually was */
+	// Default preset, what the Third Person Mode actually was
 	CAMERA_PRESET_REAR_VIEW,
 	
-	/** "Looking at the Avatar from the front" */
+	// "Looking at the Avatar from the front"
 	CAMERA_PRESET_FRONT_VIEW, 
 
-	/** "Above and to the left, over the shoulder, pulled back a little on the zoom" */
+	// "Above and to the left, over the shoulder, pulled back a little on the zoom"
 	CAMERA_PRESET_GROUP_VIEW
 };
+*/
 
 enum EAnimRequest
 {
@@ -115,6 +121,7 @@ class LLAgent : public LLOldEvents::LLObservable
 
 public:
 	friend class LLAgentDropGroupViewerNode;
+	friend class LLAgentCamera;
 
 /********************************************************************************
  **                                                                            **
@@ -448,8 +455,8 @@ public:
 	void			sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request);
 	void			endAnimationUpdateUI();
 private:
-	LLFrameTimer	mAnimationTimer; 	// Seconds that transition animation has been active
-	F32				mAnimationDuration;	// In seconds
+	LLFrameTimer	mAnimationTimer; 	// Seconds that transition animation has been active // SERAPH REMOVE
+	F32				mAnimationDuration;	// In seconds // SERAPH REMOVE
 	BOOL            mCustomAnim; 		// Current animation is ANIM_AGENT_CUSTOMIZE ?
 	LLAnimPauseRequest mPauseRequest;
 	BOOL			mViewsPushed; 		// Keep track of whether or not we have pushed views
@@ -491,6 +498,7 @@ public:
 	void			moveYaw(F32 mag, bool reset_view = true);
 	void			movePitch(F32 mag);
 
+	// SERAPH Remove this whole section
 	//--------------------------------------------------------------------
 	// Orbit
 	//--------------------------------------------------------------------
@@ -509,6 +517,7 @@ private:
 	F32				mOrbitInKey;
 	F32				mOrbitOutKey;
 	
+	// SERAPH Remove this whole section
 	//--------------------------------------------------------------------
 	// Pan
 	//--------------------------------------------------------------------
@@ -643,6 +652,7 @@ private:
  **                    CAMERA
  **/
 
+/*
 	//--------------------------------------------------------------------
 	// Mode
 	//--------------------------------------------------------------------
@@ -654,7 +664,7 @@ public:
 	void			changeCameraToFollow(BOOL animate = TRUE); 	// Ventrella
 	BOOL			cameraThirdPerson() const		{ return (mCameraMode == CAMERA_MODE_THIRD_PERSON && mLastCameraMode == CAMERA_MODE_THIRD_PERSON); }
 	BOOL			cameraMouselook() const			{ return (mCameraMode == CAMERA_MODE_MOUSELOOK && mLastCameraMode == CAMERA_MODE_MOUSELOOK); }
-	BOOL			cameraCustomizeAvatar() const	{ return (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR /*&& !mCameraAnimating*/); }
+	BOOL			cameraCustomizeAvatar() const	{ return (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR); }
 	BOOL			cameraFollow() const			{ return (mCameraMode == CAMERA_MODE_FOLLOW && mLastCameraMode == CAMERA_MODE_FOLLOW); }
 	ECameraMode		getCameraMode() const 			{ return mCameraMode; }
 	void			updateCamera();					// Call once per frame to update camera location/orientation
@@ -671,19 +681,18 @@ public:
 
 private:
 	
-	/** Determines default camera offset depending on the current camera preset */
+	// Determines default camera offset depending on the current camera preset
 	LLVector3 getCameraOffsetInitial();
 
-	/** Camera preset in Third Person Mode */
+	// Camera preset in Third Person Mode
 	ECameraPreset mCameraPreset; 
 
-	/** Initial camera offsets */
+	// Initial camera offsets
 	std::map<ECameraPreset, LLVector3> mCameraOffsetInitial;
 
-	/** Initial focus offsets */
+	// Initial focus offsets
 	std::map<ECameraPreset, LLVector3d> mFocusOffsetInitial;
 
-
 	//--------------------------------------------------------------------
 	// Position
 	//--------------------------------------------------------------------
@@ -733,6 +742,7 @@ private:
 	BOOL			mSitCameraEnabled;		// Use provided camera information when sitting?
 	LLVector3		mSitCameraPos;			// Root relative camera pos when sitting
 	LLVector3		mSitCameraFocus;		// Root relative camera target when sitting
+#endif
 
 	//--------------------------------------------------------------------
 	// Animation
@@ -781,20 +791,6 @@ private:
 	BOOL			mTrackFocusObject;
 	F32				mUIOffset;	
 	
-	//--------------------------------------------------------------------
-	// Lookat / Pointat
-	//--------------------------------------------------------------------
-public:
-	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 			slamLookAt(const LLVector3 &look_at); // Set the physics data
-	BOOL			setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
-	EPointAtType	getPointAtType();
-public:
-	LLPointer<LLHUDEffectLookAt> mLookAt;
-	LLPointer<LLHUDEffectPointAt> mPointAt;
-
 	//--------------------------------------------------------------------
 	// Third person
 	//--------------------------------------------------------------------
@@ -848,15 +844,14 @@ public:
 private:
 	BOOL			mForceMouselook;
 	
+*/
+
 	//--------------------------------------------------------------------
 	// HUD
 	//--------------------------------------------------------------------
 public:
 	const LLColor4	&getEffectColor();
 	void			setEffectColor(const LLColor4 &color);
-public:
-	F32				mHUDTargetZoom;	// Target zoom level for HUD objects (used when editing)
-	F32				mHUDCurZoom; 	// Current animated zoom level for HUD objects
 private:
 	LLUIColor 		mEffectColor;
 
@@ -864,6 +859,8 @@ private:
  **                                                                            **
  *******************************************************************************/
 
+
+
 /********************************************************************************
  **                                                                            **
  **                    ACCESS
@@ -939,7 +936,7 @@ public:
 	BOOL			needsRenderAvatar(); // TRUE when camera mode is such that your own avatar should draw
 	BOOL			needsRenderHead();
 public:
-	F32				mDrawDistance;
+	F32				mDrawDistance; // SERAPH REMOVE
 private:
 	BOOL			mShowAvatar; 		// Should we render the avatar?
 	U32				mAppearanceSerialNum;
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
new file mode 100644
index 0000000000..f1422e2442
--- /dev/null
+++ b/indra/newview/llagentcamera.cpp
@@ -0,0 +1,2806 @@
+/** 
+ * @file llagentcamera.cpp
+ * @brief LLAgent class implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llagentcamera.h" 
+
+#include "pipeline.h"
+
+#include "llagentlistener.h"
+#include "llagentwearables.h"
+#include "llagentui.h"
+#include "llanimationstates.h"
+#include "llbottomtray.h"
+#include "llcallingcard.h"
+#include "llchannelmanager.h"
+#include "llconsole.h"
+//#include "llfirstuse.h"
+#include "llfloatercamera.h"
+#include "llfloatercustomize.h"
+#include "llfloaterreg.h"
+#include "llfloatertools.h"
+#include "llgroupactions.h"
+#include "llgroupmgr.h"
+#include "llhomelocationresponder.h"
+#include "llhudmanager.h"
+#include "lljoystickbutton.h"
+#include "llmorphview.h"
+#include "llmoveview.h"
+#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
+#include "llnearbychatbar.h"
+#include "llnotificationsutil.h"
+#include "llparcel.h"
+#include "llsdutil.h"
+#include "llsidetray.h"
+#include "llsky.h"
+#include "llsmoothstep.h"
+#include "llstatusbar.h"
+#include "llteleportflags.h"
+#include "lltool.h"
+#include "lltoolmgr.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewerdisplay.h"
+#include "llviewerjoystick.h"
+#include "llviewermediafocus.h"
+#include "llviewerobjectlist.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerstats.h"
+#include "llvoavatarself.h"
+#include "llwindow.h"
+#include "llworld.h"
+#include "llworldmap.h"
+
+static LLAgent gAgentHACK = gAgent;
+
+using namespace LLVOAvatarDefines;
+
+extern LLMenuBarGL* gMenuBarView;
+
+/*
+const BOOL ANIMATE = TRUE;
+const U8 AGENT_STATE_TYPING =	0x04;
+const U8 AGENT_STATE_EDITING =  0x10;
+
+//drone wandering constants
+const F32 MAX_WANDER_TIME = 20.f;						// seconds
+const F32 MAX_HEADING_HALF_ERROR = 0.2f;				// radians
+const F32 WANDER_MAX_SLEW_RATE = 2.f * DEG_TO_RAD;		// radians / frame
+const F32 WANDER_TARGET_MIN_DISTANCE = 10.f;			// meters
+
+// Autopilot constants
+const F32 AUTOPILOT_HEADING_HALF_ERROR = 10.f * DEG_TO_RAD;	// radians
+const F32 AUTOPILOT_MAX_SLEW_RATE = 1.f * DEG_TO_RAD;		// radians / frame
+const F32 AUTOPILOT_STOP_DISTANCE = 2.f;					// meters
+const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f;			// meters
+const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f;	// meters
+const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f;		// seconds
+
+// face editing constants
+const LLVector3d FACE_EDIT_CAMERA_OFFSET(0.4f, -0.05f, 0.07f);
+const LLVector3d FACE_EDIT_TARGET_OFFSET(0.f, 0.f, 0.05f);
+*/
+
+// Mousewheel camera zoom
+const F32 MIN_ZOOM_FRACTION = 0.25f;
+const F32 INITIAL_ZOOM_FRACTION = 1.f;
+const F32 MAX_ZOOM_FRACTION = 8.f;
+
+/*
+const F32 METERS_PER_WHEEL_CLICK = 1.f;
+
+const F32 MAX_TIME_DELTA = 1.f;
+*/
+
+const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f;	// seconds
+const F32 FOV_ZOOM_HALF_LIFE = 0.07f;	// seconds
+
+const F32 CAMERA_FOCUS_HALF_LIFE = 0.f;//0.02f;
+const F32 CAMERA_LAG_HALF_LIFE = 0.25f;
+const F32 MIN_CAMERA_LAG = 0.5f;
+const F32 MAX_CAMERA_LAG = 5.f;
+
+const F32 CAMERA_COLLIDE_EPSILON = 0.1f;
+const F32 MIN_CAMERA_DISTANCE = 0.1f;
+
+const F32 AVATAR_ZOOM_MIN_X_FACTOR = 0.55f;
+const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.7f;
+const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
+
+const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
+
+const F32 MAX_CAMERA_SMOOTH_DISTANCE = 50.0f;
+
+const F32 HEAD_BUFFER_SIZE = 0.3f;
+
+const F32 CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP = 0.2f;
+
+const F32 LAND_MIN_ZOOM = 0.15f;
+
+const F32 AVATAR_MIN_ZOOM = 0.5f;
+const F32 OBJECT_MIN_ZOOM = 0.02f;
+
+const F32 APPEARANCE_MIN_ZOOM = 0.39f;
+const F32 APPEARANCE_MAX_ZOOM = 8.f;
+
+/*
+// fidget constants
+const F32 MIN_FIDGET_TIME = 8.f; // seconds
+const F32 MAX_FIDGET_TIME = 20.f; // seconds
+
+const S32 MAX_NUM_CHAT_POSITIONS = 10;
+*/
+
+const F32 GROUND_TO_AIR_CAMERA_TRANSITION_TIME = 0.5f;
+const F32 GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME = 0.5f;
+/*
+const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
+
+const F32 MAX_FOCUS_OFFSET = 20.f;
+*/
+
+const F32 OBJECT_EXTENTS_PADDING = 0.5f;
+/*
+const F32 MIN_RADIUS_ALPHA_SIZZLE = 0.5f;
+
+const F64 CHAT_AGE_FAST_RATE = 3.0;
+*/
+
+// The agent instance.
+LLAgentCamera gAgentCamera;
+
+//-----------------------------------------------------------------------------
+// LLAgentCamera()
+//-----------------------------------------------------------------------------
+LLAgentCamera::LLAgentCamera() :
+	mLookAt(NULL),
+	mPointAt(NULL),
+
+	mCameraMode( CAMERA_MODE_THIRD_PERSON ),
+	mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
+
+	mCameraPreset(CAMERA_PRESET_REAR_VIEW),
+
+	mCameraAnimating( FALSE ),
+	mAnimationCameraStartGlobal(),
+	mAnimationFocusStartGlobal(),
+	mAnimationTimer(),
+	mAnimationDuration(0.33f),
+	
+	mCameraFOVZoomFactor(0.f),
+	mCameraCurrentFOVZoomFactor(0.f),
+	mCameraFocusOffset(),
+	mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
+
+	mCameraCollidePlane(),
+
+	mCurrentCameraDistance(2.f),		// meters, set in init()
+	mTargetCameraDistance(2.f),
+	mCameraZoomFraction(1.f),			// deprecated
+	mThirdPersonHeadOffset(0.f, 0.f, 1.f),
+	mSitCameraEnabled(FALSE),
+	mCameraSmoothingLastPositionGlobal(),
+	mCameraSmoothingLastPositionAgent(),
+	mCameraSmoothingStop(FALSE),
+
+	mCameraUpVector(LLVector3::z_axis), // default is straight up
+
+	mFocusOnAvatar(TRUE),
+	mFocusGlobal(),
+	mFocusTargetGlobal(),
+	mFocusObject(NULL),
+	mFocusObjectDist(0.f),
+	mFocusObjectOffset(),
+	mFocusDotRadius( 0.1f ),			// meters
+	mTrackFocusObject(TRUE),
+	mUIOffset(0.f),
+
+	mOrbitLeftKey(0.f),
+	mOrbitRightKey(0.f),
+	mOrbitUpKey(0.f),
+	mOrbitDownKey(0.f),
+	mOrbitInKey(0.f),
+	mOrbitOutKey(0.f),
+
+	mPanUpKey(0.f),
+	mPanDownKey(0.f),
+	mPanLeftKey(0.f),
+	mPanRightKey(0.f),
+	mPanInKey(0.f),
+	mPanOutKey(0.f)
+{
+}
+
+// Requires gSavedSettings to be initialized.
+//-----------------------------------------------------------------------------
+// init()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::init()
+{
+	// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
+
+	LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW);
+	// Leave at 0.1 meters until we have real near clip management
+	LLViewerCamera::getInstance()->setNear(0.1f);
+	LLViewerCamera::getInstance()->setFar(mDrawDistance);			// if you want to change camera settings, do so in camera.h
+	LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() );		// default, overridden in LLViewerWindow::reshape
+	LLViewerCamera::getInstance()->setViewHeightInPixels(768);			// default, overridden in LLViewerWindow::reshape
+
+	mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
+	
+	mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
+
+	mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3("CameraOffsetRearView");
+	mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3("CameraOffsetFrontView");
+	mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3("CameraOffsetGroupView");
+
+	mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3d("FocusOffsetRearView");
+	mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3d("FocusOffsetFrontView");
+	mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3d("FocusOffsetGroupView");
+
+	mCameraCollidePlane.clearVec();
+	mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
+	mTargetCameraDistance = mCurrentCameraDistance;
+	mCameraZoomFraction = 1.f;
+	mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
+
+	mInitialized = TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// cleanup()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cleanup()
+{
+	setSitCamera(LLUUID::null);
+
+	if(mLookAt)
+	{
+		mLookAt->markDead() ;
+		mLookAt = NULL;
+	}
+	if(mPointAt)
+	{
+		mPointAt->markDead() ;
+		mPointAt = NULL;
+	}
+	setFocusObject(NULL);
+}
+
+//-----------------------------------------------------------------------------
+// LLAgent()
+//-----------------------------------------------------------------------------
+LLAgentCamera::~LLAgentCamera()
+{
+	cleanup();
+
+	// *Note: this is where LLViewerCamera::getInstance() used to be deleted.
+}
+
+// Change camera back to third person, stop the autopilot,
+// deselect stuff, etc.
+//-----------------------------------------------------------------------------
+// resetView()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera)
+{
+	if (gAgentHACK.mAutoPilot)
+	{
+		gAgentHACK.stopAutoPilot(TRUE);
+	}
+
+	if (!gNoRender)
+	{
+		LLSelectMgr::getInstance()->unhighlightAll();
+
+		// By popular request, keep land selection while walking around. JC
+		// LLViewerParcelMgr::getInstance()->deselectLand();
+
+		// force deselect when walking and attachment is selected
+		// this is so people don't wig out when their avatar moves without animating
+		if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
+		{
+			LLSelectMgr::getInstance()->deselectAll();
+		}
+
+		// Hide all popup menus
+		gMenuHolder->hideMenus();
+	}
+
+	if (change_camera && !gSavedSettings.getBOOL("FreezeTime"))
+	{
+		changeCameraToDefault();
+		
+		if (LLViewerJoystick::getInstance()->getOverrideCamera())
+		{
+			handle_toggle_flycam();
+		}
+
+		// reset avatar mode from eventual residual motion
+		if (LLToolMgr::getInstance()->inBuildMode())
+		{
+			LLViewerJoystick::getInstance()->moveAvatar(true);
+		}
+
+		//Camera Tool is needed for Free Camera Control Mode
+		if (!LLFloaterCamera::inFreeCameraMode())
+		{
+			LLFloaterReg::hideInstance("build");
+
+			// Switch back to basic toolset
+			LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+		}
+		
+		gViewerWindow->showCursor();
+	}
+
+
+	if (reset_camera && !gSavedSettings.getBOOL("FreezeTime"))
+	{
+		if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson())
+		{
+			// leaving mouse-steer mode
+			LLVector3 agent_at_axis = gAgentHACK.getAtAxis();
+			agent_at_axis -= projected_vec(agent_at_axis, gAgentHACK.getReferenceUpVector());
+			agent_at_axis.normalize();
+			gAgentHACK.resetAxes(lerp(gAgentHACK.getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f)));
+		}
+
+		setFocusOnAvatar(TRUE, ANIMATE);
+
+		mCameraFOVZoomFactor = 0.f;
+	}
+
+	mHUDTargetZoom = 1.f;
+}
+
+// Allow camera to be moved somewhere other than behind avatar.
+//-----------------------------------------------------------------------------
+// unlockView()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::unlockView()
+{
+	if (getFocusOnAvatar())
+	{
+		if (gAgentHACK.mAvatarObject.notNull())
+		{
+			setFocusGlobal( LLVector3d::zero, gAgentHACK.mAvatarObject->mID );
+		}
+		setFocusOnAvatar(FALSE, FALSE);	// no animation
+	}
+}
+
+//-----------------------------------------------------------------------------
+// slamLookAt()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::slamLookAt(const LLVector3 &look_at)
+{
+	LLVector3 look_at_norm = look_at;
+	look_at_norm.mV[VZ] = 0.f;
+	look_at_norm.normalize();
+	gAgentHACK.resetAxes(look_at_norm);
+}
+
+//-----------------------------------------------------------------------------
+// calcFocusOffset()
+//-----------------------------------------------------------------------------
+LLVector3 LLAgentCamera::calcFocusOffset(LLViewerObject *object, LLVector3 original_focus_point, S32 x, S32 y)
+{
+	LLMatrix4 obj_matrix = object->getRenderMatrix();
+	LLQuaternion obj_rot = object->getRenderRotation();
+	LLVector3 obj_pos = object->getRenderPosition();
+
+	BOOL is_avatar = object->isAvatar();
+	// if is avatar - don't do any funk heuristics to position the focal point
+	// see DEV-30589
+	if (is_avatar)
+	{
+		return original_focus_point - obj_pos;
+	}
+
+	
+	LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation
+	LLVector3 object_extents = object->getScale();
+	// make sure they object extents are non-zero
+	object_extents.clamp(0.001f, F32_MAX);
+
+	// obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object
+	LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin();
+	obj_to_cam_ray.rotVec(inv_obj_rot);
+	obj_to_cam_ray.normalize();
+
+	// obj_to_cam_ray_proportions are the (positive) ratios of 
+	// the obj_to_cam_ray x,y,z components with the x,y,z object dimensions.
+	LLVector3 obj_to_cam_ray_proportions;
+	obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]);
+	obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]);
+	obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]);
+
+	// find the largest ratio stored in obj_to_cam_ray_proportions
+	// this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera
+	LLVector3 longest_object_axis;
+	// is x-axis longest?
+	if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY] 
+		&& obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ])
+	{
+		// then grab it
+		longest_object_axis.setVec(obj_matrix.getFwdRow4());
+	}
+	// is y-axis longest?
+	else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ])
+	{
+		// then grab it
+		longest_object_axis.setVec(obj_matrix.getLeftRow4());
+	}
+	// otherwise, use z axis
+	else
+	{
+		longest_object_axis.setVec(obj_matrix.getUpRow4());
+	}
+
+	// Use this axis as the normal to project mouse click on to plane with that normal, at the object center.
+	// This generates a point behind the mouse cursor that is approximately in the middle of the object in
+	// terms of depth.  
+	// We do this to allow the camera rotation tool to "tumble" the object by rotating the camera.
+	// If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable
+	// eccentricity to the object orientation
+	LLVector3 focus_plane_normal(longest_object_axis);
+	focus_plane_normal.normalize();
+
+	LLVector3d focus_pt_global;
+	gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal);
+	LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global);
+
+	// find vector from camera to focus point in object space
+	LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin();
+	camera_to_focus_vec.rotVec(inv_obj_rot);
+
+	// find vector from object origin to focus point in object coordinates
+	LLVector3 focus_offset_from_object_center = focus_pt - obj_pos;
+	// convert to object-local space
+	focus_offset_from_object_center.rotVec(inv_obj_rot);
+
+	// We need to project the focus point back into the bounding box of the focused object.
+	// Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis
+	LLVector3 clip_fraction;
+
+	// for each axis...
+	for (U32 axis = VX; axis <= VZ; axis++)
+	{
+		//...calculate distance that focus offset sits outside of bounding box along that axis...
+		//NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center 
+		F32 dist_out_of_bounds;
+		if (focus_offset_from_object_center.mV[axis] > 0.f)
+		{
+			dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f));
+		}
+		else
+		{
+			dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f));
+		}
+
+		//...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis
+		if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f)
+		{
+			// don't divide by very small number
+			clip_fraction.mV[axis] = 0.f;
+		}
+		else
+		{
+			clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis];
+		}
+	}
+
+	LLVector3 abs_clip_fraction = clip_fraction;
+	abs_clip_fraction.abs();
+
+	// find axis of focus offset that is *most* outside the bounding box and use that to
+	// rescale focus offset to inside object extents
+	if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY]
+		&& abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ])
+	{
+		focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec;
+	}
+	else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ])
+	{
+		focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec;
+	}
+	else
+	{
+		focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec;
+	}
+
+	// convert back to world space
+	focus_offset_from_object_center.rotVec(obj_rot);
+	
+	// now, based on distance of camera from object relative to object size
+	// push the focus point towards the near surface of the object when (relatively) close to the objcet
+	// or keep the focus point in the object middle when (relatively) far
+	// NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
+	// is almost always "tumble about middle" and not "spin around surface point"
+	if (!is_avatar) 
+	{
+		LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
+		
+		//now that we have the object relative position, we should bias toward the center of the object 
+		//based on the distance of the camera to the focus point vs. the distance of the camera to the focus
+
+		F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis());
+		F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin());
+
+
+		LLBBox obj_bbox = object->getBoundingBoxAgent();
+		F32 bias = 0.f;
+
+		// virtual_camera_pos is the camera position we are simulating by backing the camera off
+		// and adjusting the FOV
+		LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor));
+
+		// if the camera is inside the object (large, hollow objects, for example)
+		// leave focus point all the way to destination depth, away from object center
+		if(!obj_bbox.containsPointAgent(virtual_camera_pos))
+		{
+			// perform magic number biasing of focus point towards surface vs. planar center
+			bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f);
+			obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias);
+		}
+			
+		focus_offset_from_object_center = obj_rel;
+	}
+
+	return focus_offset_from_object_center;
+}
+
+//-----------------------------------------------------------------------------
+// calcCameraMinDistance()
+//-----------------------------------------------------------------------------
+BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
+{
+	BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars)
+
+	if (!mFocusObject || mFocusObject->isDead())
+	{
+		obj_min_distance = 0.f;
+		return TRUE;
+	}
+
+	if (mFocusObject->mDrawable.isNull())
+	{
+#ifdef LL_RELEASE_FOR_DOWNLOAD
+		llwarns << "Focus object with no drawable!" << llendl;
+#else
+		mFocusObject->dump();
+		llerrs << "Focus object with no drawable!" << llendl;
+#endif
+		obj_min_distance = 0.f;
+		return TRUE;
+	}
+	
+	LLQuaternion inv_object_rot = ~mFocusObject->getRenderRotation();
+	LLVector3 target_offset_origin = mFocusObjectOffset;
+	LLVector3 camera_offset_target(getCameraPositionAgent() - gAgentHACK.getPosAgentFromGlobal(mFocusTargetGlobal));
+
+	// convert offsets into object local space
+	camera_offset_target.rotVec(inv_object_rot);
+	target_offset_origin.rotVec(inv_object_rot);
+
+	// push around object extents based on target offset
+	LLVector3 object_extents = mFocusObject->getScale();
+	if (mFocusObject->isAvatar())
+	{
+		// fudge factors that lets you zoom in on avatars a bit more (which don't do FOV zoom)
+		object_extents.mV[VX] *= AVATAR_ZOOM_MIN_X_FACTOR;
+		object_extents.mV[VY] *= AVATAR_ZOOM_MIN_Y_FACTOR;
+		object_extents.mV[VZ] *= AVATAR_ZOOM_MIN_Z_FACTOR;
+		soft_limit = TRUE;
+	}
+	LLVector3 abs_target_offset = target_offset_origin;
+	abs_target_offset.abs();
+
+	LLVector3 target_offset_dir = target_offset_origin;
+	F32 object_radius = mFocusObject->getVObjRadius();
+
+	BOOL target_outside_object_extents = FALSE;
+
+	for (U32 i = VX; i <= VZ; i++)
+	{
+		if (abs_target_offset.mV[i] * 2.f > object_extents.mV[i] + OBJECT_EXTENTS_PADDING)
+		{
+			target_outside_object_extents = TRUE;
+		}
+		if (camera_offset_target.mV[i] > 0.f)
+		{
+			object_extents.mV[i] -= target_offset_origin.mV[i] * 2.f;
+		}
+		else
+		{
+			object_extents.mV[i] += target_offset_origin.mV[i] * 2.f;
+		}
+	}
+
+	// don't shrink the object extents so far that the object inverts
+	object_extents.clamp(0.001f, F32_MAX);
+
+	// move into first octant
+	LLVector3 camera_offset_target_abs_norm = camera_offset_target;
+	camera_offset_target_abs_norm.abs();
+	// make sure offset is non-zero
+	camera_offset_target_abs_norm.clamp(0.001f, F32_MAX);
+	camera_offset_target_abs_norm.normalize();
+
+	// find camera position relative to normalized object extents
+	LLVector3 camera_offset_target_scaled = camera_offset_target_abs_norm;
+	camera_offset_target_scaled.mV[VX] /= object_extents.mV[VX];
+	camera_offset_target_scaled.mV[VY] /= object_extents.mV[VY];
+	camera_offset_target_scaled.mV[VZ] /= object_extents.mV[VZ];
+
+	if (camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VY] && 
+		camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VZ])
+	{
+		if (camera_offset_target_abs_norm.mV[VX] < 0.001f)
+		{
+			obj_min_distance = object_extents.mV[VX] * 0.5f;
+		}
+		else
+		{
+			obj_min_distance = object_extents.mV[VX] * 0.5f / camera_offset_target_abs_norm.mV[VX];
+		}
+	}
+	else if (camera_offset_target_scaled.mV[VY] > camera_offset_target_scaled.mV[VZ])
+	{
+		if (camera_offset_target_abs_norm.mV[VY] < 0.001f)
+		{
+			obj_min_distance = object_extents.mV[VY] * 0.5f;
+		}
+		else
+		{
+			obj_min_distance = object_extents.mV[VY] * 0.5f / camera_offset_target_abs_norm.mV[VY];
+		}
+	}
+	else
+	{
+		if (camera_offset_target_abs_norm.mV[VZ] < 0.001f)
+		{
+			obj_min_distance = object_extents.mV[VZ] * 0.5f;
+		}
+		else
+		{
+			obj_min_distance = object_extents.mV[VZ] * 0.5f / camera_offset_target_abs_norm.mV[VZ];
+		}
+	}
+
+	LLVector3 object_split_axis;
+	LLVector3 target_offset_scaled = target_offset_origin;
+	target_offset_scaled.abs();
+	target_offset_scaled.normalize();
+	target_offset_scaled.mV[VX] /= object_extents.mV[VX];
+	target_offset_scaled.mV[VY] /= object_extents.mV[VY];
+	target_offset_scaled.mV[VZ] /= object_extents.mV[VZ];
+
+	if (target_offset_scaled.mV[VX] > target_offset_scaled.mV[VY] && 
+		target_offset_scaled.mV[VX] > target_offset_scaled.mV[VZ])
+	{
+		object_split_axis = LLVector3::x_axis;
+	}
+	else if (target_offset_scaled.mV[VY] > target_offset_scaled.mV[VZ])
+	{
+		object_split_axis = LLVector3::y_axis;
+	}
+	else
+	{
+		object_split_axis = LLVector3::z_axis;
+	}
+
+	LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
+
+	// length projected orthogonal to target offset
+	F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec();
+
+	// calculate whether the target point would be "visible" if it were outside the bounding box
+	// on the opposite of the splitting plane defined by object_split_axis;
+	BOOL exterior_target_visible = FALSE;
+	if (camera_offset_dist > object_radius)
+	{
+		// target is visible from camera, so turn off fov zoom
+		exterior_target_visible = TRUE;
+	}
+
+	F32 camera_offset_clip = camera_offset_object * object_split_axis;
+	F32 target_offset_clip = target_offset_dir * object_split_axis;
+
+	// target has moved outside of object extents
+	// check to see if camera and target are on same side 
+	if (target_outside_object_extents)
+	{
+		if (camera_offset_clip > 0.f && target_offset_clip > 0.f)
+		{
+			return FALSE;
+		}
+		else if (camera_offset_clip < 0.f && target_offset_clip < 0.f)
+		{
+			return FALSE;
+		}
+	}
+
+	// clamp obj distance to diagonal of 10 by 10 cube
+	obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3);
+
+	obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f);
+	
+	return TRUE;
+}
+
+F32 LLAgentCamera::getCameraZoomFraction()
+{
+	// 0.f -> camera zoomed all the way out
+	// 1.f -> camera zoomed all the way in
+	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+	{
+		// already [0,1]
+		return mHUDTargetZoom;
+	}
+	else if (mFocusOnAvatar && cameraThirdPerson())
+	{
+		return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
+	}
+	else if (cameraCustomizeAvatar())
+	{
+		F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
+		return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f );
+	}
+	else
+	{
+		F32 min_zoom;
+		const F32 DIST_FUDGE = 16.f; // meters
+		F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 
+								LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
+								MAX_CAMERA_DISTANCE_FROM_AGENT);
+
+		F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
+		if (mFocusObject.notNull())
+		{
+			if (mFocusObject->isAvatar())
+			{
+				min_zoom = AVATAR_MIN_ZOOM;
+			}
+			else
+			{
+				min_zoom = OBJECT_MIN_ZOOM;
+			}
+		}
+		else
+		{
+			min_zoom = LAND_MIN_ZOOM;
+		}
+
+		return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f);
+	}
+}
+
+void LLAgentCamera::setCameraZoomFraction(F32 fraction)
+{
+	// 0.f -> camera zoomed all the way out
+	// 1.f -> camera zoomed all the way in
+	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+	{
+		mHUDTargetZoom = fraction;
+	}
+	else if (mFocusOnAvatar && cameraThirdPerson())
+	{
+		mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION);
+	}
+	else if (cameraCustomizeAvatar())
+	{
+		LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
+		camera_offset_dir.normalize();
+		mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, APPEARANCE_MAX_ZOOM, APPEARANCE_MIN_ZOOM);
+	}
+	else
+	{
+		F32 min_zoom = LAND_MIN_ZOOM;
+		const F32 DIST_FUDGE = 16.f; // meters
+		F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 
+								LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
+								MAX_CAMERA_DISTANCE_FROM_AGENT);
+
+		if (mFocusObject.notNull())
+		{
+			if (mFocusObject.notNull())
+			{
+				if (mFocusObject->isAvatar())
+				{
+					min_zoom = AVATAR_MIN_ZOOM;
+				}
+				else
+				{
+					min_zoom = OBJECT_MIN_ZOOM;
+				}
+			}
+		}
+
+		LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
+		camera_offset_dir.normalize();
+		mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom);
+	}
+	startCameraAnimation();
+}
+
+
+//-----------------------------------------------------------------------------
+// cameraOrbitAround()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraOrbitAround(const F32 radians)
+{
+	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+	{
+		// do nothing for hud selection
+	}
+	else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW))
+	{
+		gAgentHACK.mFrameAgent.rotate(radians, gAgentHACK.getReferenceUpVector());
+	}
+	else
+	{
+		mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f);
+		
+		cameraZoomIn(1.f);
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+// cameraOrbitOver()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraOrbitOver(const F32 angle)
+{
+	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+	{
+		// do nothing for hud selection
+	}
+	else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
+	{
+		gAgentHACK.pitch(angle);
+	}
+	else
+	{
+		LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
+		camera_offset_unit.normalize();
+
+		F32 angle_from_up = acos( camera_offset_unit * gAgentHACK.getReferenceUpVector() );
+
+		LLVector3d left_axis;
+		left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+		F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
+		mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
+
+		cameraZoomIn(1.f);
+	}
+}
+
+//-----------------------------------------------------------------------------
+// cameraZoomIn()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraZoomIn(const F32 fraction)
+{
+	if (gDisconnected)
+	{
+		return;
+	}
+
+	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+	if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+	{
+		// just update hud zoom level
+		mHUDTargetZoom /= fraction;
+		return;
+	}
+
+
+	LLVector3d	camera_offset(mCameraFocusOffsetTarget);
+	LLVector3d	camera_offset_unit(mCameraFocusOffsetTarget);
+	F32 min_zoom = LAND_MIN_ZOOM;
+	F32 current_distance = (F32)camera_offset_unit.normalize();
+	F32 new_distance = current_distance * fraction;
+
+	// Don't move through focus point
+	if (mFocusObject)
+	{
+		LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]);
+
+		if (mFocusObject->isAvatar())
+		{
+			calcCameraMinDistance(min_zoom);
+		}
+		else
+		{
+			min_zoom = OBJECT_MIN_ZOOM;
+		}
+	}
+
+	new_distance = llmax(new_distance, min_zoom); 
+
+	// Don't zoom too far back
+	const F32 DIST_FUDGE = 16.f; // meters
+	F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
+							 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
+
+	if (new_distance > max_distance)
+	{
+		new_distance = max_distance;
+
+		/*
+		// Unless camera is unlocked
+		if (!LLViewerCamera::sDisableCameraConstraints)
+		{
+			return;
+		}
+		*/
+	}
+
+	if( cameraCustomizeAvatar() )
+	{
+		new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
+	}
+
+	mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
+}
+
+//-----------------------------------------------------------------------------
+// cameraOrbitIn()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraOrbitIn(const F32 meters)
+{
+	if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
+	{
+		F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"));
+		
+		mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
+
+		if (!gSavedSettings.getBOOL("FreezeTime") && mCameraZoomFraction < MIN_ZOOM_FRACTION && meters > 0.f)
+		{
+			// No need to animate, camera is already there.
+			changeCameraToMouselook(FALSE);
+		}
+
+		mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION);
+	}
+	else
+	{
+		LLVector3d	camera_offset(mCameraFocusOffsetTarget);
+		LLVector3d	camera_offset_unit(mCameraFocusOffsetTarget);
+		F32 current_distance = (F32)camera_offset_unit.normalize();
+		F32 new_distance = current_distance - meters;
+		F32 min_zoom = LAND_MIN_ZOOM;
+		
+		// Don't move through focus point
+		if (mFocusObject.notNull())
+		{
+			if (mFocusObject->isAvatar())
+			{
+				min_zoom = AVATAR_MIN_ZOOM;
+			}
+			else
+			{
+				min_zoom = OBJECT_MIN_ZOOM;
+			}
+		}
+
+		new_distance = llmax(new_distance, min_zoom);
+
+		// Don't zoom too far back
+		const F32 DIST_FUDGE = 16.f; // meters
+		F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
+								 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
+
+		if (new_distance > max_distance)
+		{
+			// Unless camera is unlocked
+			if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
+			{
+				return;
+			}
+		}
+
+		if( CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode() )
+		{
+			new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
+		}
+
+		// Compute new camera offset
+		mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
+		cameraZoomIn(1.f);
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+// cameraPanIn()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraPanIn(F32 meters)
+{
+	LLVector3d at_axis;
+	at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis());
+
+	mFocusTargetGlobal += meters * at_axis;
+	mFocusGlobal = mFocusTargetGlobal;
+	// don't enforce zoom constraints as this is the only way for users to get past them easily
+	updateFocusOffset();
+	// NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
+	mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+}
+
+//-----------------------------------------------------------------------------
+// cameraPanLeft()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraPanLeft(F32 meters)
+{
+	LLVector3d left_axis;
+	left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
+
+	mFocusTargetGlobal += meters * left_axis;
+	mFocusGlobal = mFocusTargetGlobal;
+
+	// disable smoothing for camera pan, which causes some residents unhappiness
+	mCameraSmoothingStop = TRUE;
+	
+	cameraZoomIn(1.f);
+	updateFocusOffset();
+	// NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx
+	mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+}
+
+//-----------------------------------------------------------------------------
+// cameraPanUp()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraPanUp(F32 meters)
+{
+	LLVector3d up_axis;
+	up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis());
+
+	mFocusTargetGlobal += meters * up_axis;
+	mFocusGlobal = mFocusTargetGlobal;
+
+	// disable smoothing for camera pan, which causes some residents unhappiness
+	mCameraSmoothingStop = TRUE;
+
+	cameraZoomIn(1.f);
+	updateFocusOffset();
+	// NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
+	mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
+}
+
+//-----------------------------------------------------------------------------
+// updateLookAt()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
+{
+	static LLVector3 last_at_axis;
+
+
+	if (gAgentHACK.mAvatarObject.isNull())
+	{
+		return;
+	}
+
+	LLQuaternion av_inv_rot = ~gAgentHACK.mAvatarObject->mRoot.getWorldRotation();
+	LLVector3 root_at = LLVector3::x_axis * gAgentHACK.mAvatarObject->mRoot.getWorldRotation();
+
+	if 	((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
+		(root_at * last_at_axis > 0.95f ))
+	{
+		LLVector3 vel = gAgentHACK.mAvatarObject->getVelocity();
+		if (vel.magVecSquared() > 4.f)
+		{
+			setLookAt(LOOKAT_TARGET_IDLE, gAgentHACK.mAvatarObject, vel * av_inv_rot);
+		}
+		else
+		{
+			// *FIX: rotate mframeagent by sit object's rotation?
+			LLQuaternion look_rotation = gAgentHACK.mAvatarObject->isSitting() ? gAgentHACK.mAvatarObject->getRenderRotation() : gAgentHACK.mFrameAgent.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, gAgentHACK.mAvatarObject, look_offset);
+		}
+		last_at_axis = root_at;
+		return;
+	}
+
+	last_at_axis = root_at;
+	
+	if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
+	{
+		setLookAt(LOOKAT_TARGET_NONE, gAgentHACK.mAvatarObject, LLVector3(-2.f, 0.f, 0.f));	
+	}
+	else
+	{
+		// Move head based on cursor position
+		ELookAtType lookAtType = LOOKAT_TARGET_NONE;
+		LLVector3 headLookAxis;
+		LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
+
+		if (cameraMouselook())
+		{
+			lookAtType = LOOKAT_TARGET_MOUSELOOK;
+		}
+		else if (cameraThirdPerson())
+		{
+			// range from -.5 to .5
+			F32 x_from_center = 
+				((F32) mouse_x / (F32) gViewerWindow->getWindowWidthScaled() ) - 0.5f;
+			F32 y_from_center = 
+				((F32) mouse_y / (F32) gViewerWindow->getWindowHeightScaled() ) - 0.5f;
+
+			frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD);
+			frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD);
+			lookAtType = LOOKAT_TARGET_FREELOOK;
+		}
+
+		headLookAxis = frameCamera.getAtAxis();
+		// RN: we use world-space offset for mouselook and freelook
+		//headLookAxis = headLookAxis * av_inv_rot;
+		setLookAt(lookAtType, gAgentHACK.mAvatarObject, headLookAxis);
+	}
+}
+
+//-----------------------------------------------------------------------------
+// updateCamera()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::updateCamera()
+{
+	static LLFastTimer::DeclareTimer ftm("Camera");
+	LLFastTimer t(ftm);
+
+	//Ventrella - changed camera_skyward to the new global "mCameraUpVector"
+	mCameraUpVector = LLVector3::z_axis;
+	//LLVector3	camera_skyward(0.f, 0.f, 1.f);
+	//end Ventrella
+
+	U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
+
+	validateFocusObject();
+
+	if (gAgentHACK.mAvatarObject.notNull() && 
+		gAgentHACK.mAvatarObject->isSitting() &&
+		camera_mode == CAMERA_MODE_MOUSELOOK)
+	{
+		//Ventrella
+		//changed camera_skyward to the new global "mCameraUpVector"
+		mCameraUpVector = mCameraUpVector * gAgentHACK.mAvatarObject->getRenderRotation();
+		//end Ventrella
+	}
+
+	if (cameraThirdPerson() && mFocusOnAvatar && LLFollowCamMgr::getActiveFollowCamParams())
+	{
+		changeCameraToFollow();
+	}
+
+	//Ventrella
+	//NOTE - this needs to be integrated into a general upVector system here within llAgent. 
+	if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
+	{
+		mCameraUpVector = mFollowCam.getUpVector();
+	}
+	//end Ventrella
+
+	if (mSitCameraEnabled)
+	{
+		if (mSitCameraReferenceObject->isDead())
+		{
+			setSitCamera(LLUUID::null);
+		}
+	}
+
+	// Update UI with our camera inputs
+	LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
+	if (camera_floater)
+	{
+		camera_floater->mRotate->setToggleState(
+		mOrbitRightKey > 0.f,	// left
+		mOrbitUpKey > 0.f,		// top
+		mOrbitLeftKey > 0.f,	// right
+		mOrbitDownKey > 0.f);	// bottom
+
+		camera_floater->mTrack->setToggleState(
+		mPanLeftKey > 0.f,		// left
+		mPanUpKey > 0.f,		// top
+		mPanRightKey > 0.f,		// right
+		mPanDownKey > 0.f);		// bottom
+	}
+
+	// Handle camera movement based on keyboard.
+	const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD;			// radians per second
+	const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD;		// radians per second
+	const F32 PAN_RATE = 5.f;								// meters per second
+
+	if( mOrbitUpKey || mOrbitDownKey )
+	{
+		F32 input_rate = mOrbitUpKey - mOrbitDownKey;
+		cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped );
+	}
+
+	if( mOrbitLeftKey || mOrbitRightKey)
+	{
+		F32 input_rate = mOrbitLeftKey - mOrbitRightKey;
+		cameraOrbitAround( input_rate * ORBIT_AROUND_RATE / gFPSClamped );
+	}
+
+	if( mOrbitInKey || mOrbitOutKey )
+	{
+		F32 input_rate = mOrbitInKey - mOrbitOutKey;
+		
+		LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - calcFocusPositionTargetGlobal();
+		F32 distance_to_focus = (F32)to_focus.magVec();
+		// Move at distance (in meters) meters per second
+		cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped );
+	}
+
+	if( mPanInKey || mPanOutKey )
+	{
+		F32 input_rate = mPanInKey - mPanOutKey;
+		cameraPanIn( input_rate * PAN_RATE / gFPSClamped );
+	}
+
+	if( mPanRightKey || mPanLeftKey )
+	{
+		F32 input_rate = mPanRightKey - mPanLeftKey;
+		cameraPanLeft( input_rate * -PAN_RATE / gFPSClamped );
+	}
+
+	if( mPanUpKey || mPanDownKey )
+	{
+		F32 input_rate = mPanUpKey - mPanDownKey;
+		cameraPanUp( input_rate * PAN_RATE / gFPSClamped );
+	}
+
+	// Clear camera keyboard keys.
+	mOrbitLeftKey		= 0.f;
+	mOrbitRightKey		= 0.f;
+	mOrbitUpKey			= 0.f;
+	mOrbitDownKey		= 0.f;
+	mOrbitInKey			= 0.f;
+	mOrbitOutKey		= 0.f;
+
+	mPanRightKey		= 0.f;
+	mPanLeftKey			= 0.f;
+	mPanUpKey			= 0.f;
+	mPanDownKey			= 0.f;
+	mPanInKey			= 0.f;
+	mPanOutKey			= 0.f;
+
+	// lerp camera focus offset
+	mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE));
+
+	//Ventrella
+	if ( mCameraMode == CAMERA_MODE_FOLLOW )
+	{
+		if ( gAgentHACK.mAvatarObject.notNull() )
+		{
+			//--------------------------------------------------------------------------------
+			// this is where the avatar's position and rotation are given to followCam, and 
+			// where it is updated. All three of its attributes are updated: (1) position, 
+			// (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent.
+			//--------------------------------------------------------------------------------
+			// *TODO: use combined rotation of frameagent and sit object
+			LLQuaternion avatarRotationForFollowCam = gAgentHACK.mAvatarObject->isSitting() ? gAgentHACK.mAvatarObject->getRenderRotation() : gAgentHACK.mFrameAgent.getQuaternion();
+
+			LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams();
+			if (current_cam)
+			{
+				mFollowCam.copyParams(*current_cam);
+				mFollowCam.setSubjectPositionAndRotation( gAgentHACK.mAvatarObject->getRenderPosition(), avatarRotationForFollowCam );
+				mFollowCam.update();
+				LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
+			}
+			else
+			{
+				changeCameraToThirdPerson(TRUE);
+			}
+		}
+	}
+	// end Ventrella
+
+	BOOL hit_limit;
+	LLVector3d camera_pos_global;
+	LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit);
+	mCameraVirtualPositionAgent = gAgentHACK.getPosAgentFromGlobal(camera_target_global);
+	LLVector3d focus_target_global = calcFocusPositionTargetGlobal();
+
+	// perform field of view correction
+	mCameraFOVZoomFactor = calcCameraFOVZoomFactor();
+	camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor);
+
+	gAgentHACK.mShowAvatar = TRUE; // can see avatar by default
+
+	// Adjust position for animation
+	if (mCameraAnimating)
+	{
+		F32 time = mAnimationTimer.getElapsedTimeF32();
+
+		// yet another instance of critically damped motion, hooray!
+		// F32 fraction_of_animation = 1.f - pow(2.f, -time / CAMERA_ZOOM_HALF_LIFE);
+
+		// linear interpolation
+		F32 fraction_of_animation = time / mAnimationDuration;
+
+		BOOL isfirstPerson = mCameraMode == CAMERA_MODE_MOUSELOOK;
+		BOOL wasfirstPerson = mLastCameraMode == CAMERA_MODE_MOUSELOOK;
+		F32 fraction_animation_to_skip;
+
+		if (mAnimationCameraStartGlobal == camera_target_global)
+		{
+			fraction_animation_to_skip = 0.f;
+		}
+		else
+		{
+			LLVector3d cam_delta = mAnimationCameraStartGlobal - camera_target_global;
+			fraction_animation_to_skip = HEAD_BUFFER_SIZE / (F32)cam_delta.magVec();
+		}
+		F32 animation_start_fraction = (wasfirstPerson) ? fraction_animation_to_skip : 0.f;
+		F32 animation_finish_fraction =  (isfirstPerson) ? (1.f - fraction_animation_to_skip) : 1.f;
+	
+		if (fraction_of_animation < animation_finish_fraction)
+		{
+			if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction )
+			{
+				gAgentHACK.mShowAvatar = FALSE;
+			}
+
+			// ...adjust position for animation
+			F32 smooth_fraction_of_animation = llsmoothstep(0.0f, 1.0f, fraction_of_animation);
+			camera_pos_global = lerp(mAnimationCameraStartGlobal, camera_target_global, smooth_fraction_of_animation);
+			mFocusGlobal = lerp(mAnimationFocusStartGlobal, focus_target_global, smooth_fraction_of_animation);
+		}
+		else
+		{
+			// ...animation complete
+			mCameraAnimating = FALSE;
+
+			camera_pos_global = camera_target_global;
+			mFocusGlobal = focus_target_global;
+
+			gAgentHACK.endAnimationUpdateUI();
+			gAgentHACK.mShowAvatar = TRUE;
+		}
+
+		if (gAgentHACK.getAvatarObject() && mCameraMode != CAMERA_MODE_MOUSELOOK)
+		{
+			gAgentHACK.getAvatarObject()->updateAttachmentVisibility(mCameraMode);
+		}
+	}
+	else 
+	{
+		camera_pos_global = camera_target_global;
+		mFocusGlobal = focus_target_global;
+		gAgentHACK.mShowAvatar = TRUE;
+	}
+
+	// smoothing
+	if (TRUE)
+	{
+		LLVector3d agent_pos = gAgentHACK.getPositionGlobal();
+		LLVector3d camera_pos_agent = camera_pos_global - agent_pos;
+		// Sitting on what you're manipulating can cause camera jitter with smoothing. 
+		// This turns off smoothing while editing. -MG
+		mCameraSmoothingStop |= (BOOL)LLToolMgr::getInstance()->inBuildMode();
+		
+		if (cameraThirdPerson() && !mCameraSmoothingStop)
+		{
+			const F32 SMOOTHING_HALF_LIFE = 0.02f;
+			
+			F32 smoothing = LLCriticalDamp::getInterpolant(gSavedSettings.getF32("CameraPositionSmoothing") * SMOOTHING_HALF_LIFE, FALSE);
+					
+			if (!mFocusObject)  // we differentiate on avatar mode 
+			{
+				// for avatar-relative focus, we smooth in avatar space -
+				// the avatar moves too jerkily w/r/t global space to smooth there.
+
+				LLVector3d delta = camera_pos_agent - mCameraSmoothingLastPositionAgent;
+				if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE)  // only smooth over short distances please
+				{
+					camera_pos_agent = lerp(mCameraSmoothingLastPositionAgent, camera_pos_agent, smoothing);
+					camera_pos_global = camera_pos_agent + agent_pos;
+				}
+			}
+			else
+			{
+				LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal;
+				if (delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) // only smooth over short distances please
+				{
+					camera_pos_global = lerp(mCameraSmoothingLastPositionGlobal, camera_pos_global, smoothing);
+				}
+			}
+		}
+								 
+		mCameraSmoothingLastPositionGlobal = camera_pos_global;
+		mCameraSmoothingLastPositionAgent = camera_pos_agent;
+		mCameraSmoothingStop = FALSE;
+	}
+
+	
+	mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE));
+
+//	llinfos << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << llendl;
+
+	F32 ui_offset = 0.f;
+	if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) 
+	{
+		ui_offset = calcCustomizeAvatarUIOffset( camera_pos_global );
+	}
+
+
+	LLVector3 focus_agent = gAgentHACK.getPosAgentFromGlobal(mFocusGlobal);
+	
+	mCameraPositionAgent = gAgentHACK.getPosAgentFromGlobal(camera_pos_global);
+
+	// Move the camera
+
+	//Ventrella
+	LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
+	//LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent);
+	//end Ventrella
+
+	//RN: translate UI offset after camera is oriented properly
+	LLViewerCamera::getInstance()->translate(LLViewerCamera::getInstance()->getLeftAxis() * ui_offset);
+	
+	// Change FOV
+	LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
+
+	// follow camera when in customize mode
+	if (cameraCustomizeAvatar())	
+	{
+		setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
+	}
+
+	// update the travel distance stat
+	// this isn't directly related to the camera
+	// but this seemed like the best place to do this
+	LLVector3d global_pos = gAgentHACK.getPositionGlobal(); 
+	if (! gAgentHACK.mLastPositionGlobal.isExactlyZero())
+	{
+		LLVector3d delta = global_pos - gAgentHACK.mLastPositionGlobal;
+		gAgentHACK.mDistanceTraveled += delta.magVec();
+	}
+	gAgentHACK.mLastPositionGlobal = global_pos;
+	
+	if (LLVOAvatar::sVisibleInFirstPerson && gAgentHACK.mAvatarObject.notNull() && !gAgentHACK.mAvatarObject->isSitting() && cameraMouselook())
+	{
+		LLVector3 head_pos = gAgentHACK.mAvatarObject->mHeadp->getWorldPosition() + 
+			LLVector3(0.08f, 0.f, 0.05f) * gAgentHACK.mAvatarObject->mHeadp->getWorldRotation() + 
+			LLVector3(0.1f, 0.f, 0.f) * gAgentHACK.mAvatarObject->mPelvisp->getWorldRotation();
+		LLVector3 diff = mCameraPositionAgent - head_pos;
+		diff = diff * ~gAgentHACK.mAvatarObject->mRoot.getWorldRotation();
+
+		LLJoint* torso_joint = gAgentHACK.mAvatarObject->mTorsop;
+		LLJoint* chest_joint = gAgentHACK.mAvatarObject->mChestp;
+		LLVector3 torso_scale = torso_joint->getScale();
+		LLVector3 chest_scale = chest_joint->getScale();
+
+		// shorten avatar skeleton to avoid foot interpenetration
+		if (!gAgentHACK.mAvatarObject->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 = gAgentHACK.mAvatarObject->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;
+		}
+
+		gAgentHACK.mAvatarObject->mPelvisp->setPosition(gAgentHACK.mAvatarObject->mPelvisp->getPosition() + diff);
+
+		gAgentHACK.mAvatarObject->mRoot.updateWorldMatrixChildren();
+
+		for (LLVOAvatar::attachment_map_t::iterator iter = gAgentHACK.mAvatarObject->mAttachmentPoints.begin(); 
+			 iter != gAgentHACK.mAvatarObject->mAttachmentPoints.end(); )
+		{
+			LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+			LLViewerJointAttachment* attachment = curiter->second;
+			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+				 attachment_iter != attachment->mAttachedObjects.end();
+				 ++attachment_iter)
+			{
+				LLViewerObject *attached_object = (*attachment_iter);
+				if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
+				{
+					// clear any existing "early" movements of attachment
+					attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE);
+					gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
+					attached_object->updateText();
+				}
+			}
+		}
+
+		torso_joint->setScale(torso_scale);
+		chest_joint->setScale(chest_scale);
+	}
+}
+
+void LLAgentCamera::updateFocusOffset()
+{
+	validateFocusObject();
+	if (mFocusObject.notNull())
+	{
+		LLVector3d obj_pos = gAgentHACK.getPosGlobalFromAgent(mFocusObject->getRenderPosition());
+		mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos);
+	}
+}
+
+void LLAgentCamera::validateFocusObject()
+{
+	if (mFocusObject.notNull() && 
+		(mFocusObject->isDead()))
+	{
+		mFocusObjectOffset.clearVec();
+		clearFocusObject();
+		mCameraFOVZoomFactor = 0.f;
+	}
+}
+
+//-----------------------------------------------------------------------------
+// calcCustomizeAvatarUIOffset()
+//-----------------------------------------------------------------------------
+F32 LLAgentCamera::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global )
+{
+	F32 ui_offset = 0.f;
+
+	if( gFloaterCustomize )
+	{
+		const LLRect& rect = gFloaterCustomize->getRect();
+
+		// Move the camera so that the avatar isn't covered up by this floater.
+		F32 fraction_of_fov = 0.5f - (0.5f * (1.f - llmin(1.f, ((F32)rect.getWidth() / (F32)gViewerWindow->getWindowWidthScaled()))));
+		F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();  // radians
+		F32 offset = tan(apparent_angle);
+
+		if( rect.mLeft < (gViewerWindow->getWindowWidthScaled() - rect.mRight) )
+		{
+			// Move the avatar to the right (camera to the left)
+			ui_offset = offset;
+		}
+		else
+		{
+			// Move the avatar to the left (camera to the right)
+			ui_offset = -offset;
+		}
+	}
+	F32 range = (F32)dist_vec(camera_pos_global, getFocusGlobal());
+	mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f));
+	return mUIOffset * range;
+}
+
+//-----------------------------------------------------------------------------
+// calcFocusPositionTargetGlobal()
+//-----------------------------------------------------------------------------
+LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
+{
+	if (mFocusObject.notNull() && mFocusObject->isDead())
+	{
+		clearFocusObject();
+	}
+
+	// Ventrella
+	if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
+	{
+		mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
+		return mFocusTargetGlobal;
+	}// End Ventrella 
+	else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+	{
+		LLVector3d at_axis(1.0, 0.0, 0.0);
+		LLQuaternion agent_rot = gAgentHACK.mFrameAgent.getQuaternion();
+		if (gAgentHACK.mAvatarObject.notNull() && gAgentHACK.mAvatarObject->getParent())
+		{
+			LLViewerObject* root_object = (LLViewerObject*)gAgentHACK.mAvatarObject->getRoot();
+			if (!root_object->flagCameraDecoupled())
+			{
+				agent_rot *= ((LLViewerObject*)(gAgentHACK.mAvatarObject->getParent()))->getRenderRotation();
+			}
+		}
+		at_axis = at_axis * agent_rot;
+		mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis;
+		return mFocusTargetGlobal;
+	}
+	else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
+	{
+		return mFocusTargetGlobal;
+	}
+	else if (!mFocusOnAvatar)
+	{
+		if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull())
+		{
+			LLDrawable* drawablep = mFocusObject->mDrawable;
+			
+			if (mTrackFocusObject &&
+				drawablep && 
+				drawablep->isActive())
+			{
+				if (!mFocusObject->isAvatar())
+				{
+					if (mFocusObject->isSelected())
+					{
+						gPipeline.updateMoveNormalAsync(drawablep);
+					}
+					else
+					{
+						if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
+						{
+							gPipeline.updateMoveNormalAsync(drawablep);
+						}
+						else
+						{
+							gPipeline.updateMoveDampedAsync(drawablep);
+						}
+					}
+				}
+			}
+			// if not tracking object, update offset based on new object position
+			else
+			{
+				updateFocusOffset();
+			}
+			LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset;
+			mFocusTargetGlobal.setVec(gAgentHACK.getPosGlobalFromAgent(focus_agent));
+		}
+		return mFocusTargetGlobal;
+	}
+	else if (mSitCameraEnabled && gAgentHACK.mAvatarObject.notNull() && gAgentHACK.mAvatarObject->isSitting() && mSitCameraReferenceObject.notNull())
+	{
+		// sit camera
+		LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
+		LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
+
+		LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot);
+		return gAgentHACK.getPosGlobalFromAgent(target_pos);
+	}
+	else
+	{
+		return gAgentHACK.getPositionGlobal() + calcThirdPersonFocusOffset();
+	}
+}
+
+LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
+{
+	// ...offset from avatar
+	LLVector3d focus_offset;
+
+	LLQuaternion agent_rot = gAgentHACK.mFrameAgent.getQuaternion();
+	if (!gAgentHACK.mAvatarObject.isNull() && gAgentHACK.mAvatarObject->getParent())
+	{
+		agent_rot *= ((LLViewerObject*)(gAgentHACK.mAvatarObject->getParent()))->getRenderRotation();
+	}
+
+	focus_offset = mFocusOffsetInitial[mCameraPreset] * agent_rot;
+	return focus_offset;
+}
+
+void LLAgentCamera::setupSitCamera()
+{
+	// agent frame entering this function is in world coordinates
+	if (gAgentHACK.mAvatarObject.notNull() && gAgentHACK.mAvatarObject->getParent())
+	{
+		LLQuaternion parent_rot = ((LLViewerObject*)gAgentHACK.mAvatarObject->getParent())->getRenderRotation();
+		// slam agent coordinate frame to proper parent local version
+		LLVector3 at_axis = gAgentHACK.mFrameAgent.getAtAxis();
+		at_axis.mV[VZ] = 0.f;
+		at_axis.normalize();
+		gAgentHACK.resetAxes(at_axis * ~parent_rot);
+	}
+}
+
+//-----------------------------------------------------------------------------
+// getCameraPositionAgent()
+//-----------------------------------------------------------------------------
+const LLVector3 &LLAgentCamera::getCameraPositionAgent() const
+{
+	return LLViewerCamera::getInstance()->getOrigin();
+}
+
+//-----------------------------------------------------------------------------
+// getCameraPositionGlobal()
+//-----------------------------------------------------------------------------
+LLVector3d LLAgentCamera::getCameraPositionGlobal() const
+{
+	return gAgentHACK.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
+}
+
+//-----------------------------------------------------------------------------
+// calcCameraFOVZoomFactor()
+//-----------------------------------------------------------------------------
+F32	LLAgentCamera::calcCameraFOVZoomFactor()
+{
+	LLVector3 camera_offset_dir;
+	camera_offset_dir.setVec(mCameraFocusOffset);
+
+	if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+	{
+		return 0.f;
+	}
+	else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
+	{
+		// don't FOV zoom on mostly transparent objects
+		LLVector3 focus_offset = mFocusObjectOffset;
+		F32 obj_min_dist = 0.f;
+		calcCameraMinDistance(obj_min_dist);
+		F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
+
+		mFocusObjectDist = obj_min_dist - current_distance;
+
+		F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f);
+		return new_fov_zoom;
+	}
+	else // focusing on land or avatar
+	{
+		// keep old field of view until user changes focus explicitly
+		return mCameraFOVZoomFactor;
+		//return 0.f;
+	}
+}
+
+//-----------------------------------------------------------------------------
+// calcCameraPositionTargetGlobal()
+//-----------------------------------------------------------------------------
+LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
+{
+	// Compute base camera position and look-at points.
+	F32			camera_land_height;
+	LLVector3d	frame_center_global = gAgentHACK.mAvatarObject.isNull() ? gAgentHACK.getPositionGlobal() 
+															 : gAgentHACK.getPosGlobalFromAgent(gAgentHACK.mAvatarObject->mRoot.getWorldPosition());
+		
+	BOOL		isConstrained = FALSE;
+	LLVector3d	head_offset;
+	head_offset.setVec(mThirdPersonHeadOffset);
+
+	LLVector3d camera_position_global;
+
+	// Ventrella 
+	if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
+	{
+		camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
+	}// End Ventrella
+	else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+	{
+		if (gAgentHACK.mAvatarObject.isNull() || gAgentHACK.mAvatarObject->mDrawable.isNull())
+		{
+			llwarns << "Null avatar drawable!" << llendl;
+			return LLVector3d::zero;
+		}
+		head_offset.clearVec();
+		if (gAgentHACK.mAvatarObject->isSitting() && gAgentHACK.mAvatarObject->getParent())
+		{
+			gAgentHACK.mAvatarObject->updateHeadOffset();
+			head_offset.mdV[VX] = gAgentHACK.mAvatarObject->mHeadOffset.mV[VX];
+			head_offset.mdV[VY] = gAgentHACK.mAvatarObject->mHeadOffset.mV[VY];
+			head_offset.mdV[VZ] = gAgentHACK.mAvatarObject->mHeadOffset.mV[VZ] + 0.1f;
+			const LLMatrix4& mat = ((LLViewerObject*) gAgentHACK.mAvatarObject->getParent())->getRenderMatrix();
+			camera_position_global = gAgentHACK.getPosGlobalFromAgent
+								((gAgentHACK.mAvatarObject->getPosition()+
+								 LLVector3(head_offset)*gAgentHACK.mAvatarObject->getRotation()) * mat);
+		}
+		else
+		{
+			head_offset.mdV[VZ] = gAgentHACK.mAvatarObject->mHeadOffset.mV[VZ];
+			if (gAgentHACK.mAvatarObject->isSitting())
+			{
+				head_offset.mdV[VZ] += 0.1;
+			}
+			camera_position_global = gAgentHACK.getPosGlobalFromAgent(gAgentHACK.mAvatarObject->getRenderPosition());//frame_center_global;
+			head_offset = head_offset * gAgentHACK.mAvatarObject->getRenderRotation();
+			camera_position_global = camera_position_global + head_offset;
+		}
+	}
+	else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar)
+	{
+		LLVector3 local_camera_offset;
+		F32 camera_distance = 0.f;
+
+		if (mSitCameraEnabled 
+			&& gAgentHACK.mAvatarObject.notNull() 
+			&& gAgentHACK.mAvatarObject->isSitting() 
+			&& mSitCameraReferenceObject.notNull())
+		{
+			// sit camera
+			LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
+			LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
+
+			LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot);
+
+			camera_position_global = gAgentHACK.getPosGlobalFromAgent(target_pos);
+		}
+		else
+		{
+			local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale");
+			
+			// are we sitting down?
+			if (gAgentHACK.mAvatarObject.notNull() && gAgentHACK.mAvatarObject->getParent())
+			{
+				LLQuaternion parent_rot = ((LLViewerObject*)gAgentHACK.mAvatarObject->getParent())->getRenderRotation();
+				// slam agent coordinate frame to proper parent local version
+				LLVector3 at_axis = gAgentHACK.mFrameAgent.getAtAxis() * parent_rot;
+				at_axis.mV[VZ] = 0.f;
+				at_axis.normalize();
+				gAgentHACK.resetAxes(at_axis * ~parent_rot);
+
+				local_camera_offset = local_camera_offset * gAgentHACK.mFrameAgent.getQuaternion() * parent_rot;
+			}
+			else
+			{
+				local_camera_offset = gAgentHACK.mFrameAgent.rotateToAbsolute( local_camera_offset );
+			}
+
+			if (!mCameraCollidePlane.isExactlyZero() && (gAgentHACK.mAvatarObject.isNull() || !gAgentHACK.mAvatarObject->isSitting()))
+			{
+				LLVector3 plane_normal;
+				plane_normal.setVec(mCameraCollidePlane.mV);
+
+				F32 offset_dot_norm = local_camera_offset * plane_normal;
+				if (llabs(offset_dot_norm) < 0.001f)
+				{
+					offset_dot_norm = 0.001f;
+				}
+				
+				camera_distance = local_camera_offset.normalize();
+
+				F32 pos_dot_norm = gAgentHACK.getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal;
+				
+				// if agent is outside the colliding half-plane
+				if (pos_dot_norm > mCameraCollidePlane.mV[VW])
+				{
+					// check to see if camera is on the opposite side (inside) the half-plane
+					if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW])
+					{
+						// diminish offset by factor to push it back outside the half-plane
+						camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm;
+					}
+				}
+				else
+				{
+					if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW])
+					{
+						camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm;
+					}
+				}
+			}
+			else
+			{
+				camera_distance = local_camera_offset.normalize();
+			}
+
+			mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE);
+
+			if (mTargetCameraDistance != mCurrentCameraDistance)
+			{
+				F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
+
+				mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);
+			}
+
+			// Make the camera distance current
+			local_camera_offset *= mCurrentCameraDistance;
+
+			// set the global camera position
+			LLVector3d camera_offset;
+			
+			LLVector3 av_pos = gAgentHACK.mAvatarObject.isNull() ? LLVector3::zero : gAgentHACK.mAvatarObject->getRenderPosition();
+			camera_offset.setVec( local_camera_offset );
+			camera_position_global = frame_center_global + head_offset + camera_offset;
+
+			if (gAgentHACK.mAvatarObject.notNull())
+			{
+				LLVector3d camera_lag_d;
+				F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
+				LLVector3 target_lag;
+				LLVector3 vel = gAgentHACK.getVelocity();
+
+				// lag by appropriate amount for flying
+				F32 time_in_air = gAgentHACK.mAvatarObject->mTimeInAir.getElapsedTimeF32();
+				if(!mCameraAnimating && gAgentHACK.mAvatarObject->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
+				{
+					LLVector3 frame_at_axis = gAgentHACK.mFrameAgent.getAtAxis();
+					frame_at_axis -= projected_vec(frame_at_axis, gAgentHACK.getReferenceUpVector());
+					frame_at_axis.normalize();
+
+					//transition smoothly in air mode, to avoid camera pop
+					F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME;
+					u = llclamp(u, 0.f, 1.f);
+
+					lag_interp *= u;
+
+					if (gViewerWindow->getLeftMouseDown() && gViewerWindow->getLastPick().mObjectID == gAgentHACK.mAvatarObject->getID())
+					{
+						// disable camera lag when using mouse-directed steering
+						target_lag.clearVec();
+					}
+					else
+					{
+						target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
+					}
+
+					mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
+
+					F32 lag_dist = mCameraLag.magVec();
+					if (lag_dist > MAX_CAMERA_LAG)
+					{
+						mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist;
+					}
+
+					// clamp camera lag so that avatar is always in front
+					F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis;
+					if (dot < -(MIN_CAMERA_LAG * u))
+					{
+						mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis;
+					}
+				}
+				else
+				{
+					mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f));
+				}
+
+				camera_lag_d.setVec(mCameraLag);
+				camera_position_global = camera_position_global - camera_lag_d;
+			}
+		}
+	}
+	else
+	{
+		LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal();
+		// camera gets pushed out later wrt mCameraFOVZoomFactor...this is "raw" value
+		camera_position_global = focusPosGlobal + mCameraFocusOffset;
+	}
+
+	if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
+	{
+		LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(
+			camera_position_global);
+		bool constrain = true;
+		if(regionp && regionp->canManageEstate())
+		{
+			constrain = false;
+		}
+		if(constrain)
+		{
+			F32 max_dist = ( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) ?
+				APPEARANCE_MAX_ZOOM : mDrawDistance;
+
+			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;
+				isConstrained = TRUE;
+			}
+		}
+
+// JC - Could constrain camera based on parcel stuff here.
+//			LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global);
+//			
+//			if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global)))
+//			{
+//				camera_position_global = last_position_global;
+//
+//				isConstrained = TRUE;
+//			}
+	}
+
+	// Don't let camera go underground
+	F32 camera_min_off_ground = getCameraMinOffGround();
+
+	camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global);
+
+	if (camera_position_global.mdV[VZ] < camera_land_height + camera_min_off_ground)
+	{
+		camera_position_global.mdV[VZ] = camera_land_height + camera_min_off_ground;
+		isConstrained = TRUE;
+	}
+
+
+	if (hit_limit)
+	{
+		*hit_limit = isConstrained;
+	}
+
+	return camera_position_global;
+}
+
+
+LLVector3 LLAgentCamera::getCameraOffsetInitial()
+{
+	return mCameraOffsetInitial[mCameraPreset];
+}
+
+
+//-----------------------------------------------------------------------------
+// handleScrollWheel()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::handleScrollWheel(S32 clicks)
+{
+	if ( mCameraMode == CAMERA_MODE_FOLLOW && getFocusOnAvatar())
+	{
+		if ( ! mFollowCam.getPositionLocked() ) // not if the followCam position is locked in place
+		{
+			mFollowCam.zoom( clicks ); 
+			if ( mFollowCam.isZoomedToMinimumDistance() )
+			{
+				changeCameraToMouselook(FALSE);
+			}
+		}
+	}
+	else
+	{
+		LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+		const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2);
+
+		// Block if camera is animating
+		if (mCameraAnimating)
+		{
+			return;
+		}
+
+		if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
+		{
+			F32 zoom_factor = (F32)pow(0.8, -clicks);
+			cameraZoomIn(zoom_factor);
+		}
+		else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
+		{
+			F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
+			
+			F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
+			current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
+			
+			cameraOrbitIn(current_zoom_fraction * camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
+		}
+		else
+		{
+			F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec();
+			cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks)));
+		}
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+// getCameraMinOffGround()
+//-----------------------------------------------------------------------------
+F32 LLAgentCamera::getCameraMinOffGround()
+{
+	if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+	{
+		return 0.f;
+	}
+	else
+	{
+		if (gSavedSettings.getBOOL("DisableCameraConstraints"))
+		{
+			return -1000.f;
+		}
+		else
+		{
+			return 0.5f;
+		}
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+// resetCamera()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::resetCamera()
+{
+	// Remove any pitch from the avatar
+	LLVector3 at = gAgentHACK.mFrameAgent.getAtAxis();
+	at.mV[VZ] = 0.f;
+	at.normalize();
+	gAgent.resetAxes(at);
+	// have to explicitly clear field of view zoom now
+	mCameraFOVZoomFactor = 0.f;
+
+	updateCamera();
+}
+
+//-----------------------------------------------------------------------------
+// changeCameraToMouselook()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::changeCameraToMouselook(BOOL animate)
+{
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
+	// visibility changes at end of animation
+	gViewerWindow->getWindow()->resetBusyCount();
+
+	// unpause avatar animation
+	gAgentHACK.mPauseRequest = NULL;
+
+	LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
+
+	if (gAgentHACK.mAvatarObject.notNull())
+	{
+		gAgentHACK.mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
+		gAgentHACK.mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
+	}
+
+	//gViewerWindow->stopGrab();
+	LLSelectMgr::getInstance()->deselectAll();
+	gViewerWindow->hideCursor();
+	gViewerWindow->moveCursorToCenter();
+
+	if( mCameraMode != CAMERA_MODE_MOUSELOOK )
+	{
+		gFocusMgr.setKeyboardFocus( NULL );
+		
+		mLastCameraMode = mCameraMode;
+		mCameraMode = CAMERA_MODE_MOUSELOOK;
+		U32 old_flags = gAgentHACK.mControlFlags;
+		gAgentHACK.setControlFlags(AGENT_CONTROL_MOUSELOOK);
+		if (old_flags != gAgentHACK.mControlFlags)
+		{
+			gAgentHACK.mbFlagsDirty = TRUE;
+		}
+
+		if (animate)
+		{
+			startCameraAnimation();
+		}
+		else
+		{
+			mCameraAnimating = FALSE;
+			gAgentHACK.endAnimationUpdateUI();
+		}
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+// changeCameraToDefault()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::changeCameraToDefault()
+{
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
+	if (LLFollowCamMgr::getActiveFollowCamParams())
+	{
+		changeCameraToFollow();
+	}
+	else
+	{
+		changeCameraToThirdPerson();
+	}
+}
+
+
+// Ventrella
+//-----------------------------------------------------------------------------
+// changeCameraToFollow()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::changeCameraToFollow(BOOL animate)
+{
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
+	if( mCameraMode != CAMERA_MODE_FOLLOW )
+	{
+		if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+		{
+			animate = FALSE;
+		}
+		startCameraAnimation();
+
+		mLastCameraMode = mCameraMode;
+		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 );
+		
+		if (gBasicToolset)
+		{
+			LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+		}
+
+		if (gAgentHACK.mAvatarObject.notNull())
+		{
+			gAgentHACK.mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
+			gAgentHACK.mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
+			gAgentHACK.mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
+		}
+
+		// unpause avatar animation
+		gAgentHACK.mPauseRequest = NULL;
+
+		U32 old_flags = gAgentHACK.mControlFlags;
+		gAgentHACK.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
+		if (old_flags != gAgentHACK.mControlFlags)
+		{
+			gAgentHACK.mbFlagsDirty = TRUE;
+		}
+
+		if (animate)
+		{
+			startCameraAnimation();
+		}
+		else
+		{
+			mCameraAnimating = FALSE;
+			gAgentHACK.endAnimationUpdateUI();
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------
+// changeCameraToThirdPerson()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
+{
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
+	gViewerWindow->getWindow()->resetBusyCount();
+
+	mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
+
+	if (gAgentHACK.mAvatarObject.notNull())
+	{
+		if (!gAgentHACK.mAvatarObject->isSitting())
+		{
+			gAgentHACK.mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
+		}
+		gAgentHACK.mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
+		gAgentHACK.mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
+	}
+
+	LLVector3 at_axis;
+
+	// unpause avatar animation
+	gAgentHACK.mPauseRequest = NULL;
+
+	if( mCameraMode != CAMERA_MODE_THIRD_PERSON )
+	{
+		if (gBasicToolset)
+		{
+			LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
+		}
+
+		mCameraLag.clearVec();
+		if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+		{
+			mCurrentCameraDistance = MIN_CAMERA_DISTANCE;
+			mTargetCameraDistance = MIN_CAMERA_DISTANCE;
+			animate = FALSE;
+		}
+		mLastCameraMode = mCameraMode;
+		mCameraMode = CAMERA_MODE_THIRD_PERSON;
+		U32 old_flags = gAgentHACK.mControlFlags;
+		gAgentHACK.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
+		if (old_flags != gAgentHACK.mControlFlags)
+		{
+			gAgentHACK.mbFlagsDirty = TRUE;
+		}
+
+	}
+
+	// Remove any pitch from the avatar
+	if (gAgentHACK.mAvatarObject.notNull() && gAgentHACK.mAvatarObject->getParent())
+	{
+		LLQuaternion obj_rot = ((LLViewerObject*)gAgentHACK.mAvatarObject->getParent())->getRenderRotation();
+		at_axis = LLViewerCamera::getInstance()->getAtAxis();
+		at_axis.mV[VZ] = 0.f;
+		at_axis.normalize();
+		gAgentHACK.resetAxes(at_axis * ~obj_rot);
+	}
+	else
+	{
+		at_axis = gAgentHACK.mFrameAgent.getAtAxis();
+		at_axis.mV[VZ] = 0.f;
+		at_axis.normalize();
+		gAgentHACK.resetAxes(at_axis);
+	}
+
+
+	if (animate)
+	{
+		startCameraAnimation();
+	}
+	else
+	{
+		mCameraAnimating = FALSE;
+		gAgentHACK.endAnimationUpdateUI();
+	}
+}
+
+//-----------------------------------------------------------------------------
+// changeCameraToCustomizeAvatar()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_animate)
+{
+	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	{
+		return;
+	}
+
+	gAgentHACK.standUp(); // force stand up
+	gViewerWindow->getWindow()->resetBusyCount();
+
+	if (gFaceEditToolset)
+	{
+		LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
+	}
+
+	if (camera_animate)
+	{
+		startCameraAnimation();
+	}
+
+	// Remove any pitch from the avatar
+	//LLVector3 at = gAgentHACK.mFrameAgent.getAtAxis();
+	//at.mV[VZ] = 0.f;
+	//at.normalize();
+	//gAgent.resetAxes(at);
+
+	if( mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR )
+	{
+		mLastCameraMode = mCameraMode;
+		mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR;
+		U32 old_flags = gAgentHACK.mControlFlags;
+		gAgentHACK.clearControlFlags(AGENT_CONTROL_MOUSELOOK);
+		if (old_flags != gAgentHACK.mControlFlags)
+		{
+			gAgentHACK.mbFlagsDirty = TRUE;
+		}
+
+		gFocusMgr.setKeyboardFocus( NULL );
+		gFocusMgr.setMouseCapture( NULL );
+
+		LLVOAvatarSelf::onCustomizeStart();
+	}
+
+	if (gAgentHACK.mAvatarObject.notNull())
+	{
+		if(avatar_animate)
+		{
+			// Remove any pitch from the avatar
+			LLVector3 at = gAgentHACK.mFrameAgent.getAtAxis();
+			at.mV[VZ] = 0.f;
+			at.normalize();
+			gAgent.resetAxes(at);
+
+			gAgentHACK.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
+			gAgentHACK.mCustomAnim = TRUE;
+			gAgentHACK.mAvatarObject->startMotion(ANIM_AGENT_CUSTOMIZE);
+			LLMotion* turn_motion = gAgentHACK.mAvatarObject->findMotion(ANIM_AGENT_CUSTOMIZE);
+
+			if (turn_motion)
+			{
+				mAnimationDuration = turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP;
+
+			}
+			else
+			{
+				mAnimationDuration = gSavedSettings.getF32("ZoomTime");
+			}
+		}
+
+
+
+		setFocusGlobal(LLVector3d::zero);
+	}
+	else
+	{
+		mCameraAnimating = FALSE;
+		gAgentHACK.endAnimationUpdateUI();
+	}
+
+}
+
+
+void LLAgentCamera::switchCameraPreset(ECameraPreset preset)
+{
+	//zoom is supposed to be reset for the front and group views
+	mCameraZoomFraction = 1.f;
+
+	//focusing on avatar in that case means following him on movements
+	mFocusOnAvatar = TRUE;
+
+	mCameraPreset = preset;
+
+	gSavedSettings.setU32("CameraPreset", mCameraPreset);
+}
+
+
+//
+// Focus point management
+//
+
+//-----------------------------------------------------------------------------
+// startCameraAnimation()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::startCameraAnimation()
+{
+	mAnimationCameraStartGlobal = getCameraPositionGlobal();
+	mAnimationFocusStartGlobal = mFocusGlobal;
+	mAnimationTimer.reset();
+	mCameraAnimating = TRUE;
+	mAnimationDuration = gSavedSettings.getF32("ZoomTime");
+}
+
+//-----------------------------------------------------------------------------
+// stopCameraAnimation()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::stopCameraAnimation()
+{
+	mCameraAnimating = FALSE;
+}
+
+void LLAgentCamera::clearFocusObject()
+{
+	if (mFocusObject.notNull())
+	{
+		startCameraAnimation();
+
+		setFocusObject(NULL);
+		mFocusObjectOffset.clearVec();
+	}
+}
+
+void LLAgentCamera::setFocusObject(LLViewerObject* object)
+{
+	mFocusObject = object;
+}
+
+// Focus on a point, but try to keep camera position stable.
+//-----------------------------------------------------------------------------
+// setFocusGlobal()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::setFocusGlobal(const LLPickInfo& pick)
+{
+	LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID);
+
+	if (objectp)
+	{
+		// focus on object plus designated offset
+		// which may or may not be same as pick.mPosGlobal
+		setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID);
+	}
+	else
+	{
+		// focus directly on point where user clicked
+		setFocusGlobal(pick.mPosGlobal, pick.mObjectID);
+	}
+}
+
+
+void LLAgentCamera::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
+{
+	setFocusObject(gObjectList.findObject(object_id));
+	LLVector3d old_focus = mFocusTargetGlobal;
+	LLViewerObject *focus_obj = mFocusObject;
+
+	// if focus has changed
+	if (old_focus != focus)
+	{
+		if (focus.isExactlyZero())
+		{
+			if (gAgentHACK.mAvatarObject.notNull())
+			{
+				mFocusTargetGlobal = gAgentHACK.getPosGlobalFromAgent(gAgentHACK.mAvatarObject->mHeadp->getWorldPosition());
+			}
+			else
+			{
+				mFocusTargetGlobal = gAgentHACK.getPositionGlobal();
+			}
+			mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal;
+			mCameraFocusOffset = mCameraFocusOffsetTarget;
+			setLookAt(LOOKAT_TARGET_CLEAR);
+		}
+		else
+		{
+			mFocusTargetGlobal = focus;
+			if (!focus_obj)
+			{
+				mCameraFOVZoomFactor = 0.f;
+			}
+
+			mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal;
+
+			startCameraAnimation();
+
+			if (focus_obj)
+			{
+				if (focus_obj->isAvatar())
+				{
+					setLookAt(LOOKAT_TARGET_FOCUS, focus_obj);
+				}
+				else
+				{
+					setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (gAgentHACK.getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation());
+				}
+			}
+			else
+			{
+				setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgentHACK.getPosAgentFromGlobal(mFocusTargetGlobal));
+			}
+		}
+	}
+	else // focus == mFocusTargetGlobal
+	{
+		if (focus.isExactlyZero())
+		{
+			if (gAgentHACK.mAvatarObject.notNull())
+			{
+				mFocusTargetGlobal = gAgentHACK.getPosGlobalFromAgent(gAgentHACK.mAvatarObject->mHeadp->getWorldPosition());
+			}
+			else
+			{
+				mFocusTargetGlobal = gAgentHACK.getPositionGlobal();
+			}
+		}
+		mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);;
+		mCameraFocusOffset = mCameraFocusOffsetTarget;
+	}
+
+	if (mFocusObject.notNull())
+	{
+		// 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())
+			{
+				mFocusObject = (LLViewerObject*) mFocusObject->getParent();
+			}
+			setFocusObject((LLViewerObject*)mFocusObject);
+		}
+		updateFocusOffset();
+	}
+}
+
+// Used for avatar customization
+//-----------------------------------------------------------------------------
+// setCameraPosAndFocusGlobal()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, const LLVector3d& focus, const LLUUID &object_id)
+{
+	LLVector3d old_focus = mFocusTargetGlobal;
+
+	F64 focus_delta_squared = (old_focus - focus).magVecSquared();
+	const F64 ANIM_EPSILON_SQUARED = 0.0001;
+	if( focus_delta_squared > ANIM_EPSILON_SQUARED )
+	{
+		startCameraAnimation();
+
+		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 ));
+		}
+	}
+	
+	//LLViewerCamera::getInstance()->setOrigin( gAgent.getPosAgentFromGlobal( camera_pos ) );
+	setFocusObject(gObjectList.findObject(object_id));
+	mFocusTargetGlobal = focus;
+	mCameraFocusOffsetTarget = camera_pos - focus;
+	mCameraFocusOffset = mCameraFocusOffsetTarget;
+
+	if (mFocusObject)
+	{
+		if (mFocusObject->isAvatar())
+		{
+			setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject);
+		}
+		else
+		{
+			setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (gAgentHACK.getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation());
+		}
+	}
+	else
+	{
+		setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgentHACK.getPosAgentFromGlobal(mFocusTargetGlobal));
+	}
+
+	if( mCameraAnimating )
+	{
+		const F64 ANIM_METERS_PER_SECOND = 10.0;
+		const F64 MIN_ANIM_SECONDS = 0.5;
+		const F64 MAX_ANIM_SECONDS = 10.0;
+		F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
+		anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS );
+		setAnimationDuration( (F32)anim_duration );
+	}
+
+	updateFocusOffset();
+}
+
+//-----------------------------------------------------------------------------
+// setSitCamera()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos, const LLVector3 &camera_focus)
+{
+	BOOL camera_enabled = !object_id.isNull();
+
+	if (camera_enabled)
+	{
+		LLViewerObject *reference_object = gObjectList.findObject(object_id);
+		if (reference_object)
+		{
+			//convert to root object relative?
+			mSitCameraPos = camera_pos;
+			mSitCameraFocus = camera_focus;
+			mSitCameraReferenceObject = reference_object;
+			mSitCameraEnabled = TRUE;
+		}
+	}
+	else
+	{
+		mSitCameraPos.clearVec();
+		mSitCameraFocus.clearVec();
+		mSitCameraReferenceObject = NULL;
+		mSitCameraEnabled = FALSE;
+	}
+}
+
+//-----------------------------------------------------------------------------
+// setFocusOnAvatar()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
+{
+	if (focus_on_avatar != mFocusOnAvatar)
+	{
+		if (animate)
+		{
+			startCameraAnimation();
+		}
+		else
+		{
+			stopCameraAnimation();
+		}
+	}
+	
+	//RN: when focused on the avatar, we're not "looking" at it
+	// looking implies intent while focusing on avatar means
+	// you're just walking around with a camera on you...eesh.
+	if (!mFocusOnAvatar && focus_on_avatar)
+	{
+		setFocusGlobal(LLVector3d::zero);
+		mCameraFOVZoomFactor = 0.f;
+		if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
+		{
+			LLVector3 at_axis;
+			if (gAgentHACK.mAvatarObject.notNull() && gAgentHACK.mAvatarObject->getParent())
+			{
+				LLQuaternion obj_rot = ((LLViewerObject*)gAgentHACK.mAvatarObject->getParent())->getRenderRotation();
+				at_axis = LLViewerCamera::getInstance()->getAtAxis();
+				at_axis.mV[VZ] = 0.f;
+				at_axis.normalize();
+				gAgentHACK.resetAxes(at_axis * ~obj_rot);
+			}
+			else
+			{
+				at_axis = LLViewerCamera::getInstance()->getAtAxis();
+				at_axis.mV[VZ] = 0.f;
+				at_axis.normalize();
+				gAgentHACK.resetAxes(at_axis);
+			}
+		}
+	}
+	// unlocking camera from avatar
+	else if (mFocusOnAvatar && !focus_on_avatar)
+	{
+		// keep camera focus point consistent, even though it is now unlocked
+		setFocusGlobal(gAgentHACK.getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID());
+	}
+	
+	mFocusOnAvatar = focus_on_avatar;
+}
+
+
+BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position)
+{
+	if(object && object->isAttachment())
+	{
+		LLViewerObject* parent = object;
+		while(parent)
+		{
+			if (parent == gAgentHACK.mAvatarObject)
+			{
+				// looking at an attachment on ourselves, which we don't want to do
+				object = gAgentHACK.mAvatarObject;
+				position.clearVec();
+			}
+			parent = (LLViewerObject*)parent->getParent();
+		}
+	}
+	if(!mLookAt || mLookAt->isDead())
+	{
+		mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
+		mLookAt->setSourceObject(gAgentHACK.mAvatarObject);
+	}
+
+	return mLookAt->setLookAt(target_type, object, position);
+}
+
+BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
+{
+	// disallow pointing at attachments and avatars
+	if (object && (object->isAttachment() || object->isAvatar()))
+	{
+		return FALSE;
+	}
+
+	if(!mPointAt || mPointAt->isDead())
+	{
+		mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
+		mPointAt->setSourceObject(gAgentHACK.mAvatarObject);
+	}
+
+	return mPointAt->setPointAt(target_type, object, position);
+}
+
+ELookAtType LLAgentCamera::getLookAtType()
+{ 
+	if (mLookAt) 
+	{
+		return mLookAt->getLookAtType();
+	}
+
+	return LOOKAT_TARGET_NONE;
+}
+
+EPointAtType LLAgentCamera::getPointAtType()
+{ 
+	if (mPointAt) 
+	{
+		return mPointAt->getPointAtType();
+	}
+
+	return POINTAT_TARGET_NONE;
+}
+
+// EOF
+
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
new file mode 100644
index 0000000000..6a0e8d372e
--- /dev/null
+++ b/indra/newview/llagentcamera.h
@@ -0,0 +1,370 @@
+/** 
+ * @file llagent.h
+ * @brief LLAgent class header file
+ *
+ * $LicenseInfo:firstyear=2000&license=viewergpl$
+ * 
+ * Copyright (c) 2000-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAGENTCAMERA_H
+#define LL_LLAGENTCAMERA_H
+
+#include "indra_constants.h"
+#include "llevent.h" 				// LLObservable base class
+#include "llagent.h"
+#include "llagentaccess.h"
+#include "llagentconstants.h"
+#include "llagentdata.h" 			// gAgentID, gAgentSessionID
+#include "llcharacter.h" 			// LLAnimPauseRequest
+#include "llfollowcam.h" 			// Ventrella
+#include "llhudeffectlookat.h" 		// EPointAtType
+#include "llhudeffectpointat.h" 	// ELookAtType
+#include "llpointer.h"
+#include "lluicolor.h"
+#include "llvoavatardefines.h"
+
+class LLChat;
+class LLVOAvatarSelf;
+class LLViewerRegion;
+class LLMotion;
+class LLToolset;
+class LLMessageSystem;
+class LLPermissions;
+class LLHost;
+class LLFriendObserver;
+class LLPickInfo;
+class LLViewerObject;
+class LLAgentDropGroupViewerNode;
+
+//--------------------------------------------------------------------
+// Types
+//--------------------------------------------------------------------
+enum ECameraMode
+{
+	CAMERA_MODE_THIRD_PERSON,
+	CAMERA_MODE_MOUSELOOK,
+	CAMERA_MODE_CUSTOMIZE_AVATAR,
+	CAMERA_MODE_FOLLOW
+};
+
+/** Camera Presets for CAMERA_MODE_THIRD_PERSON */
+enum ECameraPreset 
+{
+	/** Default preset, what the Third Person Mode actually was */
+	CAMERA_PRESET_REAR_VIEW,
+	
+	/** "Looking at the Avatar from the front" */
+	CAMERA_PRESET_FRONT_VIEW, 
+
+	/** "Above and to the left, over the shoulder, pulled back a little on the zoom" */
+	CAMERA_PRESET_GROUP_VIEW
+};
+
+//------------------------------------------------------------------------
+// LLAgentCamera
+//------------------------------------------------------------------------
+class LLAgentCamera
+{
+	LOG_CLASS(LLAgentCamera);
+
+public:
+	friend class LLAgent;
+
+/********************************************************************************
+ **                                                                            **
+ **                    INITIALIZATION
+ **/
+
+	// SERAPH UNFILED
+public:
+	F32				mDrawDistance;
+
+	//--------------------------------------------------------------------
+	// Constructors / Destructors
+	//--------------------------------------------------------------------
+public:
+	LLAgentCamera();
+	virtual 		~LLAgentCamera();
+	void			init();
+	void			cleanup();
+private:
+	BOOL			mInitialized;
+
+	//--------------------------------------------------------------------
+	// Mode
+	//--------------------------------------------------------------------
+public:
+	void			changeCameraToDefault();
+	void			changeCameraToMouselook(BOOL animate = TRUE);
+	void			changeCameraToThirdPerson(BOOL animate = TRUE);
+	void			changeCameraToCustomizeAvatar(BOOL avatar_animate = TRUE, BOOL camera_animate = TRUE); // Trigger transition animation
+	void			changeCameraToFollow(BOOL animate = TRUE); 	// Ventrella
+	BOOL			cameraThirdPerson() const		{ return (mCameraMode == CAMERA_MODE_THIRD_PERSON && mLastCameraMode == CAMERA_MODE_THIRD_PERSON); }
+	BOOL			cameraMouselook() const			{ return (mCameraMode == CAMERA_MODE_MOUSELOOK && mLastCameraMode == CAMERA_MODE_MOUSELOOK); }
+	BOOL			cameraCustomizeAvatar() const	{ return (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR /*&& !mCameraAnimating*/); }
+	BOOL			cameraFollow() const			{ return (mCameraMode == CAMERA_MODE_FOLLOW && mLastCameraMode == CAMERA_MODE_FOLLOW); }
+	ECameraMode		getCameraMode() const 			{ return mCameraMode; }
+	void			updateCamera();					// Call once per frame to update camera location/orientation
+	void			resetCamera(); 					// Slam camera into its default position
+private:
+	ECameraMode		mCameraMode;					// Target mode after transition animation is done
+	ECameraMode		mLastCameraMode;
+
+	//--------------------------------------------------------------------
+	// Preset
+	//--------------------------------------------------------------------
+public:
+	void switchCameraPreset(ECameraPreset preset);
+
+private:
+	
+	/** Determines default camera offset depending on the current camera preset */
+	LLVector3 getCameraOffsetInitial();
+
+	/** Camera preset in Third Person Mode */
+	ECameraPreset mCameraPreset; 
+
+	/** Initial camera offsets */
+	std::map<ECameraPreset, LLVector3> mCameraOffsetInitial;
+
+	/** Initial focus offsets */
+	std::map<ECameraPreset, LLVector3d> mFocusOffsetInitial;
+
+
+	//--------------------------------------------------------------------
+	// Position
+	//--------------------------------------------------------------------
+public:
+	LLVector3d		getCameraPositionGlobal() const;
+	const LLVector3 &getCameraPositionAgent() const;
+	LLVector3d		calcCameraPositionTargetGlobal(BOOL *hit_limit = NULL); // Calculate the camera position target
+	F32				getCameraMinOffGround(); 		// Minimum height off ground for this mode, meters
+	void			setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; }
+	BOOL			calcCameraMinDistance(F32 &obj_min_distance);
+	F32				calcCustomizeAvatarUIOffset(const LLVector3d& camera_pos_global);
+	F32				getCurrentCameraBuildOffset() 	{ return (F32)mCameraFocusOffset.length(); }
+private:
+	F32				mCurrentCameraDistance;	 		// Current camera offset from avatar
+	F32				mTargetCameraDistance;			// Target camera offset from avatar
+	F32				mCameraFOVZoomFactor;			// Amount of fov zoom applied to camera when zeroing in on an object
+	F32				mCameraCurrentFOVZoomFactor;	// Interpolated fov zoom
+	F32				mCameraFOVDefault;				// Default field of view that is basis for FOV zoom effect
+	LLVector4		mCameraCollidePlane;			// Colliding plane for camera
+	F32				mCameraZoomFraction;			// Mousewheel driven fraction of zoom
+	LLVector3		mCameraPositionAgent;			// Camera position in agent coordinates
+	LLVector3		mCameraVirtualPositionAgent;	// Camera virtual position (target) before performing FOV zoom
+	LLVector3d      mCameraSmoothingLastPositionGlobal;    
+	LLVector3d      mCameraSmoothingLastPositionAgent;
+	BOOL            mCameraSmoothingStop;
+	LLVector3		mCameraLag;						// Third person camera lag
+	LLVector3		mCameraUpVector;				// Camera's up direction in world coordinates (determines the 'roll' of the view)
+
+	//--------------------------------------------------------------------
+	// Orbit
+	//--------------------------------------------------------------------
+public:
+	void			setOrbitLeftKey(F32 mag)	{ mOrbitLeftKey = mag; }
+	void			setOrbitRightKey(F32 mag)	{ mOrbitRightKey = mag; }
+	void			setOrbitUpKey(F32 mag)		{ mOrbitUpKey = mag; }
+	void			setOrbitDownKey(F32 mag)	{ mOrbitDownKey = mag; }
+	void			setOrbitInKey(F32 mag)		{ mOrbitInKey = mag; }
+	void			setOrbitOutKey(F32 mag)		{ mOrbitOutKey = mag; }
+private:
+	F32				mOrbitLeftKey;
+	F32				mOrbitRightKey;
+	F32				mOrbitUpKey;
+	F32				mOrbitDownKey;
+	F32				mOrbitInKey;
+	F32				mOrbitOutKey;
+
+	//--------------------------------------------------------------------
+	// Pan
+	//--------------------------------------------------------------------
+public:
+	void			setPanLeftKey(F32 mag)		{ mPanLeftKey = mag; }
+	void			setPanRightKey(F32 mag)		{ mPanRightKey = mag; }
+	void			setPanUpKey(F32 mag)		{ mPanUpKey = mag; }
+	void			setPanDownKey(F32 mag)		{ mPanDownKey = mag; }
+	void			setPanInKey(F32 mag)		{ mPanInKey = mag; }
+	void			setPanOutKey(F32 mag)		{ mPanOutKey = mag; }
+private:
+	F32				mPanUpKey;						
+	F32				mPanDownKey;					
+	F32				mPanLeftKey;					
+	F32				mPanRightKey;					
+	F32				mPanInKey;
+	F32				mPanOutKey;	
+	
+	//--------------------------------------------------------------------
+	// Follow
+	//--------------------------------------------------------------------
+public:
+	void			setUsingFollowCam(bool using_follow_cam);
+private:
+	LLFollowCam 	mFollowCam; 			// Ventrella
+
+	//--------------------------------------------------------------------
+	// Sit
+	//--------------------------------------------------------------------
+public:
+	void			setupSitCamera();
+	BOOL			sitCameraEnabled() 		{ return mSitCameraEnabled; }
+	void			setSitCamera(const LLUUID &object_id, 
+								 const LLVector3 &camera_pos = LLVector3::zero, const LLVector3 &camera_focus = LLVector3::zero);
+private:
+	LLPointer<LLViewerObject> mSitCameraReferenceObject; // Object to which camera is related when sitting
+	BOOL			mSitCameraEnabled;		// Use provided camera information when sitting?
+	LLVector3		mSitCameraPos;			// Root relative camera pos when sitting
+	LLVector3		mSitCameraFocus;		// Root relative camera target when sitting
+
+	//--------------------------------------------------------------------
+	// Animation
+	//--------------------------------------------------------------------
+public:
+	void			setCameraAnimating(BOOL b)			{ mCameraAnimating = b; }
+	BOOL			getCameraAnimating()				{ return mCameraAnimating; }
+	void			setAnimationDuration(F32 seconds) 	{ mAnimationDuration = seconds; }
+	void			startCameraAnimation();
+	void			stopCameraAnimation();
+private:
+	LLFrameTimer	mAnimationTimer; 	// Seconds that transition animation has been active // SERAPH agentCamera
+	F32				mAnimationDuration;	// In seconds
+	BOOL			mCameraAnimating;					// Camera is transitioning from one mode to another
+	LLVector3d		mAnimationCameraStartGlobal;		// Camera start position, global coords
+	LLVector3d		mAnimationFocusStartGlobal;			// Camera focus point, global coords
+
+	//--------------------------------------------------------------------
+	// Focus
+	//--------------------------------------------------------------------
+public:
+	LLVector3d		calcFocusPositionTargetGlobal();
+	LLVector3		calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y);
+	BOOL			getFocusOnAvatar() const		{ return mFocusOnAvatar; }
+	LLPointer<LLViewerObject>&	getFocusObject() 	{ return mFocusObject; }
+	F32				getFocusObjectDist() const		{ return mFocusObjectDist; }
+	void			updateFocusOffset();
+	void			validateFocusObject();
+	void			setFocusGlobal(const LLPickInfo& pick);
+	void			setFocusGlobal(const LLVector3d &focus, const LLUUID &object_id = LLUUID::null);
+	void			setFocusOnAvatar(BOOL focus, BOOL animate);
+	void			setCameraPosAndFocusGlobal(const LLVector3d& pos, const LLVector3d& focus, const LLUUID &object_id);
+	void			clearFocusObject();
+	void			setFocusObject(LLViewerObject* object);
+	void			setObjectTracking(BOOL track) 	{ mTrackFocusObject = track; }
+	const LLVector3d &getFocusGlobal() const		{ return mFocusGlobal; }
+	const LLVector3d &getFocusTargetGlobal() const	{ return mFocusTargetGlobal; }
+private:
+	LLVector3d		mCameraFocusOffset;				// Offset from focus point in build mode
+	LLVector3d		mCameraFocusOffsetTarget;		// Target towards which we are lerping the camera's focus offset
+	BOOL			mFocusOnAvatar;					
+	LLVector3d		mFocusGlobal;
+	LLVector3d		mFocusTargetGlobal;
+	LLPointer<LLViewerObject> mFocusObject;
+	F32				mFocusObjectDist;
+	LLVector3		mFocusObjectOffset;
+	F32				mFocusDotRadius; 				// Meters
+	BOOL			mTrackFocusObject;
+	F32				mUIOffset;	
+	
+	//--------------------------------------------------------------------
+	// Lookat / Pointat
+	//--------------------------------------------------------------------
+public:
+	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 			slamLookAt(const LLVector3 &look_at); // Set the physics data
+	BOOL			setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero);
+	EPointAtType	getPointAtType();
+public:
+	LLPointer<LLHUDEffectLookAt> mLookAt;
+	LLPointer<LLHUDEffectPointAt> mPointAt;
+
+	//--------------------------------------------------------------------
+	// Third person
+	//--------------------------------------------------------------------
+public:
+	LLVector3d		calcThirdPersonFocusOffset();
+	void			setThirdPersonHeadOffset(LLVector3 offset) 	{ mThirdPersonHeadOffset = offset; }	
+private:
+	LLVector3		mThirdPersonHeadOffset;						// Head offset for third person camera position
+
+	//--------------------------------------------------------------------
+	// Orbit
+	//--------------------------------------------------------------------
+public:
+	void			cameraOrbitAround(const F32 radians);	// Rotate camera CCW radians about build focus point
+	void			cameraOrbitOver(const F32 radians);		// Rotate camera forward radians over build focus point
+	void			cameraOrbitIn(const F32 meters);		// Move camera in toward build focus point
+
+	//--------------------------------------------------------------------
+	// Zoom
+	//--------------------------------------------------------------------
+public:
+	void			handleScrollWheel(S32 clicks); 			// Mousewheel driven zoom
+	void			cameraZoomIn(const F32 factor);			// Zoom in by fraction of current distance
+	F32				getCameraZoomFraction();				// Get camera zoom as fraction of minimum and maximum zoom
+	void			setCameraZoomFraction(F32 fraction);	// Set camera zoom as fraction of minimum and maximum zoom
+	F32				calcCameraFOVZoomFactor();
+
+	//--------------------------------------------------------------------
+	// Pan
+	//--------------------------------------------------------------------
+public:
+	void			cameraPanIn(const F32 meters);
+	void			cameraPanLeft(const F32 meters);
+	void			cameraPanUp(const F32 meters);
+	
+	//--------------------------------------------------------------------
+	// View
+	//--------------------------------------------------------------------
+public:
+	// Called whenever the agent moves.  Puts camera back in default position, deselects items, etc.
+	void			resetView(BOOL reset_camera = TRUE, BOOL change_camera = FALSE);
+	// Called on camera movement.  Unlocks camera from the default position behind the avatar.
+	void			unlockView();
+
+	//--------------------------------------------------------------------
+	// Mouselook
+	//--------------------------------------------------------------------
+public:
+	BOOL			getForceMouselook() const 			{ return mForceMouselook; }
+	void			setForceMouselook(BOOL mouselook) 	{ mForceMouselook = mouselook; }
+private:
+	BOOL			mForceMouselook;
+	
+	//--------------------------------------------------------------------
+	// HUD
+	//--------------------------------------------------------------------
+public:
+	F32				mHUDTargetZoom;	// Target zoom level for HUD objects (used when editing)
+	F32				mHUDCurZoom; 	// Current animated zoom level for HUD objects
+};
+
+extern LLAgentCamera gAgentCamera;
+
+#endif
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 1187455971..bcb62e1b6f 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -32,7 +32,8 @@
 
 #include "llviewerprecompiledheaders.h"
 
-#include "llagent.h" 
+#include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 
 #include "llcallbacklist.h"
@@ -1087,7 +1088,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void*
 
 		// Check to see if there are any baked textures that we hadn't uploaded before we logged off last time.
 		// If there are any, schedule them to be uploaded as soon as the layer textures they depend on arrive.
-		if (gAgent.cameraCustomizeAvatar())
+		if (gAgentCamera.cameraCustomizeAvatar())
 		{
 			avatar->requestLayerSetUploads();
 		}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 2384e6c5ba..aaac36d557 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -44,6 +44,7 @@
 #include "llviewertexturelist.h"
 #include "llgroupmgr.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llwindow.h"
 #include "llviewerstats.h"
@@ -3345,10 +3346,10 @@ void LLAppViewer::saveFinalSnapshot()
 {
 	if (!mSavedFinalSnapshot && !gNoRender)
 	{
-		gSavedSettings.setVector3d("FocusPosOnLogout", gAgent.calcFocusPositionTargetGlobal());
-		gSavedSettings.setVector3d("CameraPosOnLogout", gAgent.calcCameraPositionTargetGlobal());
+		gSavedSettings.setVector3d("FocusPosOnLogout", gAgentCamera.calcFocusPositionTargetGlobal());
+		gSavedSettings.setVector3d("CameraPosOnLogout", gAgentCamera.calcCameraPositionTargetGlobal());
 		gViewerWindow->setCursor(UI_CURSOR_WAIT);
-		gAgent.changeCameraToThirdPerson( FALSE );	// don't animate, need immediate switch
+		gAgentCamera.changeCameraToThirdPerson( FALSE );	// don't animate, need immediate switch
 		gSavedSettings.setBOOL("ShowParcelOwners", FALSE);
 		idle();
 
@@ -3758,7 +3759,7 @@ void LLAppViewer::idle()
 			LLViewerJoystick::getInstance()->moveObjects();
 		}
 
-		gAgent.updateCamera();
+		gAgentCamera.updateCamera();
 	}
 
 	// update media focus
diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp
index 5e71e64b2f..50363ea2e7 100644
--- a/indra/newview/llaudiosourcevo.cpp
+++ b/indra/newview/llaudiosourcevo.cpp
@@ -35,7 +35,7 @@
 
 #include "llaudiosourcevo.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llmutelist.h"
 #include "llviewerparcelmgr.h"
 
@@ -148,7 +148,7 @@ void LLAudioSourceVO::update()
 	updateGain();
 	if (mObjectp->isHUDAttachment())
 	{
-		mPositionGlobal = gAgent.getCameraPositionGlobal();
+		mPositionGlobal = gAgentCamera.getCameraPositionGlobal();
 	}
 	else
 	{
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index b88be53d79..34cb6fd2eb 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -35,7 +35,7 @@
 #define LLBOTTOMTRAY_CPP
 #include "llbottomtray.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llchiclet.h"
 #include "llfloaterreg.h"
 #include "llflyoutbutton.h"
@@ -125,7 +125,7 @@ public:
 
 	void onFocusLost()
 	{
-		if (gAgent.cameraMouselook())
+		if (gAgentCamera.cameraMouselook())
 		{
 			LLBottomTray::getInstance()->setVisible(FALSE);
 		}
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index d0188352c7..d84ebef1dd 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -38,11 +38,11 @@
 #include "llfloaterreg.h"
 
 // Viewer includes
+#include "llagentcamera.h"
 #include "lljoystickbutton.h"
 #include "llviewercontrol.h"
 #include "llviewercamera.h"
 #include "llbottomtray.h"
-#include "llagent.h"
 #include "lltoolmgr.h"
 #include "lltoolfocus.h"
 #include "llslider.h"
@@ -104,7 +104,7 @@ BOOL LLPanelCameraZoom::postBuild()
 
 void LLPanelCameraZoom::draw()
 {
-	mSlider->setValue(gAgent.getCameraZoomFraction());
+	mSlider->setValue(gAgentCamera.getCameraZoomFraction());
 	LLPanel::draw();
 }
 
@@ -131,7 +131,7 @@ void LLPanelCameraZoom::onZoomMinusHeldDown()
 void  LLPanelCameraZoom::onSliderValueChanged()
 {
 	F32 zoom_level = mSlider->getValueF32();
-	gAgent.setCameraZoomFraction(zoom_level);
+	gAgentCamera.setCameraZoomFraction(zoom_level);
 }
 
 void activate_camera_tool()
@@ -146,7 +146,7 @@ void activate_camera_tool()
 /*static*/ bool LLFloaterCamera::inFreeCameraMode()
 {
 	LLFloaterCamera* floater_camera = LLFloaterCamera::findInstance();
-	if (floater_camera && floater_camera->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+	if (floater_camera && floater_camera->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
 	{
 		return true;
 	}
@@ -265,7 +265,7 @@ ECameraControlMode LLFloaterCamera::determineMode()
 		return CAMERA_CTRL_MODE_FREE_CAMERA;
 	} 
 
-	if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+	if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
 	{
 		return CAMERA_CTRL_MODE_AVATAR_VIEW;
 	}
@@ -421,7 +421,7 @@ void LLFloaterCamera::updateCameraPresetButtons()
 	childSetValue("rear_view",		preset == CAMERA_PRESET_REAR_VIEW);
 	childSetValue("group_view",		preset == CAMERA_PRESET_GROUP_VIEW);
 	childSetValue("front_view",		preset == CAMERA_PRESET_FRONT_VIEW);
-	childSetValue("mouselook_view",	gAgent.cameraMouselook());
+	childSetValue("mouselook_view",	gAgentCamera.cameraMouselook());
 }
 
 void LLFloaterCamera::onClickCameraPresets(const LLSD& param)
@@ -430,19 +430,19 @@ void LLFloaterCamera::onClickCameraPresets(const LLSD& param)
 
 	if ("rear_view" == name)
 	{
-		gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
+		gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
 	}
 	else if ("group_view" == name)
 	{
-		gAgent.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
+		gAgentCamera.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW);
 	}
 	else if ("front_view" == name)
 	{
-		gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
+		gAgentCamera.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW);
 	}
 	else if ("mouselook_view" == name)
 	{
-		gAgent.changeCameraToMouselook();
+		gAgentCamera.changeCameraToMouselook();
 	}
 
 	LLFloaterCamera* camera_floater = LLFloaterCamera::findInstance();
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index 844f0ac509..d7b2b24382 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -34,7 +34,7 @@
 
 #include "llfloaterinventory.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 //#include "llfirstuse.h"
 #include "llfloaterreg.h"
 #include "llinventorymodel.h"
@@ -115,7 +115,7 @@ LLFloaterInventory* LLFloaterInventory::showAgentInventory()
 	instance_num = (instance_num + 1) % S32_MAX;
 
 	LLFloaterInventory* iv = NULL;
-	if (!gAgent.cameraMouselook())
+	if (!gAgentCamera.cameraMouselook())
 	{
 		iv = LLFloaterReg::showTypedInstance<LLFloaterInventory>("inventory", LLSD(instance_num));
 	}
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index 051ab585e2..8894628788 100644
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -41,7 +41,7 @@
 #include "llglheaders.h"
 
 // Viewer includes
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "llnetmap.h"
 #include "lltracker.h"
@@ -196,7 +196,7 @@ void LLFloaterMap::draw()
 	setDirectionPos( mTextBoxSouthEast, rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2);
 
 	// Note: we can't just gAgent.check cameraMouselook() because the transition states are wrong.
-	if( gAgent.cameraMouselook())
+	if(gAgentCamera.cameraMouselook())
 	{
 		setMouseOpaque(FALSE);
 		getDragHandle()->setMouseOpaque(FALSE);
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 2df297fc42..4d09523b82 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -38,6 +38,7 @@
 
 // Viewer includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentui.h"
 #include "llbottomtray.h"
 #include "llbutton.h"
@@ -912,7 +913,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 			previewp->mSnapshotUpToDate = TRUE;
 			previewp->generateThumbnailImage(TRUE) ;
 
-			previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal();
+			previewp->mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal();
 			previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
 		}
 	}
@@ -1100,7 +1101,7 @@ void LLSnapshotLivePreview::saveWeb(std::string url)
 
 	body["avatar_name"] = name;
 	
-	LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(gAgent.getCameraPositionGlobal(),
+	LLLandmarkActions::getRegionNameAndCoordsFromPosGlobal(gAgentCamera.getCameraPositionGlobal(),
 		boost::bind(&LLSnapshotLivePreview::regionNameCallback, this, url, body, _1, _2, _3, _4));
 	
 	gViewerWindow->playSnapshotAnimAndSound();
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 7c42a581ff..d8d7057c4e 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -38,7 +38,7 @@
 #include "llcoord.h"
 //#include "llgl.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llcombobox.h"
@@ -533,7 +533,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 	}
 
 	// multiply by correction factor because volume sliders go [0, 0.5]
-	childSetValue( "slider zoom", gAgent.getCameraZoomFraction() * 0.5f);
+	childSetValue( "slider zoom", gAgentCamera.getCameraZoomFraction() * 0.5f);
 
 	// Move buttons
 	BOOL move_visible = (tool == LLToolGrab::getInstance());
@@ -766,7 +766,7 @@ void LLFloaterTools::onClose(bool app_quitting)
 
     // Different from handle_reset_view in that it doesn't actually 
 	//   move the camera if EditCameraMovement is not set.
-	gAgent.resetView(gSavedSettings.getBOOL("EditCameraMovement"));
+	gAgentCamera.resetView(gSavedSettings.getBOOL("EditCameraMovement"));
 	
 	// exit component selection mode
 	LLSelectMgr::getInstance()->promoteSelectionToRoot();
@@ -847,7 +847,7 @@ void commit_slider_zoom(LLUICtrl *ctrl)
 {
 	// renormalize value, since max "volume" level is 0.5 for some reason
 	F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
-	gAgent.setCameraZoomFraction(zoom_level);
+	gAgentCamera.setCameraZoomFraction(zoom_level);
 }
 
 void click_popup_rotate_left(void*)
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 67c0b530eb..391e63f730 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -41,6 +41,7 @@
 #include "llfloaterworldmap.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llbutton.h"
 #include "llcallingcard.h"
 #include "llcombobox.h"
@@ -1220,12 +1221,12 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
 		{
 			// We've got the position finally, so we're no longer busy. JC
 //			getWindow()->decBusyCount();
-			pos_global = LLTracker::getTrackedPositionGlobal() - gAgent.getCameraPositionGlobal();
+			pos_global = LLTracker::getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();
 		}
 	}
 	else if(LLWorldMap::getInstance()->isTracking())
 	{
-		pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgent.getCameraPositionGlobal();;
+		pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgentCamera.getCameraPositionGlobal();;
 	}
 	else
 	{
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 8569e208eb..2aba0b5c09 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -71,99 +71,6 @@
 // Height of the yellow selection highlight posts for land
 const F32 PARCEL_POST_HEIGHT = 0.666f;
 
-BOOL LLAgent::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position)
-{
-	if(object && object->isAttachment())
-	{
-		LLViewerObject* parent = object;
-		while(parent)
-		{
-			if (parent == mAvatarObject)
-			{
-				// looking at an attachment on ourselves, which we don't want to do
-				object = mAvatarObject;
-				position.clearVec();
-			}
-			parent = (LLViewerObject*)parent->getParent();
-		}
-	}
-	if(!mLookAt || mLookAt->isDead())
-	{
-		mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
-		mLookAt->setSourceObject(mAvatarObject);
-	}
-
-	return mLookAt->setLookAt(target_type, object, position);
-}
-
-BOOL LLAgent::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position)
-{
-	// disallow pointing at attachments and avatars
-	if (object && (object->isAttachment() || object->isAvatar()))
-	{
-		return FALSE;
-	}
-
-	if(!mPointAt || mPointAt->isDead())
-	{
-		mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
-		mPointAt->setSourceObject(mAvatarObject);
-	}
-
-	return mPointAt->setPointAt(target_type, object, position);
-}
-
-ELookAtType LLAgent::getLookAtType()
-{ 
-	if (mLookAt) 
-	{
-		return mLookAt->getLookAtType();
-	}
-
-	return LOOKAT_TARGET_NONE;
-}
-
-EPointAtType LLAgent::getPointAtType()
-{ 
-	if (mPointAt) 
-	{
-		return mPointAt->getPointAtType();
-	}
-
-	return POINTAT_TARGET_NONE;
-}
-
-// Draw a representation of current autopilot target
-void LLAgent::renderAutoPilotTarget()
-{
-	if (mAutoPilot)
-	{
-		F32 height_meters;
-		LLVector3d target_global;
-
-		glMatrixMode(GL_MODELVIEW);
-		gGL.pushMatrix();
-
-		// not textured
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-		// lovely green
-		glColor4f(0.f, 1.f, 1.f, 1.f);
-
-		target_global = mAutoPilotTargetGlobal;
-
-		gGL.translatef((F32)(target_global.mdV[VX]), (F32)(target_global.mdV[VY]), (F32)(target_global.mdV[VZ]));
-
-		height_meters = 1.f;
-
-		glScalef(height_meters, height_meters, height_meters);
-
-		gSphere.render(1500.f);
-
-		gGL.popMatrix();
-	}
-}
-
 // Returns true if you got at least one object
 void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 {
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 07b81ef134..3be0fcbc5f 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -38,6 +38,7 @@
 
 #include "message.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llvoavatar.h"
 #include "lldrawable.h"
 #include "llviewerobjectlist.h"
@@ -316,7 +317,7 @@ void LLHUDEffectLookAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
 	LLUUID dataId;
 	mesgsys->getUUIDFast(_PREHASH_Effect, _PREHASH_ID, dataId, blocknum);
 
-	if (!gAgent.mLookAt.isNull() && dataId == gAgent.mLookAt->getID())
+	if (!gAgentCamera.mLookAt.isNull() && dataId == gAgentCamera.mLookAt->getID())
 	{
 		return;
 	}
@@ -637,7 +638,7 @@ bool LLHUDEffectLookAt::calcTargetPosition()
 				// mouselook and freelook target offsets are absolute
 				target_rot = LLQuaternion::DEFAULT;
 			}
-			else if (looking_at_self && gAgent.cameraCustomizeAvatar())
+			else if (looking_at_self && gAgentCamera.cameraCustomizeAvatar())
 			{
 				// *NOTE: We have to do this because animation
 				// overrides do not set lookat behavior.
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index a13ee8572f..01dfb50b10 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -38,6 +38,7 @@
 #include "llrender.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "lldrawable.h"
 #include "llviewerobjectlist.h"
 #include "llvoavatar.h"
@@ -152,7 +153,7 @@ void LLHUDEffectPointAt::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
 	mesgsys->getUUIDFast(_PREHASH_Effect, _PREHASH_ID, dataId, blocknum);
 
 	// ignore messages from ourselves
-	if (!gAgent.mPointAt.isNull() && dataId == gAgent.mPointAt->getID())
+	if (!gAgentCamera.mPointAt.isNull() && dataId == gAgentCamera.mPointAt->getID())
 	{
 		return;
 	}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index ceeffea1c9..51c5cf00a7 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -37,6 +37,7 @@
 #include "llinventorybridge.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
 #include "llavataractions.h"
@@ -4904,10 +4905,10 @@ void LLWearableBridge::editOnAvatar()
 		if (gFloaterCustomize)
 			gFloaterCustomize->setCurrentWearableType( wearable->getType() );
 
-		if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() )
+		if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() )
 		{
 			// Start Avatar Customization
-			gAgent.changeCameraToCustomizeAvatar();
+			gAgentCamera.changeCameraToCustomizeAvatar();
 		}
 	}
 }
diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp
index 2cc5c8335d..33f651284b 100644
--- a/indra/newview/lljoystickbutton.cpp
+++ b/indra/newview/lljoystickbutton.cpp
@@ -42,6 +42,7 @@
 // Project includes
 #include "llui.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewertexture.h"
 #include "llviewertexturelist.h"
 #include "llviewerwindow.h"
@@ -482,25 +483,25 @@ void LLJoystickCameraRotate::onHeldDown()
 	// left-right rotation
 	if (dx > mHorizSlopNear)
 	{
-		gAgent.unlockView();
-		gAgent.setOrbitLeftKey(getOrbitRate());
+		gAgentCamera.unlockView();
+		gAgentCamera.setOrbitLeftKey(getOrbitRate());
 	}
 	else if (dx < -mHorizSlopNear)
 	{
-		gAgent.unlockView();
-		gAgent.setOrbitRightKey(getOrbitRate());
+		gAgentCamera.unlockView();
+		gAgentCamera.setOrbitRightKey(getOrbitRate());
 	}
 
 	// over/under rotation
 	if (dy > mVertSlopNear)
 	{
-		gAgent.unlockView();
-		gAgent.setOrbitUpKey(getOrbitRate());
+		gAgentCamera.unlockView();
+		gAgentCamera.setOrbitUpKey(getOrbitRate());
 	}
 	else if (dy < -mVertSlopNear)
 	{
-		gAgent.unlockView();
-		gAgent.setOrbitDownKey(getOrbitRate());
+		gAgentCamera.unlockView();
+		gAgentCamera.setOrbitDownKey(getOrbitRate());
 	}
 }
 
@@ -625,24 +626,24 @@ void LLJoystickCameraTrack::onHeldDown()
 
 	if (dx > mVertSlopNear)
 	{
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setPanRightKey(getOrbitRate());
 	}
 	else if (dx < -mVertSlopNear)
 	{
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setPanLeftKey(getOrbitRate());
 	}
 
 	// over/under rotation
 	if (dy > mVertSlopNear)
 	{
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setPanUpKey(getOrbitRate());
 	}
 	else if (dy < -mVertSlopNear)
 	{
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setPanDownKey(getOrbitRate());
 	}
 }
@@ -692,25 +693,25 @@ void LLJoystickCameraZoom::onHeldDown()
 	if (dy > mVertSlopFar)
 	{
 		// Zoom in fast
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setOrbitInKey(FAST_RATE);
 	}
 	else if (dy > mVertSlopNear)
 	{
 		// Zoom in slow
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setOrbitInKey(getOrbitRate());
 	}
 	else if (dy < -mVertSlopFar)
 	{
 		// Zoom out fast
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setOrbitOutKey(FAST_RATE);
 	}
 	else if (dy < -mVertSlopNear)
 	{
 		// Zoom out slow
-		gAgent.unlockView();
+		gAgentCamera.unlockView();
 		gAgent.setOrbitOutKey(getOrbitRate());
 	}
 }
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index a96240e31c..957e88960d 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -43,6 +43,7 @@
 #include "llviewertexturelist.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "lldrawable.h"
 #include "llfontgl.h"
@@ -180,7 +181,7 @@ F32 LLManip::getSubdivisionLevel(const LLVector3 &reference_point, const LLVecto
 	LLVector3 cam_to_reference;
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
-		cam_to_reference = LLVector3(1.f / gAgent.mHUDCurZoom, 0.f, 0.f);
+		cam_to_reference = LLVector3(1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f);
 	}
 	else
 	{
@@ -265,8 +266,8 @@ BOOL LLManip::getMousePointOnPlaneGlobal(LLVector3d& point, S32 x, S32 y, LLVect
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
 		BOOL result = FALSE;
-		F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom;
-		F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgent.mHUDCurZoom;
+		F32 mouse_x = ((F32)x / gViewerWindow->getWorldViewWidthScaled() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
+		F32 mouse_y = ((F32)y / gViewerWindow->getWorldViewHeightScaled() - 0.5f) / gAgentCamera.mHUDCurZoom;
 
 		LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin);
 		LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y);
@@ -304,15 +305,15 @@ BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, co
 
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
-		F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom;
-		F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgent.mHUDCurZoom;
+		F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidthScaled()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom;
+		F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeightScaled()) - 0.5f) / gAgentCamera.mHUDCurZoom;
 		a1 = LLVector3(llmin(b1.mV[VX] - 0.1f, b2.mV[VX] - 0.1f, 0.f), -mouse_x, mouse_y);
 		a2 = a1 + LLVector3(1.f, 0.f, 0.f);
 	}
 	else
 	{
-		a1 = gAgent.getCameraPositionAgent();
-		a2 = gAgent.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y));
+		a1 = gAgentCamera.getCameraPositionAgent();
+		a2 = gAgentCamera.getCameraPositionAgent() + LLVector3(gViewerWindow->mouseDirectionGlobal(x, y));
 	}
 
 	BOOL parallel = TRUE;
@@ -491,7 +492,7 @@ void LLManip::renderTickText(const LLVector3& pos, const std::string& text, cons
 	LLVector3 render_pos = pos;
 	if (hud_selection)
 	{
-		F32 zoom_amt = gAgent.mHUDCurZoom;
+		F32 zoom_amt = gAgentCamera.mHUDCurZoom;
 		F32 inv_zoom_amt = 1.f / zoom_amt;
 		// scale text back up to counter-act zoom level
 		render_pos = pos * zoom_amt;
@@ -549,7 +550,7 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string
 	LLVector3 render_pos = pos;
 	if (hud_selection)
 	{
-		F32 zoom_amt = gAgent.mHUDCurZoom;
+		F32 zoom_amt = gAgentCamera.mHUDCurZoom;
 		F32 inv_zoom_amt = 1.f / zoom_amt;
 		// scale text back up to counter-act zoom level
 		render_pos = pos * zoom_amt;
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 8535d52015..6dc0a929c8 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -45,6 +45,7 @@
 
 // viewer includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llbox.h"
 #include "llbutton.h"
 #include "llviewercontrol.h"
@@ -138,7 +139,7 @@ void LLManipRotate::render()
 	glPushMatrix();
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
-		F32 zoom = gAgent.mHUDCurZoom;
+		F32 zoom = gAgentCamera.mHUDCurZoom;
 		glScalef(zoom, zoom, zoom);
 	}
 
@@ -690,7 +691,7 @@ void LLManipRotate::drag( S32 x, S32 y )
 	LLSelectMgr::getInstance()->updateSelectionCenter();
 
 	// RN: just clear focus so camera doesn't follow spurious object updates
-	gAgent.clearFocusObject();
+	gAgentCamera.clearFocusObject();
 	dialog_refresh_all();
 }
 
@@ -730,7 +731,7 @@ void LLManipRotate::renderSnapGuides()
 	}
 	else
 	{
-		cam_at_axis = center - gAgent.getCameraPositionAgent();
+		cam_at_axis = center - gAgentCamera.getCameraPositionAgent();
 		cam_at_axis.normVec();
 	}
 
@@ -1097,12 +1098,12 @@ BOOL LLManipRotate::updateVisiblity()
 	LLVector3 center = gAgent.getPosAgentFromGlobal( mRotationCenter );
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
-		mCenterToCam = LLVector3(-1.f / gAgent.mHUDCurZoom, 0.f, 0.f);
+		mCenterToCam = LLVector3(-1.f / gAgentCamera.mHUDCurZoom, 0.f, 0.f);
 		mCenterToCamNorm = mCenterToCam;
 		mCenterToCamMag = mCenterToCamNorm.normVec();
 
 		mRadiusMeters = RADIUS_PIXELS / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
-		mRadiusMeters /= gAgent.mHUDCurZoom;
+		mRadiusMeters /= gAgentCamera.mHUDCurZoom;
 
 		mCenterToProfilePlaneMag = mRadiusMeters * mRadiusMeters / mCenterToCamMag;
 		mCenterToProfilePlane = -mCenterToProfilePlaneMag * mCenterToCamNorm;
@@ -1110,8 +1111,8 @@ BOOL LLManipRotate::updateVisiblity()
 		// x axis range is (-aspect * 0.5f, +aspect * 0.5)
 		// y axis range is (-0.5, 0.5)
 		// so use getWorldViewHeightRaw as scale factor when converting to pixel coordinates
-		mCenterScreen.set((S32)((0.5f - center.mV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()),
-							(S32)((center.mV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()));
+		mCenterScreen.set((S32)((0.5f - center.mV[VY]) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()),
+							(S32)((center.mV[VZ] + 0.5f) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWorldViewHeightScaled()));
 		visible = TRUE;
 	}
 	else
@@ -1119,7 +1120,7 @@ BOOL LLManipRotate::updateVisiblity()
 		visible = LLViewerCamera::getInstance()->projectPosAgentToScreen(center, mCenterScreen );
 		if( visible )
 		{
-			mCenterToCam = gAgent.getCameraPositionAgent() - center;
+			mCenterToCam = gAgentCamera.getCameraPositionAgent() - center;
 			mCenterToCamNorm = mCenterToCam;
 			mCenterToCamMag = mCenterToCamNorm.normVec();
 			LLVector3 cameraAtAxis = LLViewerCamera::getInstance()->getAtAxis();
@@ -1165,7 +1166,7 @@ BOOL LLManipRotate::updateVisiblity()
 
 LLQuaternion LLManipRotate::dragUnconstrained( S32 x, S32 y )
 {
-	LLVector3 cam = gAgent.getCameraPositionAgent();
+	LLVector3 cam = gAgentCamera.getCameraPositionAgent();
 	LLVector3 center =  gAgent.getPosAgentFromGlobal( mRotationCenter );
 
 	mMouseCur = intersectMouseWithSphere( x, y, center, mRadiusMeters);
@@ -1333,7 +1334,7 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
 		}
 		else
 		{
-			cam_to_snap_plane = snap_plane_center - gAgent.getCameraPositionAgent();
+			cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
 			cam_to_snap_plane.normVec();
 		}
 
@@ -1383,7 +1384,7 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
 			}
 			else
 			{
-				cam_to_snap_plane = snap_plane_center - gAgent.getCameraPositionAgent();
+				cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
 				cam_to_snap_plane.normVec();
 			}
 
@@ -1430,7 +1431,7 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
 			}
 			else
 			{
-				cam_at_axis = snap_plane_center - gAgent.getCameraPositionAgent();
+				cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
 				cam_at_axis.normVec();
 			}
 
@@ -1627,15 +1628,15 @@ void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_
 {
 	if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD)
 	{
-		F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgent.mHUDCurZoom;
-		F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgent.mHUDCurZoom;
+		F32 mouse_x = (((F32)x / gViewerWindow->getWorldViewRectScaled().getWidth()) - 0.5f) / gAgentCamera.mHUDCurZoom;
+		F32 mouse_y = ((((F32)y) / gViewerWindow->getWorldViewRectScaled().getHeight()) - 0.5f) / gAgentCamera.mHUDCurZoom;
 
 		*ray_pt = LLVector3(-1.f, -mouse_x, mouse_y);
 		*ray_dir = LLVector3(1.f, 0.f, 0.f);
 	}
 	else
 	{
-		*ray_pt = gAgent.getCameraPositionAgent();
+		*ray_pt = gAgentCamera.getCameraPositionAgent();
 		LLViewerCamera::getInstance()->projectScreenToPosAgent(x, y, ray_dir);
 		*ray_dir -= *ray_pt;
 		ray_dir->normVec();
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index ee3ffa2450..63643a7fc6 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -45,6 +45,7 @@
 
 // viewer includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llbbox.h"
 #include "llbox.h"
 #include "llviewercontrol.h"
@@ -210,7 +211,7 @@ void LLManipScale::render()
 		glPushMatrix();
 		if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 		{
-			F32 zoom = gAgent.mHUDCurZoom;
+			F32 zoom = gAgentCamera.mHUDCurZoom;
 			glScalef(zoom, zoom, zoom);
 		}
 
@@ -227,11 +228,11 @@ void LLManipScale::render()
 		if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 		{
 			mBoxHandleSize = BOX_HANDLE_BASE_SIZE * BOX_HANDLE_BASE_FACTOR / (F32) LLViewerCamera::getInstance()->getViewHeightInPixels();
-			mBoxHandleSize /= gAgent.mHUDCurZoom;
+			mBoxHandleSize /= gAgentCamera.mHUDCurZoom;
 		}
 		else
 		{
-			range = dist_vec(gAgent.getCameraPositionAgent(), center_agent);
+			range = dist_vec(gAgentCamera.getCameraPositionAgent(), center_agent);
 			range_from_agent = dist_vec(gAgent.getPositionAgent(), center_agent);
 
 			// Don't draw manip if object too far away
@@ -438,7 +439,7 @@ void LLManipScale::highlightManipulators(S32 x, S32 y)
 			LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
 			transform *= cfr;
 			LLMatrix4 window_scale;
-			F32 zoom_level = 2.f * gAgent.mHUDCurZoom;
+			F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom;
 			window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f),
 				LLQuaternion::DEFAULT,
 				LLVector3::zero);
@@ -635,7 +636,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
 	}
 
 	// Find nearest vertex
-	LLVector3 orientWRTHead = bbox.agentToLocalBasis( bbox.getCenterAgent() - gAgent.getCameraPositionAgent() );
+	LLVector3 orientWRTHead = bbox.agentToLocalBasis( bbox.getCenterAgent() - gAgentCamera.getCameraPositionAgent() );
 	U32 nearest = 
 		(orientWRTHead.mV[0] < 0.0f ? 1 : 0) + 
 		(orientWRTHead.mV[1] < 0.0f ? 2 : 0) + 
@@ -825,7 +826,7 @@ void LLManipScale::drag( S32 x, S32 y )
 	}	
 
 	LLSelectMgr::getInstance()->updateSelectionCenter();
-    gAgent.clearFocusObject();
+    gAgentCamera.clearFocusObject();
 }
 
 // Scale around the 
@@ -1364,7 +1365,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
 
 	if(mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
-		mSnapRegimeOffset = SNAP_GUIDE_SCREEN_OFFSET / gAgent.mHUDCurZoom;
+		mSnapRegimeOffset = SNAP_GUIDE_SCREEN_OFFSET / gAgentCamera.mHUDCurZoom;
 
 	}
 	else
@@ -1377,7 +1378,7 @@ void LLManipScale::updateSnapGuides(const LLBBox& bbox)
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
 		cam_at_axis.setVec(1.f, 0.f, 0.f);
-		snap_guide_length = SNAP_GUIDE_SCREEN_LENGTH / gAgent.mHUDCurZoom;
+		snap_guide_length = SNAP_GUIDE_SCREEN_LENGTH / gAgentCamera.mHUDCurZoom;
 	}
 	else
 	{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 52fe31fbba..35c4f7f787 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -42,6 +42,7 @@
 #include "llrender.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llbbox.h"
 #include "llbox.h"
 #include "llviewercontrol.h"
@@ -437,12 +438,12 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 	{
 		if (x < ROTATE_H_MARGIN)
 		{
-			gAgent.cameraOrbitAround(rotate_angle);
+			gAgentCamera.cameraOrbitAround(rotate_angle);
 			rotated = TRUE;
 		}
 		else if (x > world_rect.getWidth() - ROTATE_H_MARGIN)
 		{
-			gAgent.cameraOrbitAround(-rotate_angle);
+			gAgentCamera.cameraOrbitAround(-rotate_angle);
 			rotated = TRUE;
 		}
 	}
@@ -789,7 +790,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 	}
 
 	LLSelectMgr::getInstance()->updateSelectionCenter();
-	gAgent.clearFocusObject();
+	gAgentCamera.clearFocusObject();
 	dialog_refresh_all();		// ??? is this necessary?
 
 	lldebugst(LLERR_USER_INPUT) << "hover handled by LLManipTranslate (active)" << llendl;
@@ -830,7 +831,7 @@ void LLManipTranslate::highlightManipulators(S32 x, S32 y)
 		LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
 		transform *= cfr;
 		LLMatrix4 window_scale;
-		F32 zoom_level = 2.f * gAgent.mHUDCurZoom;
+		F32 zoom_level = 2.f * gAgentCamera.mHUDCurZoom;
 		window_scale.initAll(LLVector3(zoom_level / LLViewerCamera::getInstance()->getAspect(), zoom_level, 0.f),
 			LLQuaternion::DEFAULT,
 			LLVector3::zero);
@@ -1075,7 +1076,7 @@ void LLManipTranslate::render()
 	gGL.pushMatrix();
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
-		F32 zoom = gAgent.mHUDCurZoom;
+		F32 zoom = gAgentCamera.mHUDCurZoom;
 		glScalef(zoom, zoom, zoom);
 	}
 	{
@@ -1239,7 +1240,7 @@ void LLManipTranslate::renderSnapGuides()
 
 		if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 		{
-			guide_size_meters = 1.f / gAgent.mHUDCurZoom;
+			guide_size_meters = 1.f / gAgentCamera.mHUDCurZoom;
 			mSnapOffsetMeters = mArrowLengthMeters * 1.5f;
 		}
 		else
@@ -1822,11 +1823,11 @@ void LLManipTranslate::renderTranslationHandles()
 	if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
 	{
 		mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWorldViewHeightRaw();
-		mArrowLengthMeters /= gAgent.mHUDCurZoom;
+		mArrowLengthMeters /= gAgentCamera.mHUDCurZoom;
 	}
 	else
 	{
-		LLVector3 camera_pos_agent = gAgent.getCameraPositionAgent();
+		LLVector3 camera_pos_agent = gAgentCamera.getCameraPositionAgent();
 		F32 range = dist_vec(camera_pos_agent, selection_center);
 		F32 range_from_agent = dist_vec(gAgent.getPositionAgent(), selection_center);
 		
@@ -2108,7 +2109,7 @@ void LLManipTranslate::renderTranslationHandles()
 
 			// Copied from LLDrawable::updateGeometry
 			LLVector3 pos_agent     = first_object->getPositionAgent();
-			LLVector3 camera_agent	= gAgent.getCameraPositionAgent();
+			LLVector3 camera_agent	= gAgentCamera.getCameraPositionAgent();
 			LLVector3 headPos		= pos_agent - camera_agent;
 
 			LLVector3 orientWRTHead    = headPos * invRotation;
@@ -2150,7 +2151,7 @@ void LLManipTranslate::renderTranslationHandles()
 			}
 			else
 			{
-				camera_axis.setVec(gAgent.getCameraPositionAgent() - first_object->getPositionAgent());
+				camera_axis.setVec(gAgentCamera.getCameraPositionAgent() - first_object->getPositionAgent());
 			}
 
 			for (U32 i = 0; i < NUM_AXES*2; i++)
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index 8d950f072d..e6ca0dabda 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -42,7 +42,7 @@
 #include "llstring.h"
 #include "message.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llcallingcard.h"
 #include "llviewercontrol.h"
 //#include "llfirstuse.h"
@@ -66,7 +66,7 @@
 
 void handle_mouselook(void*)
 {
-	gAgent.changeCameraToMouselook();
+	gAgentCamera.changeCameraToMouselook();
 }
 
 
diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp
index b95e8bd3a2..47234eb773 100644
--- a/indra/newview/llmorphview.cpp
+++ b/indra/newview/llmorphview.cpp
@@ -37,6 +37,7 @@
 #include "lljoint.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "lldrawable.h"
 #include "lldrawpoolavatar.h"
 #include "llface.h"
@@ -91,7 +92,7 @@ void	LLMorphView::initialize()
 	LLVOAvatar *avatarp = gAgent.getAvatarObject();
 	if (!avatarp || avatarp->isDead())
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 		return;
 	}
 
@@ -187,7 +188,7 @@ void LLMorphView::updateCamera()
 
 	LLVector3d camera_pos = joint_pos + mCameraOffset * camera_rot_pitch * camera_rot_yaw * avatar_rot;
 
-	gAgent.setCameraPosAndFocusGlobal( camera_pos, target_pos, gAgent.getID() );
+	gAgentCamera.setCameraPosAndFocusGlobal( camera_pos, target_pos, gAgent.getID() );
 }
 
 void LLMorphView::setCameraDrivenByKeys(BOOL b)
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 1853b511be..58fac14349 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -41,6 +41,7 @@
 // Viewer includes
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llvoavatarself.h" // to check gAgent.getAvatarObject()->isSitting()
 #include "llbottomtray.h"
 #include "llbutton.h"
@@ -593,7 +594,7 @@ BOOL LLPanelStandStopFlying::postBuild()
 void LLPanelStandStopFlying::setVisible(BOOL visible)
 {
 	//we dont need to show the panel if these buttons are not activated
-	if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false;
+	if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) visible = false;
 
 	if (visible)
 	{
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 05623198ab..a8dee8a24a 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -49,6 +49,7 @@
 
 // Viewer includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llappviewer.h" // for gDisconnected
 #include "llcallingcard.h" // LLAvatarTracker
 #include "lltracker.h"
@@ -87,7 +88,7 @@ LLNetMap::LLNetMap (const Params & p)
 	mCurPanX(0.f),
 	mCurPanY(0.f),
 	mUpdateNow(FALSE),
-	mObjectImageCenterGlobal( gAgent.getCameraPositionGlobal() ),
+	mObjectImageCenterGlobal( gAgentCamera.getCameraPositionGlobal() ),
 	mObjectRawImagep(),
 	mObjectImagep(),
 	mClosestAgentToCursor(),
@@ -203,7 +204,7 @@ void LLNetMap::draw()
 			LLViewerRegion* regionp = *iter;
 			// Find x and y position relative to camera's center.
 			LLVector3 origin_agent = regionp->getOriginAgent();
-			LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent();
+			LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
 			F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
 			F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
 
@@ -264,7 +265,7 @@ void LLNetMap::draw()
 		
 
 		LLVector3d old_center = mObjectImageCenterGlobal;
-		LLVector3d new_center = gAgent.getCameraPositionGlobal();
+		LLVector3d new_center = gAgentCamera.getCameraPositionGlobal();
 
 		new_center.mdV[0] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[0]);
 		new_center.mdV[1] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[1]);
@@ -289,7 +290,7 @@ void LLNetMap::draw()
 		}
 
 		LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
-		map_center_agent -= gAgent.getCameraPositionAgent();
+		map_center_agent -= gAgentCamera.getCameraPositionAgent();
 		map_center_agent.mV[VX] *= mScale/region_width;
 		map_center_agent.mV[VY] *= mScale/region_width;
 
@@ -461,7 +462,7 @@ void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent)
 
 LLVector3 LLNetMap::globalPosToView( const LLVector3d& global_pos )
 {
-	LLVector3d relative_pos_global = global_pos - gAgent.getCameraPositionGlobal();
+	LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal();
 	LLVector3 pos_local;
 	pos_local.setVec(relative_pos_global);  // convert to floats from doubles
 
@@ -529,7 +530,7 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
 	
 	LLVector3d pos_global;
 	pos_global.setVec( pos_local );
-	pos_global += gAgent.getCameraPositionGlobal();
+	pos_global += gAgentCamera.getCameraPositionGlobal();
 
 	return pos_global;
 }
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index 3504cbd1ef..35acf8edcc 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -36,6 +36,7 @@
 #include "llavatarconstants.h"
 #include "llpanelme.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "lliconctrl.h"
 #include "llsidetray.h"
@@ -144,7 +145,7 @@ void LLPanelMe::onEditAppearanceClicked()
 {
 	if (gAgentWearables.areWearablesLoaded())
 	{
-		gAgent.changeCameraToCustomizeAvatar();
+		gAgentCamera.changeCameraToCustomizeAvatar();
 	}
 }
 
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index a53a3ba1ad..a9ec01f33a 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -32,7 +32,7 @@
 #include "llviewerprecompiledheaders.h"
 
 //LLPanelPrimMediaControls
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llparcel.h"
 #include "llpanel.h"
 #include "llselectmgr.h"
@@ -1010,7 +1010,7 @@ void LLPanelPrimMediaControls::updateZoom()
 	{
 	case ZOOM_NONE:
 		{
-			gAgent.setFocusOnAvatar(TRUE, ANIMATE);
+			gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
 			break;
 		}
 	case ZOOM_FAR:
@@ -1030,7 +1030,7 @@ void LLPanelPrimMediaControls::updateZoom()
 		}
 	default:
 		{
-			gAgent.setFocusOnAvatar(TRUE, ANIMATE);
+			gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
 			break;
 		}
 	}
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index d733574a9d..8a311beb7a 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -56,6 +56,7 @@
 
 // viewer includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewerwindow.h"
 #include "lldrawable.h"
 #include "llfloaterinspect.h"
@@ -2872,7 +2873,7 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response,
 				effectp->setDuration(duration);
 			}
 
-			gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
+			gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
 
 			// Keep track of how many objects have been deleted.
 			F64 obj_delete_count = LLViewerStats::getInstance()->getStat(LLViewerStats::ST_OBJECT_DELETE_COUNT);
@@ -4626,8 +4627,8 @@ void LLSelectMgr::updateSilhouettes()
 {
 	S32 num_sils_genned = 0;
 
-	LLVector3d	cameraPos = gAgent.getCameraPositionGlobal();
-	F32 currentCameraZoom = gAgent.getCurrentCameraBuildOffset();
+	LLVector3d	cameraPos = gAgentCamera.getCameraPositionGlobal();
+	F32 currentCameraZoom = gAgentCamera.getCurrentCameraBuildOffset();
 
 	if (!mSilhouetteImagep)
 	{
@@ -4648,7 +4649,7 @@ void LLSelectMgr::updateSilhouettes()
 		} func;
 		getSelection()->applyToObjects(&func);	
 		
-		mLastCameraPos = gAgent.getCameraPositionGlobal();
+		mLastCameraPos = gAgentCamera.getCameraPositionGlobal();
 	}
 	
 	std::vector<LLViewerObject*> changed_objects;
@@ -4915,7 +4916,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
 	{
 		LLBBox hud_bbox = avatar->getHUDBBox();
 
-		F32 cur_zoom = gAgent.mHUDCurZoom;
+		F32 cur_zoom = gAgentCamera.mHUDCurZoom;
 
 		// set up transform to encompass bounding box of HUD
 		glMatrixMode(GL_PROJECTION);
@@ -5399,7 +5400,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
 		F32 silhouette_thickness;
 		if (is_hud_object && gAgent.getAvatarObject())
 		{
-			silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgent.mHUDCurZoom;
+			silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgentCamera.mHUDCurZoom;
 		}
 		else
 		{
@@ -5419,7 +5420,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
 			LLGLEnable fog(GL_FOG);
 			glFogi(GL_FOG_MODE, GL_LINEAR);
 			float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
-			LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgent.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
+			LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
 			glFogf(GL_FOG_START, d);
 			glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
 			glFogfv(GL_FOG_COLOR, fogCol.mV);
@@ -5620,8 +5621,8 @@ void LLSelectMgr::updateSelectionCenter()
 		if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && gAgent.getAvatarObject())
 		{
 			// reset hud ZOOM
-			gAgent.mHUDTargetZoom = 1.f;
-			gAgent.mHUDCurZoom = 1.f;
+			gAgentCamera.mHUDTargetZoom = 1.f;
+			gAgentCamera.mHUDCurZoom = 1.f;
 		}
 
 		mShowSelection = FALSE;
@@ -5713,26 +5714,26 @@ void LLSelectMgr::updatePointAt()
 				select_offset.setVec(pick.mObjectOffset);
 				select_offset.rotVec(~click_object->getRenderRotation());
 		
-				gAgent.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset);
-				gAgent.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset);
+				gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, click_object, select_offset);
+				gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, click_object, select_offset);
 			}
 			else
 			{
 				// didn't click on an object this time, revert to pointing at center of first object
-				gAgent.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
-				gAgent.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
+				gAgentCamera.setPointAt(POINTAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
+				gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, mSelectedObjects->getFirstObject());
 			}
 		}
 		else
 		{
-			gAgent.setPointAt(POINTAT_TARGET_CLEAR);
-			gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
+			gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
+			gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
 		}
 	}
 	else
 	{
-		gAgent.setPointAt(POINTAT_TARGET_CLEAR);
-		gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
+		gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
+		gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
 	}
 }
 
@@ -5922,20 +5923,20 @@ BOOL LLSelectMgr::setForceSelection(BOOL force)
 
 void LLSelectMgr::resetAgentHUDZoom()
 {
-	gAgent.mHUDTargetZoom = 1.f;
-	gAgent.mHUDCurZoom = 1.f;
+	gAgentCamera.mHUDTargetZoom = 1.f;
+	gAgentCamera.mHUDCurZoom = 1.f;
 }
 
 void LLSelectMgr::getAgentHUDZoom(F32 &target_zoom, F32 &current_zoom) const
 {
-	target_zoom = gAgent.mHUDTargetZoom;
-	current_zoom = gAgent.mHUDCurZoom;
+	target_zoom = gAgentCamera.mHUDTargetZoom;
+	current_zoom = gAgentCamera.mHUDCurZoom;
 }
 
 void LLSelectMgr::setAgentHUDZoom(F32 target_zoom, F32 current_zoom)
 {
-	gAgent.mHUDTargetZoom = target_zoom;
-	gAgent.mHUDCurZoom = current_zoom;
+	gAgentCamera.mHUDTargetZoom = target_zoom;
+	gAgentCamera.mHUDCurZoom = current_zoom;
 }
 
 /////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 4a24a5dec5..6876079720 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -34,6 +34,7 @@
 
 #include "llaccordionctrltab.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
 #include "llinventorypanel.h"
@@ -234,7 +235,7 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()
 {
 	if (gAgentWearables.areWearablesLoaded())
 	{
-		gAgent.changeCameraToCustomizeAvatar();
+		gAgentCamera.changeCameraToCustomizeAvatar();
 	}
 }
 
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index fba1503b4a..3ec1855484 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -34,7 +34,7 @@
 
 #include "lltextbox.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llbottomtray.h"
 #include "llsidetray.h"
 #include "llviewerwindow.h"
@@ -730,7 +730,7 @@ void	LLSideTray::updateSidetrayVisibility()
 	// set visibility of parent container based on collapsed state
 	if (getParent())
 	{
-		getParent()->setVisible(!mCollapsed && !gAgent.cameraMouselook());
+		getParent()->setVisible(!mCollapsed && !gAgentCamera.cameraMouselook());
 	}
 }
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index d4d6a74f0c..559cd624f7 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -88,6 +88,7 @@
 #include "v3math.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentpicksinfo.h"
 #include "llagentwearables.h"
 #include "llagentpilot.h"
@@ -1134,6 +1135,7 @@ bool idle_startup()
 
 		// Finish agent initialization.  (Requires gSavedSettings, builds camera)
 		gAgent.init();
+		gAgentCamera.init();
 		set_underclothes_menu_options();
 
 		// Since we connected, save off the settings so the user doesn't have to
@@ -1336,8 +1338,8 @@ bool idle_startup()
 
 		gAgent.setPositionAgent(agent_start_position_region);
 		gAgent.resetAxes(gAgentStartLookAt);
-		gAgent.stopCameraAnimation();
-		gAgent.resetCamera();
+		gAgentCamera.stopCameraAnimation();
+		gAgentCamera.resetCamera();
 
 		// Initialize global class data needed for surfaces (i.e. textures)
 		if (!gNoRender)
@@ -1810,15 +1812,15 @@ bool idle_startup()
 				if (samename)
 				{
 					// restore old camera pos
-					gAgent.setFocusOnAvatar(FALSE, FALSE);
-					gAgent.setCameraPosAndFocusGlobal(gSavedSettings.getVector3d("CameraPosOnLogout"), gSavedSettings.getVector3d("FocusPosOnLogout"), LLUUID::null);
+					gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
+					gAgentCamera.setCameraPosAndFocusGlobal(gSavedSettings.getVector3d("CameraPosOnLogout"), gSavedSettings.getVector3d("FocusPosOnLogout"), LLUUID::null);
 					BOOL limit_hit = FALSE;
-					gAgent.calcCameraPositionTargetGlobal(&limit_hit);
+					gAgentCamera.calcCameraPositionTargetGlobal(&limit_hit);
 					if (limit_hit)
 					{
-						gAgent.setFocusOnAvatar(TRUE, FALSE);
+						gAgentCamera.setFocusOnAvatar(TRUE, FALSE);
 					}
-					gAgent.stopCameraAnimation();
+					gAgentCamera.stopCameraAnimation();
 				}
 			}
 			else
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 9206b4a43a..3052134d4f 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -36,6 +36,7 @@
 
 // viewer includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llbutton.h"
 #include "llcommandhandler.h"
 #include "llviewercontrol.h"
@@ -313,7 +314,7 @@ void LLStatusBar::refresh()
 		childSetVisible("scriptout", false);
 	}
 
-	if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK &&
+	if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK &&
 		((region && region->getAllowDamage()) || (parcel && parcel->getAllowDamage())))
 	{
 		// set visibility based on flashing
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index 1d479bac8c..ddb5d08e07 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -44,6 +44,7 @@
 #include "llviewerobjectlist.h"
 #include "llregionhandle.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llappviewer.h"
 #include "llworld.h"
 #include "llviewercontrol.h"
@@ -606,7 +607,7 @@ void LLSurface::moveZ(const S32 x, const S32 y, const F32 delta)
 
 void LLSurface::updatePatchVisibilities(LLAgent &agent) 
 {
-	LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgent.getCameraPositionGlobal());
+	LLVector3 pos_region = mRegionp->getPosRegionFromGlobal(gAgentCamera.getCameraPositionGlobal());
 
 	LLSurfacePatch *patchp;
 	
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp
index d55468841d..5e5d344461 100644
--- a/indra/newview/lltexlayerparams.cpp
+++ b/indra/newview/lltexlayerparams.cpp
@@ -33,7 +33,7 @@
 
 #include "lltexlayerparams.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llimagetga.h"
 #include "lltexlayer.h"
 #include "llvoavatarself.h"
@@ -180,7 +180,7 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
 
 		if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
 		{
-			if (gAgent.cameraCustomizeAvatar())
+			if (gAgentCamera.cameraCustomizeAvatar())
 			{
 				upload_bake = FALSE;
 			}
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index fff18df442..d05bfc53e5 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -54,6 +54,7 @@
 #include "llviewerobject.h"
 #include "llviewerwindow.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llfloatertools.h"
 #include "llviewercontrol.h"
 
@@ -784,7 +785,7 @@ BOOL LLToolCompGun::handleScrollWheel(S32 x, S32 y, S32 clicks)
 {
 	if (clicks > 0)
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 
 	}
 	return TRUE;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 125c62474e..442c779dc7 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -37,6 +37,7 @@
 #include "llnotificationsutil.h"
 // project headers
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentui.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
@@ -959,7 +960,7 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info)
 	gViewerWindow->getWindow()->setCursor( cursor );
 
 	mLastHitPos = pick_info.mPosGlobal;
-	mLastCameraPos = gAgent.getCameraPositionGlobal();
+	mLastCameraPos = gAgentCamera.getCameraPositionGlobal();
 }
 
 // static
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index 2320ae57df..1e2e7095d8 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -42,6 +42,7 @@
 
 // Viewer includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llbutton.h"
 #include "llviewercontrol.h"
 #include "lldrawable.h"
@@ -167,7 +168,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 		}
 	}
 
-	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
+	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
 	{
 		BOOL good_customize_avatar_hit = FALSE;
 		if( hit_obj )
@@ -207,19 +208,19 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 			// ...clicked on a world object, so focus at its position
 			if (!hit_obj->isHUDAttachment())
 			{
-				gAgent.setFocusOnAvatar(FALSE, ANIMATE);
-				gAgent.setFocusGlobal(pick_info);
+				gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+				gAgentCamera.setFocusGlobal(pick_info);
 			}
 		}
 		else if (!pick_info.mPosGlobal.isExactlyZero())
 		{
 			// Hit the ground
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
-			gAgent.setFocusGlobal(pick_info);
+			gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+			gAgentCamera.setFocusGlobal(pick_info);
 		}
 
 		if (!(pick_info.mKeyMask & MASK_ALT) &&
-			gAgent.cameraThirdPerson() &&
+			gAgentCamera.cameraThirdPerson() &&
 			gViewerWindow->getLeftMouseDown() && 
 			!gSavedSettings.getBOOL("FreezeTime") &&
 			(hit_obj == gAgent.getAvatarObject() || 
@@ -232,14 +233,14 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 
 	LLToolCamera::getInstance()->mValidClickPoint = TRUE;
 
-	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
+	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
 	{
-		gAgent.setFocusOnAvatar(FALSE, FALSE);
+		gAgentCamera.setFocusOnAvatar(FALSE, FALSE);
 		
-		LLVector3d cam_pos = gAgent.getCameraPositionGlobal();
-		cam_pos -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * gAgent.calcCustomizeAvatarUIOffset( cam_pos ));
+		LLVector3d cam_pos = gAgentCamera.getCameraPositionGlobal();
+		cam_pos -= LLVector3d(LLViewerCamera::getInstance()->getLeftAxis() * gAgentCamera.calcCustomizeAvatarUIOffset( cam_pos ));
 
-		gAgent.setCameraPosAndFocusGlobal( cam_pos, pick_info.mPosGlobal, pick_info.mObjectID);
+		gAgentCamera.setCameraPosAndFocusGlobal( cam_pos, pick_info.mPosGlobal, pick_info.mObjectID);
 	}
 }
 
@@ -280,10 +281,10 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
 	{
 		if (mValidClickPoint)
 		{
-			if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
+			if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
 			{
 				LLCoordGL mouse_pos;
-				LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgent.getFocusGlobal());
+				LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal());
 				BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
 				if (success)
 				{
@@ -369,12 +370,12 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 
 				if (dx != 0)
 				{
-					gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
+					gAgentCamera.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
 				}
 
 				if (dy != 0)
 				{
-					gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
+					gAgentCamera.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
 				}
 
 				gViewerWindow->moveCursorToCenter();
@@ -388,8 +389,8 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 			// Pan tool
 			if (hasMouseCapture())
 			{
-				LLVector3d camera_to_focus = gAgent.getCameraPositionGlobal();
-				camera_to_focus -= gAgent.getFocusGlobal();
+				LLVector3d camera_to_focus = gAgentCamera.getCameraPositionGlobal();
+				camera_to_focus -= gAgentCamera.getFocusGlobal();
 				F32 dist = (F32) camera_to_focus.normVec();
 
 				// Fudge factor for pan
@@ -397,12 +398,12 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 
 				if (dx != 0)
 				{
-					gAgent.cameraPanLeft( dx * meters_per_pixel );
+					gAgentCamera.cameraPanLeft( dx * meters_per_pixel );
 				}
 
 				if (dy != 0)
 				{
-					gAgent.cameraPanUp( -dy * meters_per_pixel );
+					gAgentCamera.cameraPanUp( -dy * meters_per_pixel );
 				}
 
 				gViewerWindow->moveCursorToCenter();
@@ -419,7 +420,7 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 
 				if (dx != 0)
 				{
-					gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
+					gAgentCamera.cameraOrbitAround( -dx * RADIANS_PER_PIXEL );
 				}
 
 				const F32 IN_FACTOR = 0.99f;
@@ -428,11 +429,11 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 				{
 					if (mMouseSteering)
 					{
-						gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
+						gAgentCamera.cameraOrbitOver( -dy * RADIANS_PER_PIXEL );
 					}
 					else
 					{
-						gAgent.cameraZoomIn( pow( IN_FACTOR, dy ) );
+						gAgentCamera.cameraZoomIn( pow( IN_FACTOR, dy ) );
 					}
 				}
 
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index d837a334f1..008cf16f2e 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -46,6 +46,7 @@
 
 // newview headers
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "lldrawable.h"
 #include "llfloatertools.h"
 #include "llhudeffect.h"
@@ -225,7 +226,7 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
 			// non-touchable objects.  If it has a touch handler, we
 			// do grab it (so llDetectedGrab works), but movement is
 			// blocked on the server side. JC
-			if (gAgent.cameraMouselook())
+			if (gAgentCamera.cameraMouselook())
 			{
 				mMode = GRAB_LOCKED;
 			}
@@ -285,8 +286,8 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
 		LLVector3 local_edit_point = gAgent.getPosAgentFromGlobal(info.mPosGlobal);
 		local_edit_point -= edit_object->getPositionAgent();
 		local_edit_point = local_edit_point * ~edit_object->getRenderRotation();
-		gAgent.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point );
-		gAgent.setLookAt(LOOKAT_TARGET_SELECT, edit_object, local_edit_point );
+		gAgentCamera.setPointAt(POINTAT_TARGET_GRAB, edit_object, local_edit_point );
+		gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, edit_object, local_edit_point );
 	}
 
 	// on transient grabs (clicks on world objects), kill the grab immediately
@@ -390,7 +391,7 @@ void LLToolGrab::startGrab()
 
 	// This planar drag starts at the grab point
 	mDragStartPointGlobal = grab_start_global;
-	mDragStartFromCamera = grab_start_global - gAgent.getCameraPositionGlobal();
+	mDragStartFromCamera = grab_start_global - gAgentCamera.getCameraPositionGlobal();
 
 	LLMessageSystem	*msg = gMessageSystem;
 	msg->newMessageFast(_PREHASH_ObjectGrab);
@@ -502,7 +503,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
 		mVerticalDragging = FALSE;
 
 		mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);
-		mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
+		mDragStartFromCamera = mDragStartPointGlobal - gAgentCamera.getCameraPositionGlobal();
 	}
 	else if (!mVerticalDragging && (mask == MASK_VERTICAL) )
 	{
@@ -510,7 +511,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
 		mVerticalDragging = TRUE;
 
 		mDragStartPointGlobal = gViewerWindow->clickPointInWorldGlobal(x, y, objectp);
-		mDragStartFromCamera = mDragStartPointGlobal - gAgent.getCameraPositionGlobal();
+		mDragStartFromCamera = mDragStartPointGlobal - gAgentCamera.getCameraPositionGlobal();
 	}
 
 	const F32 RADIANS_PER_PIXEL_X = 0.01f;
@@ -598,7 +599,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
 			// need to return offset from mGrabStartPoint
 			LLVector3d grab_point_global;
 
-			grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
+			grab_point_global = gAgentCamera.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
 
 			/* Snap to grid disabled for grab tool - very confusing
 			// Handle snapping to grid, but only when the tool is formally selected.
@@ -632,7 +633,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
 
 			grab_point_global = LLWorld::getInstance()->clipToVisibleRegions(mDragStartPointGlobal, grab_point_global);
 			// propagate constrained grab point back to grab offset
-			mGrabHiddenOffsetFromCamera = grab_point_global - gAgent.getCameraPositionGlobal();
+			mGrabHiddenOffsetFromCamera = grab_point_global - gAgentCamera.getCameraPositionGlobal();
 
 			// Handle auto-rotation at screen edge.
 			LLVector3 grab_pos_agent = gAgent.getPosAgentFromGlobal( grab_point_global );
@@ -646,24 +647,24 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
 			// ...build mode moves camera about focus point
 			if (grab_center_gl.mX < ROTATE_H_MARGIN)
 			{
-				if (gAgent.getFocusOnAvatar())
+				if (gAgentCamera.getFocusOnAvatar())
 				{
 					gAgent.yaw(rotate_angle);
 				}
 				else
 				{
-					gAgent.cameraOrbitAround(rotate_angle);
+					gAgentCamera.cameraOrbitAround(rotate_angle);
 				}
 			}
 			else if (grab_center_gl.mX > gViewerWindow->getWorldViewWidthScaled() - ROTATE_H_MARGIN)
 			{
-				if (gAgent.getFocusOnAvatar())
+				if (gAgentCamera.getFocusOnAvatar())
 				{
 					gAgent.yaw(-rotate_angle);
 				}
 				else
 				{
-					gAgent.cameraOrbitAround(-rotate_angle);
+					gAgentCamera.cameraOrbitAround(-rotate_angle);
 				}
 			}
 
@@ -705,17 +706,17 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
 	// once we've initiated a drag, lock the camera down
 	if (mHasMoved)
 	{
-		if (!gAgent.cameraMouselook() && 
+		if (!gAgentCamera.cameraMouselook() && 
 			!objectp->isHUDAttachment() && 
 			objectp->getRoot() == gAgent.getAvatarObject()->getRoot())
 		{
 			// force focus to point in space where we were looking previously
-			gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null);
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+			gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+			gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
 		}
 		else
 		{
-			gAgent.clearFocusObject();
+			gAgentCamera.clearFocusObject();
 		}
 	}
 
@@ -814,7 +815,7 @@ void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask)
 		}
 		
 		// need to return offset from mGrabStartPoint
-		LLVector3d grab_point_global = gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
+		LLVector3d grab_point_global = gAgentCamera.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
 		grab_pos_region = objectp->getRegion()->getPosRegionFromGlobal( grab_point_global );
 	}
 
@@ -872,8 +873,8 @@ void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask)
 		LLVector3 local_edit_point = pick.mIntersection;
 		local_edit_point -= objectp->getPositionAgent();
 		local_edit_point = local_edit_point * ~objectp->getRenderRotation();
-		gAgent.setPointAt(POINTAT_TARGET_GRAB, objectp, local_edit_point );
-		gAgent.setLookAt(LOOKAT_TARGET_SELECT, objectp, local_edit_point );
+		gAgentCamera.setPointAt(POINTAT_TARGET_GRAB, objectp, local_edit_point );
+		gAgentCamera.setLookAt(LOOKAT_TARGET_SELECT, objectp, local_edit_point );
 	}
 	
 	
@@ -892,7 +893,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
 	// Only works in fullscreen
 	if (gSavedSettings.getBOOL("WindowFullScreen"))
 	{
-		if (gAgent.cameraThirdPerson() )
+		if (gAgentCamera.cameraThirdPerson() )
 		{
 			if (x == 0)
 			{
@@ -994,7 +995,7 @@ void LLToolGrab::onMouseCaptureLost()
 		return;
 	}
 	// First, fix cursor placement
-	if( !gAgent.cameraMouselook() 
+	if( !gAgentCamera.cameraMouselook() 
 		&& (GRAB_ACTIVE_CENTER == mMode))
 	{
 		if (objectp->isHUDAttachment())
@@ -1035,8 +1036,8 @@ void LLToolGrab::onMouseCaptureLost()
 	mGrabPick.mObjectID.setNull();
 
 	LLSelectMgr::getInstance()->updateSelectionCenter();
-	gAgent.setPointAt(POINTAT_TARGET_CLEAR);
-	gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
+	gAgentCamera.setPointAt(POINTAT_TARGET_CLEAR);
+	gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
 
 	dialog_refresh_all();
 }
@@ -1128,7 +1129,7 @@ LLVector3d LLToolGrab::getGrabPointGlobal()
 	case GRAB_ACTIVE_CENTER:
 	case GRAB_NONPHYSICAL:
 	case GRAB_LOCKED:
-		return gAgent.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
+		return gAgentCamera.getCameraPositionGlobal() + mGrabHiddenOffsetFromCamera;
 
 	case GRAB_NOOBJECT:
 	case GRAB_INACTIVE:
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index a441d653c7..c815f1e96a 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -36,6 +36,7 @@
 
 #include "llviewerwindow.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "llsky.h"
 #include "llappviewer.h"
@@ -83,7 +84,7 @@ BOOL LLToolGun::handleMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLToolGun::handleHover(S32 x, S32 y, MASK mask) 
 {
-	if( gAgent.cameraMouselook() && mIsSelected )
+	if( gAgentCamera.cameraMouselook() && mIsSelected )
 	{
 		const F32 NOMINAL_MOUSE_SENSITIVITY = 0.0025f;
 
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index fd12163fd3..a8696c22ef 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -56,6 +56,7 @@
 #include "lltoolobjpicker.h"
 #include "lltoolpipette.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "llviewerjoystick.h"
 #include "llviewermenu.h"
@@ -262,7 +263,7 @@ void LLToolMgr::toggleBuildMode()
 		else
 		{
 			// manually disable edit mode, but do not affect the camera
-			gAgent.resetView(false);
+			gAgentCamera.resetView(false);
 			LLFloaterReg::hideInstance("build");
 			gViewerWindow->showCursor();			
 		}
@@ -271,7 +272,7 @@ void LLToolMgr::toggleBuildMode()
 	}
 	else
 	{
-		ECameraMode camMode = gAgent.getCameraMode();
+		ECameraMode camMode = gAgentCamera.getCameraMode();
 		if (CAMERA_MODE_MOUSELOOK == camMode ||	CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
 		{
 			// pull the user out of mouselook or appearance mode when entering build mode
@@ -286,13 +287,13 @@ void LLToolMgr::toggleBuildMode()
 				handle_toggle_flycam();
 			}
 
-			if (gAgent.getFocusOnAvatar())
+			if (gAgentCamera.getFocusOnAvatar())
 			{
 				// zoom in if we're looking at the avatar
-				gAgent.setFocusOnAvatar(FALSE, ANIMATE);
-				gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
-				gAgent.cameraZoomIn(0.666f);
-				gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
+				gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+				gAgentCamera.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
+				gAgentCamera.cameraZoomIn(0.666f);
+				gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
 			}
 		}
 
@@ -303,7 +304,7 @@ void LLToolMgr::toggleBuildMode()
 		// Could be first use
 		//LLFirstUse::useBuild();
 
-		gAgent.resetView(false);
+		gAgentCamera.resetView(false);
 
 		// avoid spurious avatar movements
 		LLViewerJoystick::getInstance()->setNeedsReset();
@@ -317,7 +318,7 @@ bool LLToolMgr::inBuildMode()
 	// cameraMouselook() actually starts returning true.  Also, appearance edit
 	// sets build mode to true, so let's exclude that.
 	bool b=(inEdit() 
-			&& !gAgent.cameraMouselook()
+			&& !gAgentCamera.cameraMouselook()
 			&& mCurrentToolset != gFaceEditToolset);
 	
 	return b;
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 2f4a69a53c..2081f39c99 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -39,6 +39,7 @@
 #include "llparcel.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "llfocusmgr.h"
 //#include "llfirstuse.h"
@@ -263,7 +264,7 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
 				
 				if (object)
 				{
-					gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+					gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
 					
 					LLBBox bbox = object->getBoundingBoxAgent() ;
 					F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
@@ -273,7 +274,7 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
 					obj_to_cam.normVec();
 					
 					LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
-					gAgent.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), 
+					gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), 
 													  object_center_global, 
 													  mPick.mObjectID );
 				}
@@ -336,7 +337,7 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
 			gViewerWindow->hideCursor();
 			LLToolCamera::getInstance()->setMouseCapture(TRUE);
 			LLToolCamera::getInstance()->pickCallback(mPick);
-			gAgent.setFocusOnAvatar(TRUE, TRUE);
+			gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
 
 			return TRUE;
 		}
@@ -592,7 +593,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
 
 	mGrabMouseButtonDown = FALSE;
 	LLToolMgr::getInstance()->clearTransientTool();
-	gAgent.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
+	gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
 	return LLTool::handleMouseUp(x, y, mask);
 }
 
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 612bcc03bd..b10ee590e0 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -56,6 +56,7 @@
 #include "llvolumemessage.h"
 #include "llhudmanager.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llaudioengine.h"
 #include "llhudeffecttrail.h"
 #include "llviewerobjectlist.h"
@@ -120,7 +121,7 @@ BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj,
 	}
 
 	// Make sure the surface isn't too far away.
-	LLVector3d ray_start_global = gAgent.getCameraPositionGlobal();
+	LLVector3d ray_start_global = gAgentCamera.getCameraPositionGlobal();
 	F32 dist_to_surface_sq = (F32)((surface_pos_global - ray_start_global).magVecSquared());
 	if( dist_to_surface_sq > (max_dist_from_camera * max_dist_from_camera) )
 	{
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 97e2865179..6e0c6663e9 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -35,6 +35,7 @@
 #include "lltoolselect.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "lldrawable.h"
 #include "llmanip.h"
@@ -167,7 +168,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
 			LLSelectMgr::getInstance()->setAgentHUDZoom(target_zoom, current_zoom);
 		}
 
-		if (!gAgent.getFocusOnAvatar() &&										// if camera not glued to avatar
+		if (!gAgentCamera.getFocusOnAvatar() &&										// if camera not glued to avatar
 			LLVOAvatar::findAvatarFromAttachment(object) != gAgent.getAvatarObject() &&	// and it's not one of your attachments
 			object != gAgent.getAvatarObject())									// and it's not you
 		{
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index 407cc23d0d..9a69adae31 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -50,6 +50,7 @@
 #include "llappviewer.h"
 #include "lltracker.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llcallingcard.h"
 #include "llfloaterworldmap.h"
 #include "llhudtext.h"
@@ -480,14 +481,14 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
 							 const std::string& label )
 {
 	sCheesyBeacon = gSavedSettings.getBOOL("CheesyBeacon");
-	LLVector3d to_vec = pos_global - gAgent.getCameraPositionGlobal();
+	LLVector3d to_vec = pos_global - gAgentCamera.getCameraPositionGlobal();
 
 	F32 dist = (F32)to_vec.magVec();
 	F32 color_frac = 1.f;
 	if (dist > 0.99f * LLViewerCamera::getInstance()->getFar())
 	{
 		color_frac = 0.4f;
-	//	pos_global = gAgent.getCameraPositionGlobal() + 0.99f*(LLViewerCamera::getInstance()->getFar()/dist)*to_vec;
+	//	pos_global = gAgentCamera.getCameraPositionGlobal() + 0.99f*(LLViewerCamera::getInstance()->getFar()/dist)*to_vec;
 	}
 	else
 	{
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index 1d935f5ab8..2661c9f32b 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -34,6 +34,7 @@
 
 #include "llaudioengine.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llappviewer.h"
 #include "llvieweraudio.h"
 #include "llviewercamera.h"
@@ -51,7 +52,7 @@ void init_audio()
 		llwarns << "Failed to create an appropriate Audio Engine" << llendl;
 		return;
 	}
-	LLVector3d lpos_global = gAgent.getCameraPositionGlobal();
+	LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal();
 	LLVector3 lpos_global_f;
 
 	lpos_global_f.setVec(lpos_global);
@@ -180,7 +181,7 @@ void audio_update_listener()
 	if (gAudiop)
 	{
 		// update listener position because agent has moved	
-		LLVector3d lpos_global = gAgent.getCameraPositionGlobal();		
+		LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal();		
 		LLVector3 lpos_global_f;
 		lpos_global_f.setVec(lpos_global);
 	
@@ -203,7 +204,7 @@ void audio_update_wind(bool force_update)
 	if (region)
 	{
 		static F32 last_camera_water_height = -1000.f;
-		LLVector3 camera_pos = gAgent.getCameraPositionAgent();
+		LLVector3 camera_pos = gAgentCamera.getCameraPositionAgent();
 		F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight();
 		
 		//
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 6c1c1d1096..17816bc818 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -38,6 +38,7 @@
 #include "llrender.h"
 #include "llglheaders.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "llcoord.h"
 #include "llcriticaldamp.h"
@@ -175,7 +176,7 @@ void display_update_camera()
 	// Cut draw distance in half when customizing avatar,
 	// but on the viewer only.
 	F32 final_far = gAgent.mDrawDistance;
-	if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode())
+	if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
 	{
 		final_far *= 0.5f;
 	}
@@ -393,7 +394,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			gAgent.setTeleportMessage(
 				LLAgent::sTeleportProgressMessages["arriving"]);
 			gTextureList.mForceResetTextureStats = TRUE;
-			gAgent.resetView(TRUE, TRUE);
+			gAgentCamera.resetView(TRUE, TRUE);
 			break;
 
 		case LLAgent::TELEPORT_ARRIVING:
@@ -920,9 +921,9 @@ void render_hud_attachments()
 	glh::matrix4f current_mod = glh_get_current_modelview();
 
 	// clamp target zoom level to reasonable values
-	gAgent.mHUDTargetZoom = llclamp(gAgent.mHUDTargetZoom, 0.1f, 1.f);
+	gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, 0.1f, 1.f);
 	// smoothly interpolate current zoom level
-	gAgent.mHUDCurZoom = lerp(gAgent.mHUDCurZoom, gAgent.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f));
+	gAgentCamera.mHUDCurZoom = lerp(gAgentCamera.mHUDCurZoom, gAgentCamera.mHUDTargetZoom, LLCriticalDamp::getInterpolant(0.03f));
 
 	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
 	{
@@ -1034,7 +1035,7 @@ bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::mat
 	LLVOAvatar* my_avatarp = gAgent.getAvatarObject();
 	if (my_avatarp && my_avatarp->hasHUDAttachment())
 	{
-		F32 zoom_level = gAgent.mHUDCurZoom;
+		F32 zoom_level = gAgentCamera.mHUDCurZoom;
 		LLBBox hud_bbox = my_avatarp->getHUDBBox();
 		
 		F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f);
@@ -1299,14 +1300,14 @@ void render_ui_2d()
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 
 	// render outline for HUD
-	if (gAgent.getAvatarObject() && gAgent.mHUDCurZoom < 0.98f)
+	if (gAgent.getAvatarObject() && gAgentCamera.mHUDCurZoom < 0.98f)
 	{
 		glPushMatrix();
 		S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
 		S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
 		glScalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
 		glTranslatef((F32)half_width, (F32)half_height, 0.f);
-		F32 zoom = gAgent.mHUDCurZoom;
+		F32 zoom = gAgentCamera.mHUDCurZoom;
 		glScalef(zoom,zoom,1.f);
 		gGL.color4fv(LLColor4::white.mV);
 		gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 80336e5c5a..7bf7bf5e2f 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -39,6 +39,7 @@
 #include "indra_constants.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewerfoldertype.h"
 #include "llfolderview.h"
 #include "llviewercontrol.h"
@@ -791,7 +792,7 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item)
 void ModifiedCOFCallback::fire(const LLUUID& inv_item)
 {
 	LLAppearanceManager::instance().updateAppearanceFromCOF();
-	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() )
+	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
 	{
 		// If we're in appearance editing mode, the current tab may need to be refreshed
 		if (gFloaterCustomize)
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index b593fbfb00..b758f6c701 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -43,6 +43,7 @@
 #include "llselectmgr.h"
 #include "llviewermenu.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llfocusmgr.h"
 
 
@@ -106,7 +107,7 @@ void LLViewerJoystick::setOverrideCamera(bool val)
 
 	if (mOverrideCamera)
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 	}
 }
 
@@ -432,7 +433,7 @@ void LLViewerJoystick::agentPitch(F32 pitch_inc)
 void LLViewerJoystick::agentYaw(F32 yaw_inc)
 {	
 	// Cannot steer some vehicles in mouselook if the script grabs the controls
-	if (gAgent.cameraMouselook() && !gSavedSettings.getBOOL("JoystickMouselookYaw"))
+	if (gAgentCamera.cameraMouselook() && !gSavedSettings.getBOOL("JoystickMouselookYaw"))
 	{
 		gAgent.rotate(-yaw_inc, gAgent.getReferenceUpVector());
 	}
@@ -1005,7 +1006,7 @@ bool LLViewerJoystick::toggleFlycam()
 
 	if (!mOverrideCamera)
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 	}
 
 	if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME)
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index f757155b94..4034d8c57d 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -36,6 +36,7 @@
 #include "llviewerkeyboard.h"
 #include "llmath.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llnearbychatbar.h"
 #include "llviewercontrol.h"
 #include "llfocusmgr.h"
@@ -279,7 +280,7 @@ F32 get_orbit_rate()
 void camera_spin_around_ccw( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitLeftKey( get_orbit_rate() );
 }
 
@@ -287,14 +288,14 @@ void camera_spin_around_ccw( EKeystate s )
 void camera_spin_around_cw( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitRightKey( get_orbit_rate() );
 }
 
 void camera_spin_around_ccw_sitting( EKeystate s )
 {
 	if( KEYSTATE_UP == s ) return;
-	if (gAgent.rotateGrabbed() || gAgent.sitCameraEnabled())
+	if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled())
 	{
 		//send keystrokes, but do not change camera
 		agent_turn_right(s);
@@ -310,7 +311,7 @@ void camera_spin_around_ccw_sitting( EKeystate s )
 void camera_spin_around_cw_sitting( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	if (gAgent.rotateGrabbed() || gAgent.sitCameraEnabled())
+	if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled())
 	{
 		//send keystrokes, but do not change camera
 		agent_turn_left(s);
@@ -326,7 +327,7 @@ void camera_spin_around_cw_sitting( EKeystate s )
 void camera_spin_over( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitUpKey( get_orbit_rate() );
 }
 
@@ -334,14 +335,14 @@ void camera_spin_over( EKeystate s )
 void camera_spin_under( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitDownKey( get_orbit_rate() );
 }
 
 void camera_spin_over_sitting( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	if (gAgent.upGrabbed() || gAgent.sitCameraEnabled())
+	if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled())
 	{
 		//send keystrokes, but do not change camera
 		agent_jump(s);
@@ -357,7 +358,7 @@ void camera_spin_over_sitting( EKeystate s )
 void camera_spin_under_sitting( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	if (gAgent.downGrabbed() || gAgent.sitCameraEnabled())
+	if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled())
 	{
 		//send keystrokes, but do not change camera
 		agent_push_down(s);
@@ -372,7 +373,7 @@ void camera_spin_under_sitting( EKeystate s )
 void camera_move_forward( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitInKey( get_orbit_rate() );
 }
 
@@ -380,14 +381,14 @@ void camera_move_forward( EKeystate s )
 void camera_move_backward( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitOutKey( get_orbit_rate() );
 }
 
 void camera_move_forward_sitting( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	if (gAgent.forwardGrabbed() || gAgent.sitCameraEnabled())
+	if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled())
 	{
 		agent_push_forward(s);
 	}
@@ -402,7 +403,7 @@ void camera_move_backward_sitting( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
 
-	if (gAgent.backwardGrabbed() || gAgent.sitCameraEnabled())
+	if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled())
 	{
 		agent_push_backward(s);
 	}
@@ -415,56 +416,56 @@ void camera_move_backward_sitting( EKeystate s )
 void camera_pan_up( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setPanUpKey( get_orbit_rate() );
 }
 
 void camera_pan_down( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setPanDownKey( get_orbit_rate() );
 }
 
 void camera_pan_left( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setPanLeftKey( get_orbit_rate() );
 }
 
 void camera_pan_right( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setPanRightKey( get_orbit_rate() );
 }
 
 void camera_pan_in( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setPanInKey( get_orbit_rate() );
 }
 
 void camera_pan_out( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setPanOutKey( get_orbit_rate() );
 }
 
 void camera_move_forward_fast( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitInKey(2.5f);
 }
 
 void camera_move_backward_fast( EKeystate s )
 {
 	if( KEYSTATE_UP == s  ) return;
-	gAgent.unlockView();
+	gAgentCamera.unlockView();
 	gAgent.setOrbitOutKey(2.5f);
 }
 
@@ -868,7 +869,7 @@ S32 LLViewerKeyboard::loadBindings(const std::string& filename)
 
 EKeyboardMode LLViewerKeyboard::getMode()
 {
-	if ( gAgent.cameraMouselook() )
+	if ( gAgentCamera.cameraMouselook() )
 	{
 		return MODE_FIRST_PERSON;
 	}
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index b8179f7fc2..c1e851350b 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -38,6 +38,7 @@
 #include "llpanelprimmediacontrols.h"
 #include "llpluginclassmedia.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "lltoolpie.h"
 #include "llviewercamera.h"
 #include "llviewermedia.h"
@@ -201,7 +202,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
 {
 	if (object)
 	{
-		gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+		gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
 
 		LLBBox bbox = object->getBoundingBoxAgent();
 		LLVector3d center = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
@@ -260,7 +261,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
 			// orientation with respect to the face.  In other words, if before zoom
 			// the media appears "upside down" from the camera, after zooming it will
 			// still be upside down, but at least it will not flip.
-            LLVector3d cur_camera_pos = LLVector3d(gAgent.getCameraPositionGlobal());
+            LLVector3d cur_camera_pos = LLVector3d(gAgentCamera.getCameraPositionGlobal());
             LLVector3d delta = (cur_camera_pos - camera_pos);
             F64 len = delta.length();
             delta.normalize();
@@ -271,18 +272,18 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal,
 		// If we are not allowing zooming out and the old camera position is closer to 
 		// the center then the new intended camera position, don't move camera and return
 		if (zoom_in_only &&
-		    (dist_vec_squared(gAgent.getCameraPositionGlobal(), target_pos) < dist_vec_squared(camera_pos, target_pos)))
+		    (dist_vec_squared(gAgentCamera.getCameraPositionGlobal(), target_pos) < dist_vec_squared(camera_pos, target_pos)))
 		{
 			return;
 		}
 
-		gAgent.setCameraPosAndFocusGlobal(camera_pos, target_pos, object->getID() );
+		gAgentCamera.setCameraPosAndFocusGlobal(camera_pos, target_pos, object->getID() );
 
 	}
 	else
 	{
 		// If we have no object, focus back on the avatar.
-		gAgent.setFocusOnAvatar(TRUE, ANIMATE);
+		gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
 	}
 }
 void LLViewerMediaFocus::onFocusReceived()
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 1d58daba2c..6294800428 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -42,6 +42,7 @@
 
 // newview includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llagentpilot.h"
 #include "llbottomtray.h"
@@ -2479,18 +2480,18 @@ class LLObjectBuild : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
+		if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
 		{
 			// zoom in if we're looking at the avatar
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
-			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
-			gAgent.cameraZoomIn(0.666f);
-			gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
+			gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+			gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+			gAgentCamera.cameraZoomIn(0.666f);
+			gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
 			gViewerWindow->moveCursorToCenter();
 		}
 		else if ( gSavedSettings.getBOOL("EditCameraMovement") )
 		{
-			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
+			gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
 			gViewerWindow->moveCursorToCenter();
 		}
 
@@ -2508,7 +2509,7 @@ void handle_object_edit()
 {
 	LLViewerParcelMgr::getInstance()->deselectLand();
 
-	if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
+	if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
 	{
 		LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
 
@@ -2516,19 +2517,19 @@ void handle_object_edit()
 		{
 			// always freeze camera in space, even if camera doesn't move
 			// so, for example, follow cam scripts can't affect you when in build mode
-			gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null);
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+			gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+			gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
 		}
 		else
 		{
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+			gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
 			LLViewerObject* selected_objectp = selection->getFirstRootObject();
 			if (selected_objectp)
 			{
 			  // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
-			  gAgent.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
-			  gAgent.cameraZoomIn(0.666f);
-			  gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
+			  gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
+			  gAgentCamera.cameraZoomIn(0.666f);
+			  gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
 			  gViewerWindow->moveCursorToCenter();
 			}
 		}
@@ -2573,19 +2574,19 @@ class LLLandBuild : public view_listener_t
 	{
 		LLViewerParcelMgr::getInstance()->deselectLand();
 
-		if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
+		if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
 		{
 			// zoom in if we're looking at the avatar
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
-			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
-			gAgent.cameraZoomIn(0.666f);
-			gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
+			gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+			gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
+			gAgentCamera.cameraZoomIn(0.666f);
+			gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
 			gViewerWindow->moveCursorToCenter();
 		}
 		else if ( gSavedSettings.getBOOL("EditCameraMovement")  )
 		{
 			// otherwise just move focus
-			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
+			gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
 			gViewerWindow->moveCursorToCenter();
 		}
 
@@ -2822,12 +2823,12 @@ bool handle_go_to()
 
 	if (gAgent.getAvatarObject() && !gSavedSettings.getBOOL("AutoPilotLocksCamera"))
 	{
-		gAgent.setFocusGlobal(gAgent.getFocusTargetGlobal(), gAgent.getAvatarObject()->getID());
+		gAgentCamera.setFocusGlobal(gAgentCamera.getFocusTargetGlobal(), gAgent.getAvatarObject()->getID());
 	}
 	else 
 	{
 		// Snap camera back to behind avatar
-		gAgent.setFocusOnAvatar(TRUE, ANIMATE);
+		gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE);
 	}
 
 	// Could be first use
@@ -3712,14 +3713,14 @@ void reset_view_final( BOOL proceed );
 
 void handle_reset_view()
 {
-	if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) && gFloaterCustomize )
+	if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) && gFloaterCustomize )
 	{
 		// Show dialog box if needed.
 		gFloaterCustomize->askToSaveIfDirty( reset_view_final );
 	}
 	else
 	{
-		gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
+		gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
 		reset_view_final( TRUE );
 		LLFloaterCamera::resetCameraMode();
 	}
@@ -3742,8 +3743,8 @@ void reset_view_final( BOOL proceed )
 		return;
 	}
 
-	gAgent.resetView(TRUE, TRUE);
-	gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
+	gAgentCamera.resetView(TRUE, TRUE);
+	gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
 }
 
 class LLViewLookAtLastChatter : public view_listener_t
@@ -3759,13 +3760,13 @@ class LLViewMouselook : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		if (!gAgent.cameraMouselook())
+		if (!gAgentCamera.cameraMouselook())
 		{
-			gAgent.changeCameraToMouselook();
+			gAgentCamera.changeCameraToMouselook();
 		}
 		else
 		{
-			gAgent.changeCameraToDefault();
+			gAgentCamera.changeCameraToDefault();
 		}
 		return true;
 	}
@@ -3984,9 +3985,9 @@ void handle_god_request_avatar_geometry(void *)
 
 void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
 {
-	if(gAgent.cameraMouselook())
+	if(gAgentCamera.cameraMouselook())
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 	}
 	//gInventoryView->setPanelOpen(TRUE);
 
@@ -5027,7 +5028,7 @@ class LLViewEnableLastChatter : public view_listener_t
 	bool handleEvent(const LLSD& userdata)
 	{
 		// *TODO: add check that last chatter is in range
-		bool new_value = (gAgent.cameraThirdPerson() && gAgent.getLastChatter().notNull());
+		bool new_value = (gAgentCamera.cameraThirdPerson() && gAgent.getLastChatter().notNull());
 		return new_value;
 	}
 };
@@ -5141,7 +5142,7 @@ void print_agent_nvpairs(void*)
 		llinfos << "Can't find agent object" << llendl;
 	}
 
-	llinfos << "Camera at " << gAgent.getCameraPositionGlobal() << llendl;
+	llinfos << "Camera at " << gAgentCamera.getCameraPositionGlobal() << llendl;
 }
 
 void show_debug_menus()
@@ -5332,7 +5333,7 @@ void handle_look_at_selection(const LLSD& param)
 	BOOL zoom = (param.asString() == "zoom");
 	if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
 	{
-		gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+		gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
 
 		LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
 		F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
@@ -5349,17 +5350,17 @@ void handle_look_at_selection(const LLSD& param)
 		if (zoom)
 		{
 			// Make sure we are not increasing the distance between the camera and object
-			LLVector3d orig_distance = gAgent.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal();
+			LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal();
 			distance = llmin(distance, (F32) orig_distance.length());
 				
-			gAgent.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), 
+			gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), 
 										LLSelectMgr::getInstance()->getSelectionCenterGlobal(), 
 										object_id );
 			
 		}
 		else
 		{
-			gAgent.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id );
+			gAgentCamera.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id );
 		}	
 	}
 }
@@ -5372,7 +5373,7 @@ void handle_zoom_to_object(LLUUID object_id)
 
 	if (object)
 	{
-		gAgent.setFocusOnAvatar(FALSE, ANIMATE);
+		gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
 
 		LLBBox bbox = object->getBoundingBoxAgent() ;
 		F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
@@ -5384,7 +5385,7 @@ void handle_zoom_to_object(LLUUID object_id)
 
 			LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
 
-			gAgent.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), 
+			gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), 
 											object_center_global, 
 											object_id );
 	}
@@ -5582,7 +5583,7 @@ void handle_customize_avatar()
 {
 	if (gAgentWearables.areWearablesLoaded())
 	{
-		gAgent.changeCameraToCustomizeAvatar();
+		gAgentCamera.changeCameraToCustomizeAvatar();
 	}
 }
 
@@ -5768,18 +5769,18 @@ class LLLandEdit : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
+		if (gAgentCamera.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
 		{
 			// zoom in if we're looking at the avatar
-			gAgent.setFocusOnAvatar(FALSE, ANIMATE);
-			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
+			gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+			gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
 
-			gAgent.cameraOrbitOver( F_PI * 0.25f );
+			gAgentCamera.cameraOrbitOver( F_PI * 0.25f );
 			gViewerWindow->moveCursorToCenter();
 		}
 		else if ( gSavedSettings.getBOOL("EditCameraMovement") )
 		{
-			gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick());
+			gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
 			gViewerWindow->moveCursorToCenter();
 		}
 
@@ -5905,7 +5906,7 @@ void confirm_replace_attachment(S32 option, void* user_data)
 			walkToSpot -= delta;
 
 			gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance);
-			gAgent.clearFocusObject();
+			gAgentCamera.clearFocusObject();
 		}
 	}
 }
@@ -6751,7 +6752,7 @@ class LLViewEnableMouselook : public view_listener_t
 	{
 		// You can't go directly from customize avatar to mouselook.
 		// TODO: write code with appropriate dialogs to handle this transition.
-		bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime"));
+		bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime"));
 		return new_value;
 	}
 };
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 00762894cd..42dc02c6e8 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -36,6 +36,7 @@
 
 // project includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llfilepicker.h"
 #include "llfloaterreg.h"
 #include "llfloaterbuycurrency.h"
@@ -140,9 +141,9 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
 **/
 const std::string upload_pick(void* data)
 {
- 	if( gAgent.cameraMouselook() )
+ 	if( gAgentCamera.cameraMouselook() )
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 		// This doesn't seem necessary. JC
 		// display();
 	}
@@ -289,9 +290,9 @@ class LLFileUploadBulk : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		if( gAgent.cameraMouselook() )
+		if( gAgentCamera.cameraMouselook() )
 		{
-			gAgent.changeCameraToDefault();
+			gAgentCamera.changeCameraToDefault();
 		}
 
 		// TODO:
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 5f7b19a5cb..ea80dee05c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -51,6 +51,7 @@
 #include "mean_collision_data.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llcallingcard.h"
 //#include "llfirstuse.h"
 #include "llfloaterbuycurrency.h"
@@ -2971,10 +2972,10 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 
 /*
 	// send camera update to new region
-	gAgent.updateCamera();
+	gAgentCamera.updateCamera();
 
 	// likewise make sure the camera is behind the avatar
-	gAgent.resetView(TRUE);
+	gAgentCamera.resetView(TRUE);
 	LLVector3 shift_vector = regionp->getPosRegionFromGlobal(gAgent.getRegion()->getOriginGlobal());
 	gAgent.setRegion(regionp);
 	gObjectList.shiftObjects(shift_vector);
@@ -2982,7 +2983,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
 	if (gAgent.getAvatarObject())
 	{
 		gAgent.getAvatarObject()->clearChatText();
-		gAgent.slamLookAt(look_at);
+		gAgentCamera.slamLookAt(look_at);
 	}
 	gAgent.setPositionAgent(pos);
 	gAssetStorage->setUpstream(sim);
@@ -3106,9 +3107,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 	if( is_teleport )
 	{
 		// Force the camera back onto the agent, don't animate.
-		gAgent.setFocusOnAvatar(TRUE, FALSE);
-		gAgent.slamLookAt(look_at);
-		gAgent.updateCamera();
+		gAgentCamera.setFocusOnAvatar(TRUE, FALSE);
+		gAgentCamera.slamLookAt(look_at);
+		gAgentCamera.updateCamera();
 
 		gAgent.setTeleportState( LLAgent::TELEPORT_START_ARRIVAL );
 
@@ -3157,7 +3158,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 			global_agent_pos[1] += y;
 			look_at = (LLVector3)beacon_pos - global_agent_pos;
 			look_at.normVec();
-			gAgent.slamLookAt(look_at);
+			gAgentCamera.slamLookAt(look_at);
 		}
 	}
 
@@ -3334,7 +3335,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 	LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion();
 	LLQuaternion head_rotation = gAgent.getHeadRotation();
 
-	camera_pos_agent = gAgent.getCameraPositionAgent();
+	camera_pos_agent = gAgentCamera.getCameraPositionAgent();
 
 	render_state = gAgent.getRenderState();
 
@@ -4109,7 +4110,7 @@ void process_camera_constraint(LLMessageSystem *mesgsys, void **user_data)
 	LLVector4 cameraCollidePlane;
 	mesgsys->getVector4Fast(_PREHASH_CameraCollidePlane, _PREHASH_Plane, cameraCollidePlane);
 
-	gAgent.setCameraCollidePlane(cameraCollidePlane);
+	gAgentCamera.setCameraCollidePlane(cameraCollidePlane);
 }
 
 void near_sit_object(BOOL success, void *data)
@@ -4146,10 +4147,10 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data)
 
 	if (avatar && dist_vec_squared(camera_eye, camera_at) > 0.0001f)
 	{
-		gAgent.setSitCamera(sitObjectID, camera_eye, camera_at);
+		gAgentCamera.setSitCamera(sitObjectID, camera_eye, camera_at);
 	}
 	
-	gAgent.setForceMouselook(force_mouselook);
+	gAgentCamera.setForceMouselook(force_mouselook);
 
 	LLViewerObject* object = gObjectList.findObject(sitObjectID);
 	if (object)
@@ -5144,9 +5145,9 @@ void container_inventory_arrived(LLViewerObject* object,
 								 void* data)
 {
 	LL_DEBUGS("Messaging") << "container_inventory_arrived()" << LL_ENDL;
-	if( gAgent.cameraMouselook() )
+	if( gAgentCamera.cameraMouselook() )
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 	}
 
 	LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
@@ -5371,13 +5372,13 @@ void process_teleport_local(LLMessageSystem *msg,void**)
 	}
 
 	gAgent.setPositionAgent(pos);
-	gAgent.slamLookAt(look_at);
+	gAgentCamera.slamLookAt(look_at);
 
 	// likewise make sure the camera is behind the avatar
-	gAgent.resetView(TRUE, TRUE);
+	gAgentCamera.resetView(TRUE, TRUE);
 
 	// send camera update to new region
-	gAgent.updateCamera();
+	gAgentCamera.updateCamera();
 
 	send_agent_update(TRUE, TRUE);
 
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b5642d07a5..c2ec67b4b7 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -60,6 +60,7 @@
 
 #include "llaudiosourcevo.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llbbox.h"
 #include "llbox.h"
 #include "llcylinder.h"
@@ -2757,7 +2758,7 @@ void LLViewerObject::setPixelAreaAndAngle(LLAgent &agent)
 		return;
 	}
 	
-	LLVector3 viewer_pos_agent = agent.getCameraPositionAgent();
+	LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent();
 	LLVector3 pos_agent = getRenderPosition();
 
 	F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX];
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 6347090f71..b1e7aafd0f 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -47,6 +47,7 @@
 #include "llviewerwindow.h"
 #include "llnetmap.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "pipeline.h"
 #include "llspatialpartition.h"
 #include "lltooltip.h"
@@ -288,7 +289,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 	LLMemType mt(LLMemType::MTYPE_OBJECT_PROCESS_UPDATE);
 	LLFastTimer t(FTM_PROCESS_OBJECTS);	
 	
-	LLVector3d camera_global = gAgent.getCameraPositionGlobal();
+	LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
 	LLViewerObject *objectp;
 	S32			num_objects;
 	U32			local_id;
@@ -614,7 +615,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 	}
 
 	// Focused
-	objectp = gAgent.getFocusObject();
+	objectp = gAgentCamera.getFocusObject();
 	if (objectp)
 	{
 		objectp->boostTexturePriority();
@@ -1281,7 +1282,7 @@ void LLViewerObjectList::renderPickList(const LLRect& screen_rect, BOOL pick_par
 	gViewerWindow->renderSelections( TRUE, pick_parcel_wall, FALSE );
 
 	//fix for DEV-19335.  Don't pick hud objects when customizing avatar (camera mode doesn't play nice with nametags).
-	if (!gAgent.cameraCustomizeAvatar())
+	if (!gAgentCamera.cameraCustomizeAvatar())
 	{
 		// render pickable ui elements, like names, etc.
 		LLHUDObject::renderAllForSelect();
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 9de1ef7190..2d17ea7bcd 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -43,11 +43,11 @@
 #include "v2math.h"
 
 // newview includes
+#include "llagentcamera.h"
 #include "llviewertexture.h"
 #include "llviewercontrol.h"
 #include "llsurface.h"
 #include "llviewerregion.h"
-#include "llagent.h"
 #include "llviewercamera.h"
 #include "llviewertexturelist.h"
 #include "llselectmgr.h"
@@ -760,7 +760,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()
 	LLGLDepthTest mDepthTest(GL_TRUE);
 
 	// Find camera height off the ground (not from zero)
-	F32 ground_height_at_camera = land.resolveHeightGlobal( gAgent.getCameraPositionGlobal() );
+	F32 ground_height_at_camera = land.resolveHeightGlobal( gAgentCamera.getCameraPositionGlobal() );
 	F32 camera_z = LLViewerCamera::getInstance()->getOrigin().mV[VZ];
 	F32 camera_height = camera_z - ground_height_at_camera;
 
@@ -791,7 +791,7 @@ S32 LLViewerParcelOverlay::renderPropertyLines	()
 	const S32 vertex_per_edge = 3 + 2 * (GRID_STEP-1) + 3;
 
 	// Stomp the camera into two dimensions
-	LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgent.getCameraPositionGlobal() );
+	LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgentCamera.getCameraPositionGlobal() );
 
 	// Set up a cull plane 2 * PARCEL_GRID_STEP_METERS behind
 	// the camera.  The cull plane normal is the camera's at axis.
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index ce627494c8..07d4ac664f 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -47,6 +47,7 @@
 #include "v4math.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llcallingcard.h"
 #include "llcaphttpsender.h"
 #include "llcommandhandler.h"
@@ -819,7 +820,7 @@ void LLViewerRegion::calculateCenterGlobal()
 
 void LLViewerRegion::calculateCameraDistance()
 {
-	mCameraDistanceSquared = (F32)(gAgent.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
+	mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared();
 }
 
 std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region)
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 8059f866ba..c011ef5c36 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -52,6 +52,7 @@
 #include "llsurface.h"
 #include "llvlmanager.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "llfloatertools.h"
 #include "lldebugview.h"
@@ -577,11 +578,11 @@ void update_statistics(U32 frame_count)
 	// make sure we have a valid time delta for this frame
 	if (gFrameIntervalSeconds > 0.f)
 	{
-		if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+		if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
 		{
 			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
 		}
-		else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
+		else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
 		{
 			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
 		}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index adac4b9b40..8c6571aaf7 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -44,6 +44,8 @@
 #include <fstream>
 #include <algorithm>
 
+#include "llagent.h"
+#include "llagentcamera.h"
 #include "llfloaterreg.h"
 #include "llpanellogin.h"
 #include "llviewerkeyboard.h"
@@ -383,7 +385,7 @@ public:
 			agent_left_text = llformat("AgentLeftAxis  %f %f %f",
 									   (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 
-			tvector = gAgent.getCameraPositionGlobal();
+			tvector = gAgentCamera.getCameraPositionGlobal();
 			camera_center_text = llformat("CameraCenter %f %f %f",
 										  (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 
@@ -776,7 +778,7 @@ BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window,  LLCoordGL pos, MASK
 
 	// *HACK: this should be rolled into the composite tool logic, not
 	// hardcoded at the top level.
-	if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance())
+	if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance())
 	{
 		// If the current tool didn't process the click, we should show
 		// the pie menu.  This can be done by passing the event to the pie
@@ -1151,9 +1153,9 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
 		}
 		
 		// SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues
-		if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+		if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
 		{
-			gAgent.changeCameraToDefault();
+			gAgentCamera.changeCameraToDefault();
 		}
 		
 		send_agent_pause();
@@ -1171,7 +1173,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
 
 BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating)
 {
-	//if (!activating) gAgent.changeCameraToDefault();
+	//if (!activating) gAgentCamera.changeCameraToDefault();
 
 	LLViewerJoystick::getInstance()->setNeedsReset(true);
 	return FALSE;
@@ -2088,7 +2090,7 @@ void LLViewerWindow::draw()
 		// Draw tool specific overlay on world
 		LLToolMgr::getInstance()->getCurrentTool()->draw();
 
-		if( gAgent.cameraMouselook() )
+		if( gAgentCamera.cameraMouselook() )
 		{
 			drawMouselookInstructions();
 			stop_glerror();
@@ -2424,7 +2426,7 @@ void LLViewerWindow::handleScrollWheel(S32 clicks)
 	// Zoom the camera in and out behavior
 
 	if(top_ctrl == 0 && getWorldViewRectScaled().pointInRect(mCurrentMousePoint.mX, mCurrentMousePoint.mY) )
-		gAgent.handleScrollWheel(clicks);
+		gAgentCamera.handleScrollWheel(clicks);
 
 	return;
 }
@@ -3175,7 +3177,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls,
 			glPushMatrix();
 			if (selection->getSelectType() == SELECT_TYPE_HUD)
 			{
-				F32 zoom = gAgent.mHUDCurZoom;
+				F32 zoom = gAgentCamera.mHUDCurZoom;
 				glScalef(zoom, zoom, zoom);
 			}
 
@@ -3294,7 +3296,7 @@ LLVector3d LLViewerWindow::clickPointInWorldGlobal(S32 x, S32 y_from_bot, LLView
 	// world at the location of the mouse click
 	LLVector3 mouse_direction_global = mouseDirectionGlobal( x, y_from_bot );
 
-	LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgent.getCameraPositionGlobal();
+	LLVector3d relative_object = clicked_object->getPositionGlobal() - gAgentCamera.getCameraPositionGlobal();
 
 	// make mouse vector as long as object vector, so it touchs a point near
 	// where the user clicked on the object
@@ -3303,7 +3305,7 @@ LLVector3d LLViewerWindow::clickPointInWorldGlobal(S32 x, S32 y_from_bot, LLView
 	LLVector3d new_pos;
 	new_pos.setVec(mouse_direction_global);
 	// transform mouse vector back to world coords
-	new_pos += gAgent.getCameraPositionGlobal();
+	new_pos += gAgentCamera.getCameraPositionGlobal();
 
 	return new_pos;
 }
@@ -3570,7 +3572,7 @@ LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const
 	F32 hud_x = -((F32)x - center_x)  / height;
 	F32 hud_y = ((F32)y - center_y) / height;
 
-	return LLVector3(0.f, hud_x/gAgent.mHUDCurZoom, hud_y/gAgent.mHUDCurZoom);
+	return LLVector3(0.f, hud_x/gAgentCamera.mHUDCurZoom, hud_y/gAgentCamera.mHUDCurZoom);
 }
 
 // Returns unit vector relative to camera in camera space
@@ -3617,7 +3619,7 @@ BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, con
 	LLVector3d	plane_normal_global_d;
 	plane_normal_global_d.setVec(plane_normal_global);
 	F64 plane_mouse_dot = (plane_normal_global_d * mouse_direction_global_d);
-	LLVector3d plane_origin_camera_rel = plane_point_global - gAgent.getCameraPositionGlobal();
+	LLVector3d plane_origin_camera_rel = plane_point_global - gAgentCamera.getCameraPositionGlobal();
 	F64	mouse_look_at_scale = (plane_normal_global_d * plane_origin_camera_rel)
 								/ plane_mouse_dot;
 	if (llabs(plane_mouse_dot) < 0.00001)
@@ -3631,7 +3633,7 @@ BOOL LLViewerWindow::mousePointOnPlaneGlobal(LLVector3d& point, const S32 x, con
 		mouse_look_at_scale = plane_origin_camera_rel.magVec() / (plane_origin_dir * mouse_direction_global_d);
 	}
 
-	point = gAgent.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d;
+	point = gAgentCamera.getCameraPositionGlobal() + mouse_look_at_scale * mouse_direction_global_d;
 
 	return mouse_look_at_scale > 0.0;
 }
@@ -3649,7 +3651,7 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
 	const F32	SECOND_PASS_STEP = 0.1f;	// meters
 	LLVector3d	camera_pos_global;
 
-	camera_pos_global = gAgent.getCameraPositionGlobal();
+	camera_pos_global = gAgentCamera.getCameraPositionGlobal();
 	LLVector3d		probe_point_global;
 	LLVector3		probe_point_region;
 
@@ -5039,9 +5041,9 @@ bool LLViewerWindow::onAlert(const LLSD& notify)
 
 	// If we're in mouselook, the mouse is hidden and so the user can't click 
 	// the dialog buttons.  In that case, change to First Person instead.
-	if( gAgent.cameraMouselook() )
+	if( gAgentCamera.cameraMouselook() )
 	{
-		gAgent.changeCameraToDefault();
+		gAgentCamera.changeCameraToDefault();
 	}
 	return false;
 }
@@ -5153,7 +5155,7 @@ void LLPickInfo::fetchResults()
 			{
 				mPickType = PICK_OBJECT;
 			}
-			mObjectOffset = gAgent.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY);
+			mObjectOffset = gAgentCamera.calcFocusOffset(objectp, intersection, mPickPt.mX, mPickPt.mY);
 			mObjectID = objectp->mID;
 			mObjectFace = (te_offset == NO_FACE) ? -1 : (S32)te_offset;
 
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f5e83ed025..54379dece3 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -48,6 +48,7 @@
 #include "sound_ids.h"
 
 #include "llagent.h" //  Get state values from here
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llanimationstates.h"
 #include "llavatarpropertiesprocessor.h"
@@ -885,7 +886,7 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
 // static
 void LLVOAvatar::dumpBakedStatus()
 {
-	LLVector3d camera_pos_global = gAgent.getCameraPositionGlobal();
+	LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal();
 
 	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
 		 iter != LLCharacter::sInstances.end(); ++iter)
@@ -2225,7 +2226,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 {
 	// disable voice visualizer when in mouselook
-	mVoiceVisualizer->setVoiceEnabled( voice_enabled && !(isSelf() && gAgent.cameraMouselook()) );
+	mVoiceVisualizer->setVoiceEnabled( voice_enabled && !(isSelf() && gAgentCamera.cameraMouselook()) );
 	if ( voice_enabled )
 	{		
 		//----------------------------------------------------------------
@@ -2671,7 +2672,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 	if (isSelf())
 	{
 		render_name = render_name
-			&& !gAgent.cameraMouselook()
+			&& !gAgentCamera.cameraMouselook()
 			&& (visible_chat || (gSavedSettings.getBOOL("RenderNameShowSelf") 
 								 && gSavedSettings.getS32("AvatarNameTagMode") ));
 	}
@@ -3235,7 +3236,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 				}
 			}
 			LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f));
-			if (isSelf() && gAgent.cameraMouselook())
+			if (isSelf() && gAgentCamera.cameraMouselook())
 			{
 				// make sure fwdDir stays in same general direction as primdir
 				if (gAgent.getFlying())
@@ -3266,7 +3267,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 			// When moving very slow, the pelvis is allowed to deviate from the
 			// forward direction to allow it to hold it's position while the torso
 			// and head turn.  Once in motion, it must conform however.
-			BOOL self_in_mouselook = isSelf() && gAgent.cameraMouselook();
+			BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook();
 
 			LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
 			F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST);
@@ -5206,7 +5207,7 @@ BOOL LLVOAvatar::updateJointLODs()
 	{
 		if (isSelf())
 		{
-			if(gAgent.cameraCustomizeAvatar() || gAgent.cameraMouselook())
+			if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
 			{
 				mAdjustedPixelArea = MAX_PIXEL_AREA;
 			}
@@ -5352,7 +5353,7 @@ void LLVOAvatar::updateShadowFaces()
 
 			// Render sprite
 			sprite.setNormal(normal);
-			if (isSelf() && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+			if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
 			{
 				sprite.setColor(0.f, 0.f, 0.f, 0.f);
 			}
@@ -5385,7 +5386,7 @@ void LLVOAvatar::updateShadowFaces()
 
 			// Render sprite
 			sprite.setNormal(normal);
-			if (isSelf() && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+			if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
 			{
 				sprite.setColor(0.f, 0.f, 0.f, 0.f);
 			}
@@ -5440,7 +5441,7 @@ BOOL LLVOAvatar::setParent(LLViewerObject* parent)
 		ret = LLViewerObject::setParent(parent);
 		if (isSelf())
 		{
-			gAgent.resetCamera();
+			gAgentCamera.resetCamera();
 		}
 	}
 	else
@@ -5625,15 +5626,15 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
 		//LLFirstUse::useSit();
 
 		gAgent.setFlying(FALSE);
-		gAgent.setThirdPersonHeadOffset(LLVector3::zero);
+		gAgentCamera.setThirdPersonHeadOffset(LLVector3::zero);
 		//interpolate to new camera position
-		gAgent.startCameraAnimation();
+		gAgentCamera.startCameraAnimation();
 		// make sure we are not trying to autopilot
 		gAgent.stopAutoPilot();
-		gAgent.setupSitCamera();
-		if (gAgent.getForceMouselook())
+		gAgentCamera.setupSitCamera();
+		if (gAgentCamera.getForceMouselook())
 		{
-			gAgent.changeCameraToMouselook();
+			gAgentCamera.changeCameraToMouselook();
 		}
 	}
 
@@ -5720,9 +5721,9 @@ void LLVOAvatar::getOffObject()
 
 		//reset orientation
 //		mRoot.setRotation(avWorldRot);
-		gAgent.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
+		gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
 
-		gAgent.setSitCamera(LLUUID::null);
+		gAgentCamera.setSitCamera(LLUUID::null);
 	}
 }
 
@@ -5937,7 +5938,7 @@ void LLVOAvatar::updateMeshTextures()
 		}
 	}
 
-	const BOOL self_customizing = isSelf() && gAgent.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
+	const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
 	const BOOL other_culled = !isSelf() && mCulled;
 
 	std::vector<BOOL> is_layer_baked;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 32c24b3ebd..74c08deb88 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -44,6 +44,7 @@
 #include "pipeline.h"
 
 #include "llagent.h" //  Get state values from here
+#include "llagentcamera.h"
 #include "llagentwearables.h"
 #include "llhudeffecttrail.h"
 #include "llhudmanager.h"
@@ -819,10 +820,10 @@ void LLVOAvatarSelf::idleUpdateTractorBeam()
 	{
 		LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
 
-		if (gAgent.mPointAt.notNull())
+		if (gAgentCamera.mPointAt.notNull())
 		{
 			// get point from pointat effect
-			mBeam->setPositionGlobal(gAgent.mPointAt->getPointAtPosGlobal());
+			mBeam->setPositionGlobal(gAgentCamera.mPointAt->getPointAtPosGlobal());
 			mBeam->triggerLocal();
 		}
 		else if (selection->getFirstRootObject() && 
@@ -873,7 +874,7 @@ void LLVOAvatarSelf::restoreMeshData()
 	//llinfos << "Restoring" << llendl;
 	mMeshValid = TRUE;
 	updateJointLODs();
-	updateAttachmentVisibility(gAgent.getCameraMode());
+	updateAttachmentVisibility(gAgentCamera.getCameraMode());
 
 	// force mesh update as LOD might not have changed to trigger this
 	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
@@ -938,7 +939,7 @@ void LLVOAvatarSelf::wearableUpdated( EWearableType type, BOOL upload_result )
 
 		// if we're editing our appearance, ensure that we're not using baked textures
 		// The baked texture for alpha masks is set explicitly when you hit "save"
-		if (gAgent.cameraCustomizeAvatar())
+		if (gAgentCamera.cameraCustomizeAvatar())
 		{
 			setNewBakedTexture(index,IMG_DEFAULT_AVATAR);
 		}
@@ -1027,7 +1028,7 @@ const LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *view
 		return 0;
 	}
 
-	updateAttachmentVisibility(gAgent.getCameraMode());
+	updateAttachmentVisibility(gAgentCamera.getCameraMode());
 	
 	// Then make sure the inventory is in sync with the avatar.
 
@@ -1115,11 +1116,11 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
 			discard_level < local_tex_obj->getDiscard())
 		{
 			local_tex_obj->setDiscard(discard_level);
-			if (!gAgent.cameraCustomizeAvatar())
+			if (!gAgentCamera.cameraCustomizeAvatar())
 			{
 				requestLayerSetUpdate(index);
 			}
-			else if (gAgent.cameraCustomizeAvatar())
+			else if (gAgentCamera.cameraCustomizeAvatar())
 			{
 				LLVisualParamHint::requestHintUpdates();
 			}
@@ -1523,11 +1524,11 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 				if (tex_discard >= 0 && tex_discard <= desired_discard)
 				{
 					local_tex_obj->setDiscard(tex_discard);
-					if (isSelf() && !gAgent.cameraCustomizeAvatar())
+					if (isSelf() && !gAgentCamera.cameraCustomizeAvatar())
 					{
 						requestLayerSetUpdate(type);
 					}
-					else if (isSelf() && gAgent.cameraCustomizeAvatar())
+					else if (isSelf() && gAgentCamera.cameraCustomizeAvatar())
 					{
 						LLVisualParamHint::requestHintUpdates();
 					}
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index e311f07912..a82afbeb76 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -37,7 +37,7 @@
 #include "imageids.h"
 #include "llviewercontrol.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "llnotificationsutil.h"
 #include "lldrawable.h"
 #include "llface.h"
@@ -306,7 +306,7 @@ BOOL LLVOGrass::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent)
 {
 	// This should be the camera's center, as soon as we move to all region-local.
-	LLVector3 relative_position = getPositionAgent() - agent.getCameraPositionAgent();
+	LLVector3 relative_position = getPositionAgent() - gAgentCamera.getCameraPositionAgent();
 	F32 range = relative_position.length();
 
 	F32 max_scale = getMaxScale();
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 139d2fbd88..3ba4ecad0c 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -40,7 +40,7 @@
 #include "message.h"
 #include "v2math.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "lldrawable.h"
 #include "llface.h"
 #include "llsky.h"
@@ -136,7 +136,7 @@ F32 LLVOPartGroup::getPartSize(S32 idx)
 
 LLVector3 LLVOPartGroup::getCameraPosition() const
 {
-	return gAgent.getCameraPositionAgent();
+	return gAgentCamera.getCameraPositionAgent();
 }
 
 static LLFastTimer::DeclareTimer FTM_UPDATE_PARTICLES("Update Particles");
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 0550ed770b..d73850cb49 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -41,6 +41,7 @@
 #include "timing.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "lldrawable.h"
 #include "llface.h"
 #include "llcubemap.h"
@@ -357,7 +358,7 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
 		mFace[i] = NULL;
 	}
 	
-	mCameraPosAgent = gAgent.getCameraPositionAgent();
+	mCameraPosAgent = gAgentCamera.getCameraPositionAgent();
 	mAtmHeight = ATM_HEIGHT;
 	mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1], -EARTH_RADIUS);
 
@@ -2034,7 +2035,7 @@ void LLVOSky::updateFog(const F32 distance)
 
 	const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
 	// LLWorld::getInstance()->getWaterHeight();
-	F32 camera_height = gAgent.getCameraPositionAgent().mV[2];
+	F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2];
 
 	F32 near_clip_height = LLViewerCamera::getInstance()->getAtAxis().mV[VZ] * LLViewerCamera::getInstance()->getNear();
 	camera_height += near_clip_height;
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 55e2c58a52..b89c0cd638 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -44,7 +44,7 @@
 #include "material_codes.h"
 #include "object_flags.h"
 
-#include "llagent.h"
+#include "llagentcamera.h"
 #include "lldrawable.h"
 #include "llface.h"
 #include "llviewercamera.h"
@@ -444,7 +444,7 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)
 	// Re-calculate mPixelArea accurately
 	
 	// This should be the camera's center, as soon as we move to all region-local.
-	LLVector3 relative_position = getPositionAgent() - agent.getCameraPositionAgent();
+	LLVector3 relative_position = getPositionAgent() - gAgentCamera.getCameraPositionAgent();
 	F32 range = relative_position.length();				// ugh, square root
 
 	F32 max_scale = mBillboardScale * getMaxScale();
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index 8be8f494da..436cd478b4 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -54,6 +54,7 @@
 #include "llviewercontrol.h"
 #include "lldrawpoolwater.h"
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewerregion.h"
 
 #include "llwlparammanager.h"
@@ -434,7 +435,7 @@ F32 LLWaterParamManager::getFogDensity(void)
 	
 	// modify if we're underwater
 	const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f;
-	F32 camera_height = gAgent.getCameraPositionAgent().mV[2];
+	F32 camera_height = gAgentCamera.getCameraPositionAgent().mV[2];
 	if(camera_height <= water_height)
 	{
 		// raise it to the underwater fog density modifier
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 5edf72d4ae..519da2c645 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -44,6 +44,7 @@
 #include "lltooltip.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llcallingcard.h"
 #include "llviewercontrol.h"
 #include "llfloatermap.h"
@@ -310,7 +311,7 @@ void LLWorldMapView::draw()
 	const S32 height = getRect().getHeight();
 	const F32 half_width = F32(width) / 2.0f;
 	const F32 half_height = F32(height) / 2.0f;
-	LLVector3d camera_global = gAgent.getCameraPositionGlobal();
+	LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
 
 	S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
 
@@ -912,7 +913,7 @@ void LLWorldMapView::drawFrustum()
 
 LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos )
 {
-	LLVector3d relative_pos_global = global_pos - gAgent.getCameraPositionGlobal();
+	LLVector3d relative_pos_global = global_pos - gAgentCamera.getCameraPositionGlobal();
 	LLVector3 pos_local;
 	pos_local.setVec(relative_pos_global);  // convert to floats from doubles
 
@@ -1005,7 +1006,7 @@ LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )
 	
 	LLVector3d pos_global;
 	pos_global.setVec( pos_local );
-	pos_global += gAgent.getCameraPositionGlobal();
+	pos_global += gAgentCamera.getCameraPositionGlobal();
 	if(gAgent.isGodlike())
 	{
 		pos_global.mdV[VZ] = GODLY_TELEPORT_HEIGHT; // Godly height should always be 200.
@@ -1637,7 +1638,7 @@ void LLWorldMapView::updateVisibleBlocks()
 	// Load the blocks visible in the current World Map view
 
 	// Get the World Map view coordinates and boundaries
-	LLVector3d camera_global = gAgent.getCameraPositionGlobal();
+	LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
 	const S32 width = getRect().getWidth();
 	const S32 height = getRect().getHeight();
 	const F32 half_width = F32(width) / 2.0f;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 259ca21e93..99dfa163c4 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -56,6 +56,7 @@
 
 // newview includes
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "lldrawable.h"
 #include "lldrawpoolalpha.h"
 #include "lldrawpoolavatar.h"
@@ -4361,7 +4362,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 		// mNearbyLight (and all light_set_t's) are sorted such that
 		// begin() == the closest light and rbegin() == the farthest light
 		const S32 MAX_LOCAL_LIGHTS = 6;
-// 		LLVector3 cam_pos = gAgent.getCameraPositionAgent();
+// 		LLVector3 cam_pos = gAgentCamera.getCameraPositionAgent();
 		LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ?
 						camera.getOrigin() : 
 						gAgent.getPositionAgent();
@@ -7101,7 +7102,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 	if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
 	{
 		LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
-		if (gAgent.getCameraAnimating() || gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+		if (gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
 		{
 			avatar = NULL;
 		}
@@ -7334,7 +7335,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
 		if (avatar)
 		{
-			avatar->updateAttachmentVisibility(gAgent.getCameraMode());
+			avatar->updateAttachmentVisibility(gAgentCamera.getCameraMode());
 		}
 	}
 }
-- 
cgit v1.2.3