diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 41930f539..4350152ac 100644 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -249,7 +249,7 @@ BOOL LLVorbisDecodeState::initDecode() llwarns << "Bad sound caught by zmagic" << llendl; abort_decode = true; } - else + else if(!gAudiop->getAllowLargeSounds()) { // //Much more restrictive than zmagic. Perhaps make toggleable. diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index fa5444cf5..59977faf2 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -115,6 +115,8 @@ void LLAudioEngine::setDefaults() for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++) mSecondaryGain[i] = 1.0f; + + mAllowLargeSounds = false; } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index c41458553..7f07a5bc2 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -187,6 +187,8 @@ public: bool updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null); + void setAllowLargeSounds(bool allow) { mAllowLargeSounds = allow ;} + bool getAllowLargeSounds() const {return mAllowLargeSounds;} // Asset callback when we're retrieved a sound from the asset server. void startNextTransfer(); @@ -260,6 +262,8 @@ protected: private: void setDefaults(); LLStreamingAudioInterface *mStreamingAudioImpl; + + bool mAllowLargeSounds; }; diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp index 8d3f70f89..cdd27ec3e 100644 --- a/indra/llaudio/llaudioengine_fmod.cpp +++ b/indra/llaudio/llaudioengine_fmod.cpp @@ -107,6 +107,7 @@ bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) // This means we also try to play audio when minimized, // so we manually handle muting in that case. JC fmod_flags |= FSOUND_INIT_GLOBALFOCUS; + fmod_flags |= FSOUND_INIT_DSOUND_HRTF_FULL; #endif #if LL_LINUX diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 7df7a16c7..0603c1a18 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -114,6 +114,7 @@ set(llcommon_HEADER_FILES lldarrayptr.h lldate.h lldefs.h + lldeleteutils.h lldepthstack.h lldictionary.h lldlinked.h diff --git a/indra/llcommon/lldeleteutils.h b/indra/llcommon/lldeleteutils.h new file mode 100644 index 000000000..8a8d3fd72 --- /dev/null +++ b/indra/llcommon/lldeleteutils.h @@ -0,0 +1,54 @@ +/** + * @file lldeleteutils.h + * @brief Utility functions to simplify some common pointer-munging idioms. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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_DELETE_UTILS_H +#define LL_DELETE_UTILS_H + +// Simple utility functions to eventually replace the common 2-line +// idiom scattered throughout the viewer codebase. Note that where +// possible we would rather be using smart pointers of some sort. + +template +inline void deleteAndClear(T*& ptr) +{ + delete ptr; + ptr = NULL; +} + +template +inline void deleteAndClearArray(T*& array_ptr) +{ + delete[] array_ptr; + array_ptr = NULL; +} + +#endif diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index c1fea04b3..3a7f30511 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -226,7 +226,7 @@ public: //gTimerBins[gCurTimerBin]++; //LLTimer::sNumTimerCalls++; - U64 cpu_clocks = getCPUClockCount64(); + U64 cpu_clocks = getCPUClockCount32(); sStart[sCurDepth] = cpu_clocks; sCurDepth++; @@ -241,7 +241,7 @@ public: // These don't get counted, because they use CPU clockticks //gTimerBins[gCurTimerBin]++; //LLTimer::sNumTimerCalls++; - end = getCPUClockCount64(); + end = getCPUClockCount32(); sCurDepth--; delta = end - sStart[sCurDepth]; diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index 87f011643..bbf1746bf 100644 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -233,6 +233,7 @@ LLIOPipe::EStatus LLURLRequest::process_impl( LLMemType m1(LLMemType::MTYPE_IO_URL_REQUEST); //llinfos << "LLURLRequest::process_impl()" << llendl; if(!buffer) return STATUS_ERROR; + if(!mDetail) return STATUS_ERROR; //Seems to happen on occasion. Need to hunt down why. switch(mState) { case STATE_INITIALIZED: diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index b10c77c1a..552814c7e 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -307,6 +307,11 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) return false; } + if (cubeMap->mImages[0].isNull()) + { + llwarns << "NULL LLTexUnit::bind cubeMap->mImages[0]" << llendl; + return false; + } if (mCurrTexture != cubeMap->mImages[0]->getTexName()) { if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c6621ab1d..89cd31abb 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -102,9 +102,11 @@ set(viewer_SOURCE_FILES qtoolalign.cpp llagent.cpp llagentaccess.cpp + llagentcamera.cpp llagentdata.cpp llagentlanguage.cpp llagentpilot.cpp + llagentwearables.cpp llanimstatelabels.cpp llappviewer.cpp llassetconverter.cpp @@ -576,9 +578,11 @@ set(viewer_HEADER_FILES qtoolalign.h llagent.h llagentaccess.h + llagentcamera.h llagentdata.h llagentlanguage.h llagentpilot.h + llagentwearables.h llanimstatelabels.h llappearance.h llappviewer.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9c01fb349..07da20141 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9,6 +9,17 @@ settings_rlv.xml + AllowLargeSounds + + Comment + Bypass stricter sound size/sample checks, which were introduced in SL2.x, for sound decoding. + Persist + 1 + Type + Boolean + Value + 0 + FloaterAvatarTextRect Comment @@ -4689,6 +4700,17 @@ Value 1 + EnableMouselook + + Comment + Allow first person perspective and mouse control of camera + Persist + 1 + Type + Boolean + Value + 1 + EnableRippleWater Comment diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index e43a185c6..f59de729c 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -37,6 +37,7 @@ #include "llchatbar.h" #include "llagent.h" +#include "llagentcamera.h" #include "stdtypes.h" #include "llviewerregion.h" #include "llworld.h" @@ -245,7 +246,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) if(i >> drawDist) { gSavedSettings.setF32("RenderFarClip", drawDist); - gAgent.mDrawDistance=drawDist; + gAgentCamera.mDrawDistance=drawDist; char buffer[DB_IM_MSG_BUF_SIZE * 2]; /* Flawfinder: ignore */ snprintf(buffer,sizeof(buffer),"Draw distance set to: %dm",drawDist); cmdline_printchat(std::string(buffer)); @@ -254,7 +255,7 @@ bool cmd_line_chat(std::string revised_text, EChatType type) } else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdTeleportToCam"))) { - gAgent.teleportViaLocation(gAgent.getCameraPositionGlobal()); + gAgent.teleportViaLocation(gAgentCamera.getCameraPositionGlobal()); return false; } else if(command == utf8str_tolower(gSavedSettings.getString("AscentCmdLineKeyToName"))) diff --git a/indra/newview/cofmgr.cpp b/indra/newview/cofmgr.cpp index b9f3dadc7..47f353c00 100644 --- a/indra/newview/cofmgr.cpp +++ b/indra/newview/cofmgr.cpp @@ -17,6 +17,7 @@ #include "llviewerprecompiledheaders.h" #include "cofmgr.h" #include "llagent.h" +#include "llagentwearables.h" #include "llcommonutils.h" #include "llerror.h" #include "llvoavatar.h" @@ -81,7 +82,7 @@ public: // Add all currently worn wearables for (S32 idxType = 0; idxType < WT_COUNT; idxType++) { - const LLUUID& idItem = gAgent.getWearableItem((EWearableType)idxType); + const LLUUID& idItem = gAgentWearables.getWearableItemID((EWearableType)idxType); if (idItem.isNull()) continue; idItems.push_back(idItem); @@ -388,7 +389,7 @@ void LLCOFMgr::updateAttachments() } // Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on) - LLAgent::userUpdateAttachments(items, !pAvatar->isFullyLoaded()); + LLAgentWearables::userUpdateAttachments(items, !pAvatar->isFullyLoaded()); } // ============================================================================ @@ -431,7 +432,7 @@ void LLCOFMgr::onLinkWearableComplete(const LLUUID& idItem) m_PendingWearableLinks.erase(itPending); // It may have been removed already in which case we should remove the COF link - if (!gAgent.isWearingItem(idItemBase)) + if (!gAgentWearables.isWearingItem(idItemBase)) removeCOFItemLinks(idItemBase); } @@ -458,7 +459,7 @@ void LLCOFMgr::synchWearables() uuid_vec_t newItems; for (S32 idxType = 0; idxType < WT_COUNT; idxType++) { - const LLUUID& idItem = gAgent.getWearableItem((EWearableType)idxType); + const LLUUID& idItem = gAgentWearables.getWearableItemID((EWearableType)idxType); if (idItem.isNull()) continue; newItems.push_back(idItem); diff --git a/indra/newview/floaterao.cpp b/indra/newview/floaterao.cpp index c0a2bd3ac..793c8616a 100644 --- a/indra/newview/floaterao.cpp +++ b/indra/newview/floaterao.cpp @@ -9,6 +9,7 @@ #include "floaterao.h" #include "llagent.h" +#include "llagentcamera.h" #include "llvoavatar.h" #include "llanimationstates.h" #include "lluictrlfactory.h" @@ -857,7 +858,7 @@ BOOL LLFloaterAO::ChangeStand() { if (gAgent.getAvatarObject()) { - if (gSavedSettings.getBOOL("AONoStandsInMouselook") && gAgent.cameraMouselook()) return FALSE; + if (gSavedSettings.getBOOL("AONoStandsInMouselook") && gAgentCamera.cameraMouselook()) return FALSE; if (gAgent.getAvatarObject()->isSitting()) { diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 8e3c01011..618fb7626 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -32,115 +32,70 @@ #include "llviewerprecompiledheaders.h" -#include "stdtypes.h" -#include "stdenums.h" - -#include "cofmgr.h" #include "llagent.h" -#include "llcamera.h" -#include "llcoordframe.h" -#include "indra_constants.h" -#include "llmath.h" -#include "llcriticaldamp.h" -#include "llfocusmgr.h" -#include "llglheaders.h" -#include "llparcel.h" -#include "llpermissions.h" -#include "llregionhandle.h" -#include "m3math.h" -#include "m4math.h" -#include "message.h" -#include "llquaternion.h" -#include "v3math.h" -#include "v4math.h" -#include "llsmoothstep.h" -#include "llsdutil.h" -//#include "vmath.h" -#include "imageids.h" -#include "llbox.h" -#include "llbutton.h" +#include "pipeline.h" + +#include "llagentaccess.h" +#include "llagentcamera.h" +#include "llagentwearables.h" +#include "llanimationstates.h" #include "llcallingcard.h" -#include "llchatbar.h" #include "llconsole.h" -#include "lldrawable.h" -#include "llface.h" #include "llfirstuse.h" -#include "llfloater.h" -#include "floaterao.h" -#include "llfloateractivespeakers.h" -#include "llfloateravatarinfo.h" -#include "llfloaterbuildoptions.h" #include "llfloatercamera.h" -#include "llfloaterchat.h" -#include "llfloatercustomize.h" +#include "llfloatertools.h" + +#include "llgroupmgr.h" +#include "llhomelocationresponder.h" +#include "llhudmanager.h" +#include "lljoystickbutton.h" +#include "llmorphview.h" +#include "llmoveview.h" +#include "llchatbar.h" +#include "llnotify.h" +#include "llparcel.h" +#include "llrendersphere.h" +#include "llsdutil.h" +#include "llsky.h" +#include "llsmoothstep.h" +#include "llstartup.h" +#include "llstatusbar.h" +#include "lltool.h" +#include "lltoolpie.h" +#include "lltoolmgr.h" +#include "lltrans.h" +#include "llviewercontrol.h" +#include "llviewerdisplay.h" +#include "llviewerjoystick.h" +#include "llviewermediafocus.h" +#include "llviewermenu.h" +#include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" +#include "llviewerstats.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llworld.h" +#include "llworldmap.h" + +//Misc non-standard includes +#include "llviewerregion.h" +#include "llurldispatcher.h" +#include "llimview.h" //For gIMMgr +//Floaters +#include "llfloatermute.h" +#include "llfloatermap.h" +#include "llfloateractivespeakers.h" #include "llfloaterdirectory.h" #include "llfloatergroupinfo.h" #include "llfloatergroups.h" -#include "llfloaterland.h" -#include "llfloatermap.h" -#include "llfloatermute.h" -#include "llfloatersnapshot.h" -#include "llfloatertools.h" +#include "llfloateravatarinfo.h" #include "llfloaterworldmap.h" -#include "llgroupmgr.h" -#include "llhomelocationresponder.h" -#include "llhudeffectlookat.h" -#include "llhudmanager.h" -#include "llinventorymodel.h" -#include "llinventoryview.h" -#include "lljoystickbutton.h" -#include "llmenugl.h" -#include "llmorphview.h" -#include "llmoveview.h" -#include "llnotify.h" -#include "llprimitive.h" //For new client id method -HgB -#include "llquantize.h" -#include "llsdutil.h" -#include "llselectmgr.h" -#include "llsky.h" -#include "llrendersphere.h" -#include "llstatusbar.h" -#include "llstartup.h" -#include "llimview.h" -#include "lltexturestats.h" -#include "lltool.h" -#include "lltoolcomp.h" -#include "lltoolfocus.h" -#include "lltoolgrab.h" -#include "lltoolmgr.h" -#include "lltoolpie.h" -#include "lltoolview.h" -#include "lltrans.h" -#include "llui.h" // for make_ui_sound -#include "llurldispatcher.h" -#include "llviewercamera.h" -#include "llviewerinventory.h" -#include "llviewermediafocus.h" -#include "llviewermenu.h" -#include "llviewernetwork.h" -#include "llviewerobjectlist.h" -#include "llviewerparcelmgr.h" -#include "llviewerparceloverlay.h" -#include "llviewerregion.h" -#include "llviewerstats.h" -#include "llviewerwindow.h" -#include "llviewerdisplay.h" -#include "llvoavatar.h" -#include "llvoground.h" -#include "llvosky.h" -#include "llwearable.h" -#include "llwearablelist.h" -#include "llworld.h" -#include "llworldmap.h" -#include "pipeline.h" -#include "roles_constants.h" -#include "llviewercontrol.h" -#include "llappviewer.h" -#include "llviewerjoystick.h" -#include "llfollowcam.h" +#include "llfloaterland.h" +#include "llfloatersnapshot.h" +#include "llfloaterchat.h" -#include "hippogridmanager.h" +#include "lluictrlfactory.h" //For LLUICtrlFactory::getLayeredXMLNode // [RLVa:KB] - Checked: 2010-09-27 (RLVa-1.1.3b) #include "rlvhandler.h" @@ -150,79 +105,22 @@ using namespace LLVOAvatarDefines; -extern LLMenuBarGL* gMenuBarView; - -//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 +const BOOL ANIMATE = TRUE; +const U8 AGENT_STATE_TYPING = 0x04; +const U8 AGENT_STATE_EDITING = 0x10; // 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.0f; -const F32 MIN_CAMERA_DISTANCE = 0.0f; -const F32 AVATAR_ZOOM_MIN_X_FACTOR = 0.0f; -const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.0f; -const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 0.0f; - -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; +const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f; +const F64 CHAT_AGE_FAST_RATE = 3.0; // 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. LLAgent gAgent; @@ -236,20 +134,6 @@ LLVector3 gReSitOffset; // Statics // -// -// For MapBlockReply funk 'cause I dunno what I'm doing -BOOL LLAgent::lure_show = FALSE; -std::string LLAgent::lure_name; -LLVector3d LLAgent::lure_posglobal; -U16 LLAgent::lure_global_x; -U16 LLAgent::lure_global_y; -int LLAgent::lure_x; -int LLAgent::lure_y; -int LLAgent::lure_z; -std::string LLAgent::lure_maturity; - -// - BOOL LLAgent::exlPhantom = 0; BOOL LLAgent::mForceTPose = 0; LLVector3 LLAgent::exlStartMeasurePoint = LLVector3::zero; @@ -300,34 +184,20 @@ void LLAgentFriendObserver::changed(U32 mask) // LLAgent() //----------------------------------------------------------------------------- LLAgent::LLAgent() : - mDrawDistance( DEFAULT_FAR_PLANE ), - mGroupPowers(0), mHideGroupTitle(FALSE), mGroupID(), - mMapOriginX(0.F), - mMapOriginY(0.F), - mMapWidth(0), - mMapHeight(0), - - mLookAt(NULL), - mPointAt(NULL), - - mHUDTargetZoom(1.f), - mHUDCurZoom(1.f), mInitialized(FALSE), - mNumPendingQueries(0), - mActiveCacheQueries(NULL), - mForceMouselook(FALSE), mDoubleTapRunTimer(), mDoubleTapRunMode(DOUBLETAP_NONE), mbAlwaysRun(false), mbRunning(false), + mbTeleportKeepsLookAt(false), - mAgentAccess(gSavedSettings), + mAgentAccess(new LLAgentAccess(gSavedSettings)), mTeleportState( TELEPORT_NONE ), mRegionp(NULL), @@ -342,78 +212,18 @@ LLAgent::LLAgent() : mRenderState(0), mTypingTimer(), - mCameraMode( CAMERA_MODE_THIRD_PERSON ), - mLastCameraMode( CAMERA_MODE_THIRD_PERSON ), mViewsPushed(FALSE), mCustomAnim(FALSE), mShowAvatar(TRUE), - mCameraAnimating( FALSE ), - mAnimationCameraStartGlobal(), - mAnimationFocusStartGlobal(), - mAnimationTimer(), - mAnimationDuration(0.33f), - - mCameraFOVZoomFactor(0.f), - mCameraCurrentFOVZoomFactor(0.f), - mCameraFocusOffset(), - mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW), - - mCameraOffsetDefault(), - 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(), mIsBusy(FALSE), - mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed - mWalkKey(0), // like AtKey, but causes less forward thrust - mLeftKey(0), - mUpKey(0), - mYawKey(0.f), - mPitchKey(0), - - 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), - mControlFlags(0x00000000), mbFlagsDirty(FALSE), mbFlagsNeedReset(FALSE), - mbJump(FALSE), - mAutoPilot(FALSE), mAutoPilotFlyOnStop(FALSE), mAutoPilotTargetGlobal(), @@ -426,7 +236,7 @@ LLAgent::LLAgent() : mAutoPilotFinishedCallback(NULL), mAutoPilotCallbackData(NULL), - mEffectColor(0.f, 1.f, 1.f, 1.f), + mEffectColor(new LLColor4(0.f, 1.f, 1.f, 1.f)), mHaveHomePosition(FALSE), mHomeRegionHandle( 0 ), @@ -436,27 +246,15 @@ LLAgent::LLAgent() : mCurrentFidget(0), mFirstLogin(FALSE), mGenderChosen(FALSE), - - mAgentWearablesUpdateSerialNum(0), - mWearablesLoaded(FALSE), - mTextureCacheQueryID(0), mAppearanceSerialNum(0), - mbTeleportKeepsLookAt(false) + + mPendingLure(NULL) { - U32 i; - for (i = 0; i < TOTAL_CONTROLS; i++) + for (U32 i = 0; i < TOTAL_CONTROLS; i++) { mControlsTakenCount[i] = 0; mControlsTakenPassedOnCount[i] = 0; } - - mActiveCacheQueries = new S32[BAKED_NUM_INDICES]; - for (i = 0; i < (U32)BAKED_NUM_INDICES; i++) - { - mActiveCacheQueries[i] = 0; - } - - mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT ); } // Requires gSavedSettings to be initialized. @@ -465,30 +263,14 @@ LLAgent::LLAgent() : //----------------------------------------------------------------------------- void LLAgent::init() { - mDrawDistance = gSavedSettings.getF32("RenderFarClip"); - - // *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->getDisplayAspectRatio() ); // default, overridden in LLViewerWindow::reshape - LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape setFlying( gSavedSettings.getBOOL("FlyingAtExit") ); - mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild")); - mCameraOffsetDefault = gSavedSettings.getVector3("CameraOffsetDefault"); - mCameraCollidePlane.clearVec(); - mCurrentCameraDistance = mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"); - mTargetCameraDistance = mCurrentCameraDistance; - mCameraZoomFraction = 1.f; - mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); + // LLDebugVarMessageBox::show("Camera Lag", &CAMERA_FOCUS_HALF_LIFE, 0.5f, 0.01f); - mEffectColor = gSavedSettings.getColor4("EffectColor"); + *mEffectColor = gSavedSettings.getColor4("EffectColor"); mInitialized = TRUE; } @@ -498,20 +280,11 @@ 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); + if(mPendingLure) + delete mPendingLure; + mPendingLure = NULL; } //----------------------------------------------------------------------------- @@ -521,87 +294,12 @@ LLAgent::~LLAgent() { cleanup(); - delete [] mActiveCacheQueries; - mActiveCacheQueries = NULL; - - // *Note: this is where LLViewerCamera::getInstance() used to be deleted. + delete mAgentAccess; + mAgentAccess = NULL; + delete mEffectColor; + mEffectColor = NULL; } -// Change camera back to third person, stop the autopilot, -// deselect stuff, etc. -//----------------------------------------------------------------------------- -// resetView() -//----------------------------------------------------------------------------- -void LLAgent::resetView(BOOL reset_camera, BOOL change_camera) -{ - if (mAutoPilot) - { - 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(); - } - - if (gMenuHolder != NULL) - { - // Hide all popup menus - gMenuHolder->hideMenus(); - } - } - - static const LLCachedControl freeze_time("FreezeTime",false); - if (change_camera && !freeze_time) - { - changeCameraToDefault(); - - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - handle_toggle_flycam(); - } - - // reset avatar mode from eventual residual motion - if (LLToolMgr::getInstance()->inBuildMode()) - { - LLViewerJoystick::getInstance()->moveAvatar(true); - } - - gFloaterTools->close(); - - gViewerWindow->showCursor(); - - // Switch back to basic toolset - LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); - } - - if (reset_camera && !freeze_time) - { - if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson()) - { - // leaving mouse-steer mode - LLVector3 agent_at_axis = getAtAxis(); - agent_at_axis -= projected_vec(agent_at_axis, getReferenceUpVector()); - agent_at_axis.normalize(); - gAgent.resetAxes(lerp(getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f))); - } - - setFocusOnAvatar(TRUE, ANIMATE); - - mCameraFOVZoomFactor = 0.f; - } - - mHUDTargetZoom = 1.f; -} // Handle any actions that need to be performed when the main app gains focus // (such as through alt-tab). @@ -610,9 +308,9 @@ void LLAgent::resetView(BOOL reset_camera, BOOL change_camera) //----------------------------------------------------------------------------- void LLAgent::onAppFocusGained() { - if (CAMERA_MODE_MOUSELOOK == mCameraMode) + if (CAMERA_MODE_MOUSELOOK == gAgentCamera.getCameraMode()) { - changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); LLToolMgr::getInstance()->clearSavedTool(); } } @@ -629,22 +327,6 @@ void LLAgent::ageChat() } } -// Allow camera to be moved somewhere other than behind avatar. -//----------------------------------------------------------------------------- -// unlockView() -//----------------------------------------------------------------------------- -void LLAgent::unlockView() -{ - if (getFocusOnAvatar()) - { - if (isAgentAvatarValid()) - { - setFocusGlobal( LLVector3d::zero, mAvatarObject->mID ); - } - setFocusOnAvatar(FALSE, FALSE); // no animation - } -} - //----------------------------------------------------------------------------- // moveAt() @@ -654,7 +336,7 @@ void LLAgent::moveAt(S32 direction, bool reset) // age chat timer so it fades more quickly when you are intentionally moving ageChat(); - setKey(direction, mAtKey); + gAgentCamera.setAtKey(LLAgentCamera::directionToKey(direction)); if (direction > 0) { @@ -667,7 +349,7 @@ void LLAgent::moveAt(S32 direction, bool reset) if (reset) { - resetView(); + gAgentCamera.resetView(); } } @@ -679,7 +361,7 @@ void LLAgent::moveAtNudge(S32 direction) // age chat timer so it fades more quickly when you are intentionally moving ageChat(); - setKey(direction, mWalkKey); + gAgentCamera.setWalkKey(LLAgentCamera::directionToKey(direction)); if (direction > 0) { @@ -690,7 +372,7 @@ void LLAgent::moveAtNudge(S32 direction) setControlFlags(AGENT_CONTROL_NUDGE_AT_NEG); } - resetView(); + gAgentCamera.resetView(); } //----------------------------------------------------------------------------- @@ -701,7 +383,7 @@ void LLAgent::moveLeft(S32 direction) // age chat timer so it fades more quickly when you are intentionally moving ageChat(); - setKey(direction, mLeftKey); + gAgentCamera.setLeftKey(LLAgentCamera::directionToKey(direction)); if (direction > 0) { @@ -712,7 +394,7 @@ void LLAgent::moveLeft(S32 direction) setControlFlags(AGENT_CONTROL_LEFT_NEG | AGENT_CONTROL_FAST_LEFT); } - resetView(); + gAgentCamera.resetView(); } //----------------------------------------------------------------------------- @@ -723,7 +405,7 @@ void LLAgent::moveLeftNudge(S32 direction) // age chat timer so it fades more quickly when you are intentionally moving ageChat(); - setKey(direction, mLeftKey); + gAgentCamera.setLeftKey(LLAgentCamera::directionToKey(direction)); if (direction > 0) { @@ -734,7 +416,7 @@ void LLAgent::moveLeftNudge(S32 direction) setControlFlags(AGENT_CONTROL_NUDGE_LEFT_NEG); } - resetView(); + gAgentCamera.resetView(); } //----------------------------------------------------------------------------- @@ -745,7 +427,7 @@ void LLAgent::moveUp(S32 direction) // age chat timer so it fades more quickly when you are intentionally moving ageChat(); - setKey(direction, mUpKey); + gAgentCamera.setUpKey(LLAgentCamera::directionToKey(direction)); if (direction > 0) { @@ -756,7 +438,7 @@ void LLAgent::moveUp(S32 direction) setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP); } - resetView(); + gAgentCamera.resetView(); } //----------------------------------------------------------------------------- @@ -764,7 +446,7 @@ void LLAgent::moveUp(S32 direction) //----------------------------------------------------------------------------- void LLAgent::moveYaw(F32 mag, bool reset_view) { - mYawKey = mag; + gAgentCamera.setYawKey(mag); if (mag > 0) { @@ -777,22 +459,22 @@ void LLAgent::moveYaw(F32 mag, bool reset_view) if (reset_view) { - resetView(); + gAgentCamera.resetView(); } } //----------------------------------------------------------------------------- // movePitch() //----------------------------------------------------------------------------- -void LLAgent::movePitch(S32 direction) +void LLAgent::movePitch(F32 mag) { - setKey(direction, mPitchKey); + gAgentCamera.setPitchKey(mag); - if (direction > 0) + if (mag > 0) { setControlFlags(AGENT_CONTROL_PITCH_POS ); } - else if (direction < 0) + else if (mag < 0) { setControlFlags(AGENT_CONTROL_PITCH_NEG); } @@ -828,6 +510,11 @@ BOOL LLAgent::canFly() return parcel->getAllowFly(); } +BOOL LLAgent::getFlying() const +{ + return mControlFlags & AGENT_CONTROL_FLY; +} + // Better Set Phantom options ~Charbl void LLAgent::setPhantom(BOOL phantom) { @@ -910,10 +597,26 @@ void LLAgent::setFlying(BOOL fly) //----------------------------------------------------------------------------- void LLAgent::toggleFlying() { - BOOL fly = !(mControlFlags & AGENT_CONTROL_FLY); + BOOL fly = !gAgent.getFlying(); - setFlying( fly ); - resetView(); + gAgent.setFlying( fly ); + gAgentCamera.resetView(); +} + +// static +bool LLAgent::enableFlying() +{ + BOOL sitting = FALSE; + if (isAgentAvatarValid()) + { + sitting = gAgent.getAvatarObject()->isSitting(); + } + return !sitting; +} + +void LLAgent::standUp() +{ + setControlFlags(AGENT_CONTROL_STAND_UP); } void LLAgent::togglePhantom() @@ -1150,16 +853,6 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent) } } -//----------------------------------------------------------------------------- -// slamLookAt() -//----------------------------------------------------------------------------- -void LLAgent::slamLookAt(const LLVector3 &look_at) -{ - LLVector3 look_at_norm = look_at; - look_at_norm.mV[VZ] = 0.f; - look_at_norm.normalize(); - resetAxes(look_at_norm); -} //----------------------------------------------------------------------------- // getPositionGlobal() @@ -1229,6 +922,11 @@ LLVector3d LLAgent::getPosGlobalFromAgent(const LLVector3 &pos_agent) const return pos_agent_d + mAgentOriginGlobal; } +void LLAgent::sitDown() +{ + setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); +} + //----------------------------------------------------------------------------- // resetAxes() @@ -1315,7 +1013,7 @@ LLVector3 LLAgent::getReferenceUpVector() mAvatarObject->getParent() && mAvatarObject->mDrawable.notNull()) { - U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode; + U32 camera_mode = gAgentCamera.getCameraAnimating() ? gAgentCamera.getLastCameraMode() : gAgentCamera.getCameraMode(); // and in third person... if (camera_mode == CAMERA_MODE_THIRD_PERSON) { @@ -1414,730 +1112,6 @@ LLQuaternion LLAgent::getQuat() const return mFrameAgent.getQuaternion(); } - -//----------------------------------------------------------------------------- -// calcFocusOffset() -//----------------------------------------------------------------------------- -LLVector3 LLAgent::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 LLAgent::calcCameraMinDistance(F32 &obj_min_distance) -{ - /* Emerald: - We don't care about minimum distances in Emerald. No we don't. - ~Zwag - */ - BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars) - - if (!mFocusObject || mFocusObject->isDead() || gSavedSettings.getBOOL("DisableCameraConstraints")) - { - 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() - 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 LLAgent::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 (gSavedSettings.getBOOL("AscentDisableMinZoomDist")) - { - return mCameraZoomFraction; - } - 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 = 65535.f*4.f;//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 LLAgent::setCameraZoomFraction(F32 fraction) -{ - // 0.f -> camera zoomed all the way out - // 1.f -> camera zoomed all the way in - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - BOOL disable_min = gSavedSettings.getBOOL("AscentDisableMinZoomDist"); - if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) - { - mHUDTargetZoom = fraction; - } - else if (mFocusOnAvatar && cameraThirdPerson() && !disable_min) - { - 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 (!disable_min) - { - if (mFocusObject.notNull()) - { - if (mFocusObject->isAvatar()) - { - min_zoom = AVATAR_MIN_ZOOM; - } - else - { - min_zoom = OBJECT_MIN_ZOOM; - } - } - } - else - { - min_zoom = 0.f; - } - LLVector3d camera_offset_dir = mCameraFocusOffsetTarget; - camera_offset_dir.normalize(); - //mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom); - mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 65535.*4., 1.f, min_zoom); - } - startCameraAnimation(); -} - - -//----------------------------------------------------------------------------- -// cameraOrbitAround() -//----------------------------------------------------------------------------- -void LLAgent::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)) - { - mFrameAgent.rotate(radians, getReferenceUpVector()); - } - else - { - mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f); - - cameraZoomIn(1.f); - } -} - - -//----------------------------------------------------------------------------- -// cameraOrbitOver() -//----------------------------------------------------------------------------- -void LLAgent::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) - { - pitch(angle); - } - else - { - LLVector3 camera_offset_unit(mCameraFocusOffsetTarget); - camera_offset_unit.normalize(); - - F32 angle_from_up = acos( camera_offset_unit * 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 LLAgent::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 = 0.f;//LAND_MIN_ZOOM; - F32 current_distance = (F32)camera_offset_unit.normalize(); - F32 new_distance = current_distance * fraction; - - if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist")) - { - 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*/ INT_MAX - DIST_FUDGE//, - /*LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE )*/; - - if (new_distance > max_distance) - { - // screw cam constraints - //new_distance = max_distance; - // - - /* - // Unless camera is unlocked - if (!LLViewerCamera::sDisableCameraConstraints) - { - return; - } - */ - } - - mCameraFocusOffsetTarget = new_distance * camera_offset_unit; -} - -//----------------------------------------------------------------------------- -// cameraOrbitIn() -//----------------------------------------------------------------------------- -void LLAgent::cameraOrbitIn(const F32 meters) -{ - if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) - { - F32 camera_offset_dist = llmax(0.001f, mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale")); - - mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist; - - static const LLCachedControl freeze_time("FreezeTime",false); - if (!freeze_time && 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 LLAgent::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 LLAgent::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 LLAgent::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(); -} - -//----------------------------------------------------------------------------- -// setKey() -//----------------------------------------------------------------------------- -void LLAgent::setKey(const S32 direction, S32 &key) -{ - if (direction > 0) - { - key = 1; - } - else if (direction < 0) - { - key = -1; - } - else - { - key = 0; - } -} - - //----------------------------------------------------------------------------- // getControlFlags() //----------------------------------------------------------------------------- @@ -2317,7 +1291,13 @@ BOOL LLAgent::getBusy() const //----------------------------------------------------------------------------- // startAutoPilotGlobal() //----------------------------------------------------------------------------- -void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::string& behavior_name, const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *), void *callback_data, F32 stop_distance, F32 rot_threshold) +void LLAgent::startAutoPilotGlobal( + const LLVector3d &target_global, + const std::string& behavior_name, + const LLQuaternion *target_rotation, + void (*finish_callback)(BOOL, void *), + void *callback_data, + F32 stop_distance, F32 rot_threshold) { if (!isAgentAvatarValid()) { @@ -2447,7 +1427,7 @@ void LLAgent::stopAutoPilot(BOOL user_cancel) //NB: auto pilot can terminate for a reason other than reaching the destination if (mAutoPilotFinishedCallback) { - mAutoPilotFinishedCallback(!user_cancel && dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData); + mAutoPilotFinishedCallback(!user_cancel && dist_vec_squared(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < (mAutoPilotStopDistance * mAutoPilotStopDistance), mAutoPilotCallbackData); } mLeaderID = LLUUID::null; @@ -2630,22 +1610,22 @@ void LLAgent::propagate(const F32 dt) LLFloaterMove *floater_move = LLFloaterMove::getInstance(); if (floater_move) { - floater_move->mForwardButton ->setToggleState( mAtKey > 0 || mWalkKey > 0 ); - floater_move->mBackwardButton ->setToggleState( mAtKey < 0 || mWalkKey < 0 ); - floater_move->mSlideLeftButton ->setToggleState( mLeftKey > 0 ); - floater_move->mSlideRightButton->setToggleState( mLeftKey < 0 ); - floater_move->mTurnLeftButton ->setToggleState( mYawKey > 0.f ); - floater_move->mTurnRightButton ->setToggleState( mYawKey < 0.f ); - floater_move->mMoveUpButton ->setToggleState( mUpKey > 0 ); - floater_move->mMoveDownButton ->setToggleState( mUpKey < 0 ); + floater_move->mForwardButton ->setToggleState( gAgentCamera.getAtKey() > 0 || gAgentCamera.getWalkKey() > 0 ); + floater_move->mBackwardButton ->setToggleState( gAgentCamera.getAtKey() < 0 || gAgentCamera.getWalkKey() < 0 ); + floater_move->mTurnLeftButton ->setToggleState( gAgentCamera.getYawKey() > 0.f ); + floater_move->mTurnRightButton ->setToggleState( gAgentCamera.getYawKey() < 0.f ); + floater_move->mSlideLeftButton ->setToggleState( gAgentCamera.getLeftKey() > 0.f ); + floater_move->mSlideRightButton ->setToggleState( gAgentCamera.getLeftKey() < 0.f ); + floater_move->mMoveUpButton ->setToggleState( gAgentCamera.getUpKey() > 0 ); + floater_move->mMoveDownButton ->setToggleState( gAgentCamera.getUpKey() < 0 ); } // handle rotation based on keyboard levels const F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second - yaw( YAW_RATE * mYawKey * dt ); + yaw(YAW_RATE * gAgentCamera.getYawKey() * dt); const F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second - pitch(PITCH_RATE * (F32) mPitchKey * dt); + pitch(PITCH_RATE * gAgentCamera.getPitchKey() * dt); // handle auto-land behavior if (mAvatarObject.notNull()) @@ -2655,7 +1635,7 @@ void LLAgent::propagate(const F32 dt) land_vel.mV[VZ] = 0.f; if (!in_air - && mUpKey < 0 + && gAgentCamera.getUpKey() < 0 && land_vel.magVecSquared() < MAX_VELOCITY_AUTO_LAND_SQUARED && gSavedSettings.getBOOL("AutomaticFly")) { @@ -2664,13 +1644,7 @@ void LLAgent::propagate(const F32 dt) } } - // clear keys - mAtKey = 0; - mWalkKey = 0; - mLeftKey = 0; - mUpKey = 0; - mYawKey = 0.f; - mPitchKey = 0; + gAgentCamera.clearGeneralKeys(); } //----------------------------------------------------------------------------- @@ -2688,76 +1662,9 @@ 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); + gAgentCamera.updateLookAt(mouse_x, mouse_y); } -//----------------------------------------------------------------------------- -// updateLookAt() -//----------------------------------------------------------------------------- -void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y) -{ - static LLVector3 last_at_axis; - - if (!isAgentAvatarValid()) return; - - LLQuaternion av_inv_rot = ~mAvatarObject->mRoot.getWorldRotation(); - LLVector3 root_at = LLVector3::x_axis * mAvatarObject->mRoot.getWorldRotation(); - - if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) && - (root_at * last_at_axis > 0.95f )) - { - LLVector3 vel = mAvatarObject->getVelocity(); - if (vel.magVecSquared() > 4.f) - { - setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, vel * av_inv_rot); - } - else - { - // *FIX: rotate mframeagent by sit object's rotation? - LLQuaternion look_rotation = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : 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, mAvatarObject, look_offset); - } - last_at_axis = root_at; - return; - } - - last_at_axis = root_at; - - if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode()) - { - setLookAt(LOOKAT_TARGET_NONE, 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->getWindowWidth() ) - 0.5f; - F32 y_from_center = - ((F32) mouse_y / (F32) gViewerWindow->getWindowHeight() ) - 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, mAvatarObject, headLookAxis); - } -} // friends and operators @@ -2789,26 +1696,7 @@ void LLAgent::setAvatarObject(LLVOAvatar *avatar) llinfos << "Setting LLAgent::mAvatarObject to NULL" << llendl; return; } - - if (!mLookAt) - { - mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); - } - if (!mPointAt) - { - mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); - } - - if (!mLookAt.isNull()) - { - mLookAt->setSourceObject(avatar); - } - if (!mPointAt.isNull()) - { - mPointAt->setSourceObject(avatar); - } - - sendAgentWearablesRequest(); + gAgentCamera.setAvatarObject(avatar); } // TRUE if your own avatar needs to be rendered. Usually only @@ -2818,7 +1706,7 @@ void LLAgent::setAvatarObject(LLVOAvatar *avatar) //----------------------------------------------------------------------------- BOOL LLAgent::needsRenderAvatar() { - if (cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson) + if (gAgentCamera.cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson) { return FALSE; } @@ -2829,7 +1717,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 && !gAgentCamera.cameraMouselook()); } //----------------------------------------------------------------------------- @@ -2853,7 +1741,7 @@ void LLAgent::startTyping() LLVOAvatar* chatter = gObjectList.findAvatar(mLastChatterID); if (chatter) { - gAgent.setLookAt(LOOKAT_TARGET_RESPOND, chatter, LLVector3::zero); + gAgentCamera.setLookAt(LOOKAT_TARGET_RESPOND, chatter, LLVector3::zero); } } @@ -2939,14 +1827,14 @@ static const LLFloaterView::skip_list_t& get_skip_list() //----------------------------------------------------------------------------- void LLAgent::endAnimationUpdateUI() { - if (mCameraMode == mLastCameraMode) + if (gAgentCamera.getCameraMode() == gAgentCamera.getLastCameraMode()) { // We're already done endAnimationUpdateUI for this transition. return; } // clean up UI from mode we're leaving - if ( mLastCameraMode == CAMERA_MODE_MOUSELOOK ) + if (gAgentCamera.getLastCameraMode() == CAMERA_MODE_MOUSELOOK ) { // show mouse cursor gViewerWindow->showCursor(); @@ -2963,7 +1851,7 @@ void LLAgent::endAnimationUpdateUI() gFloaterView->popVisibleAll(get_skip_list()); } - gAgent.setLookAt(LOOKAT_TARGET_CLEAR); + gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); if( gMorphView ) { gMorphView->setVisible( FALSE ); @@ -2997,8 +1885,7 @@ void LLAgent::endAnimationUpdateUI() } } } - else - if( mLastCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR ) + else if (gAgentCamera.getLastCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { // make sure we ask to save changes @@ -3027,20 +1914,20 @@ void LLAgent::endAnimationUpdateUI() } } - setLookAt(LOOKAT_TARGET_CLEAR); + gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); } //--------------------------------------------------------------------- // Set up UI for mode we're entering //--------------------------------------------------------------------- - if (mCameraMode == CAMERA_MODE_MOUSELOOK) + if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) { // hide menus gMenuBarView->setVisible(FALSE); gStatusBar->setVisibleForMouselook(false); // clear out camera lag effect - mCameraLag.clearVec(); + gAgentCamera.clearCameraLag(); // JC - Added for always chat in third person option gFocusMgr.setKeyboardFocus(NULL); @@ -3100,7 +1987,7 @@ void LLAgent::endAnimationUpdateUI() } } - else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR) + else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); @@ -3129,1561 +2016,17 @@ void LLAgent::endAnimationUpdateUI() if (isAgentAvatarValid()) { - mAvatarObject->updateAttachmentVisibility(mCameraMode); + gAgent.getAvatarObject()->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } gFloaterTools->dirty(); // Don't let this be called more than once if the camera // mode hasn't changed. --JC - mLastCameraMode = mCameraMode; - + gAgentCamera.updateLastCamera(); } -//----------------------------------------------------------------------------- -// updateCamera() -//----------------------------------------------------------------------------- -void LLAgent::updateCamera() -{ - //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 (isAgentAvatarValid() && - mAvatarObject->isSitting() && - camera_mode == CAMERA_MODE_MOUSELOOK) - { - //Ventrella - //changed camera_skyward to the new global "mCameraUpVector" - mCameraUpVector = mCameraUpVector * 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::getInstance()->mRotate->setToggleState( - mOrbitRightKey > 0.f, // left - mOrbitUpKey > 0.f, // top - mOrbitLeftKey > 0.f, // right - mOrbitDownKey > 0.f); // bottom - - LLFloaterCamera::getInstance()->mZoom->setToggleState( - mOrbitInKey > 0.f, // top - mOrbitOutKey > 0.f); // bottom - - LLFloaterCamera::getInstance()->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 (isAgentAvatarValid()) - { - //-------------------------------------------------------------------------------- - // 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 = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); - - LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams(); - if (current_cam) - { - mFollowCam.copyParams(*current_cam); - mFollowCam.setSubjectPositionAndRotation( 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 = 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); - - 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 ) - { - 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; - - endAnimationUpdateUI(); - mShowAvatar = TRUE; - } - - if (getAvatarObject() && mCameraMode != CAMERA_MODE_MOUSELOOK) - { - getAvatarObject()->updateAttachmentVisibility(mCameraMode); - } - } - else - { - camera_pos_global = camera_target_global; - mFocusGlobal = focus_target_global; - mShowAvatar = TRUE; - } - - // smoothing - if (TRUE) - { - LLVector3d agent_pos = 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 = getPosAgentFromGlobal(mFocusGlobal); - - mCameraPositionAgent = 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 = getPositionGlobal(); - if (! mLastPositionGlobal.isExactlyZero()) - { - LLVector3d delta = global_pos - mLastPositionGlobal; - mDistanceTraveled += delta.magVec(); - } - mLastPositionGlobal = global_pos; - - if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->isSitting() && cameraMouselook()) - { - LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() + - LLVector3(0.08f, 0.f, 0.05f) * mAvatarObject->mHeadp->getWorldRotation() + - LLVector3(0.1f, 0.f, 0.f) * mAvatarObject->mPelvisp->getWorldRotation(); - LLVector3 diff = mCameraPositionAgent - head_pos; - diff = diff * ~mAvatarObject->mRoot.getWorldRotation(); - - LLJoint* torso_joint = mAvatarObject->mTorsop; - LLJoint* chest_joint = mAvatarObject->mChestp; - LLVector3 torso_scale = torso_joint->getScale(); - LLVector3 chest_scale = chest_joint->getScale(); - - // shorten avatar skeleton to avoid foot interpenetration - if (!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 = 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; - } - - mAvatarObject->mPelvisp->setPosition(mAvatarObject->mPelvisp->getPosition() + diff); - - mAvatarObject->mRoot.updateWorldMatrixChildren(); - - for (LLVOAvatar::attachment_map_t::iterator iter = mAvatarObject->mAttachmentPoints.begin(); - iter != 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 LLAgent::updateLastCamera() -{ - mLastCameraMode = mCameraMode; -} - -void LLAgent::updateFocusOffset() -{ - validateFocusObject(); - if (mFocusObject.notNull()) - { - LLVector3d obj_pos = getPosGlobalFromAgent(mFocusObject->getRenderPosition()); - mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos); - } -} - -void LLAgent::validateFocusObject() -{ - if (mFocusObject.notNull() && - (mFocusObject->isDead())) - { - mFocusObjectOffset.clearVec(); - clearFocusObject(); - mCameraFOVZoomFactor = 0.f; - } -} - -//----------------------------------------------------------------------------- -// calcCustomizeAvatarUIOffset() -//----------------------------------------------------------------------------- -F32 LLAgent::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->getWindowWidth())))); - F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); // radians - F32 offset = tan(apparent_angle); - - if( rect.mLeft < (gViewerWindow->getWindowWidth() - 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, gAgent.getFocusGlobal()); - mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f)); - return mUIOffset * range; -} - -//----------------------------------------------------------------------------- -// calcFocusPositionTargetGlobal() -//----------------------------------------------------------------------------- -LLVector3d LLAgent::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 = mFrameAgent.getQuaternion(); - if (mAvatarObject.notNull() && mAvatarObject->getParent()) - { - LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot(); - if (!root_object->flagCameraDecoupled()) - { - agent_rot *= ((LLViewerObject*)(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(getPosGlobalFromAgent(focus_agent)); - } - return mFocusTargetGlobal; - } - else if (mSitCameraEnabled && mAvatarObject.notNull() && 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 getPosGlobalFromAgent(target_pos); - } - else - { - return getPositionGlobal() + calcThirdPersonFocusOffset(); - } -} - -LLVector3d LLAgent::calcThirdPersonFocusOffset() -{ - // ...offset from avatar - LLVector3d focus_offset; - focus_offset.setVec(gSavedSettings.getVector3("FocusOffsetDefault")); - - LLQuaternion agent_rot = mFrameAgent.getQuaternion(); - if (isAgentAvatarValid() && mAvatarObject->getParent()) - { - agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation(); - } - - focus_offset = focus_offset * agent_rot; - return focus_offset; -} - -void LLAgent::setupSitCamera() -{ - // agent frame entering this function is in world coordinates - if (isAgentAvatarValid() && mAvatarObject->getParent()) - { - LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation(); - // slam agent coordinate frame to proper parent local version - LLVector3 at_axis = mFrameAgent.getAtAxis(); - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - resetAxes(at_axis * ~parent_rot); - } -} - -//----------------------------------------------------------------------------- -// getCameraPositionAgent() -//----------------------------------------------------------------------------- -const LLVector3 &LLAgent::getCameraPositionAgent() const -{ - return LLViewerCamera::getInstance()->getOrigin(); -} - -//----------------------------------------------------------------------------- -// getCameraPositionGlobal() -//----------------------------------------------------------------------------- -LLVector3d LLAgent::getCameraPositionGlobal() const -{ - return getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()); -} - -//----------------------------------------------------------------------------- -// calcCameraFOVZoomFactor() -//----------------------------------------------------------------------------- -F32 LLAgent::calcCameraFOVZoomFactor() -{ - LLVector3 camera_offset_dir; - camera_offset_dir.setVec(mCameraFocusOffset); - - if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - return 0.f; - } - else if (mFocusObject.notNull() && !mFocusObject->isAvatar()) - { - // don't FOV zoom on mostly transparent objects - LLVector3 focus_offset = mFocusObjectOffset; - F32 obj_min_dist = 0.f; - if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist")) - 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 LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit) -{ - // Compute base camera position and look-at points. - //F32 camera_land_height; - LLVector3d frame_center_global = !isAgentAvatarValid() ? getPositionGlobal() - : getPosGlobalFromAgent(mAvatarObject->mRoot.getWorldPosition()); - - LLVector3 upAxis = getUpAxis(); - 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 (!isAgentAvatarValid() || mAvatarObject->mDrawable.isNull()) - { - llwarns << "Null avatar drawable!" << llendl; - return LLVector3d::zero; - } - head_offset.clearVec(); - if (mAvatarObject->isSitting() && mAvatarObject->getParent()) - { - mAvatarObject->updateHeadOffset(); - head_offset.mdV[VX] = mAvatarObject->mHeadOffset.mV[VX]; - head_offset.mdV[VY] = mAvatarObject->mHeadOffset.mV[VY]; - head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ] + 0.1f; - const LLMatrix4& mat = ((LLViewerObject*) mAvatarObject->getParent())->getRenderMatrix(); - camera_position_global = getPosGlobalFromAgent - ((mAvatarObject->getPosition()+ - LLVector3(head_offset)*mAvatarObject->getRotation()) * mat); - } - else - { - head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ]; - if (mAvatarObject->isSitting()) - { - head_offset.mdV[VZ] += 0.1; - } - camera_position_global = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());//frame_center_global; - head_offset = head_offset * 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 - && isAgentAvatarValid() - && 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 = getPosGlobalFromAgent(target_pos); - } - else - { - local_camera_offset = mCameraZoomFraction * mCameraOffsetDefault * gSavedSettings.getF32("CameraOffsetScale"); - - // are we sitting down? - if (isAgentAvatarValid() && mAvatarObject->getParent()) - { - LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation(); - // slam agent coordinate frame to proper parent local version - LLVector3 at_axis = mFrameAgent.getAtAxis() * parent_rot; - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - resetAxes(at_axis * ~parent_rot); - - local_camera_offset = local_camera_offset * mFrameAgent.getQuaternion() * parent_rot; - } - else - { - local_camera_offset = mFrameAgent.rotateToAbsolute( local_camera_offset ); - } - - if (!mCameraCollidePlane.isExactlyZero() && (!isAgentAvatarValid() || !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 = 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 = !isAgentAvatarValid() ? LLVector3::zero : mAvatarObject->getRenderPosition(); - camera_offset.setVec( local_camera_offset ); - camera_position_global = frame_center_global + head_offset + camera_offset; - - if (isAgentAvatarValid()) - { - LLVector3d camera_lag_d; - F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE); - LLVector3 target_lag; - LLVector3 vel = getVelocity(); - - // lag by appropriate amount for flying - F32 time_in_air = mAvatarObject->mTimeInAir.getElapsedTimeF32(); - if(!mCameraAnimating && mAvatarObject->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) - { - LLVector3 frame_at_axis = mFrameAgent.getAtAxis(); - frame_at_axis -= projected_vec(frame_at_axis, 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 == 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 (hit_limit) - { - *hit_limit = isConstrained; - } - - return camera_position_global; -} - - -//----------------------------------------------------------------------------- -// handleScrollWheel() -//----------------------------------------------------------------------------- -void LLAgent::handleScrollWheel(S32 clicks) -{ - if ( mCameraMode == CAMERA_MODE_FOLLOW && gAgent.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 current_zoom_fraction = mTargetCameraDistance / (mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale")); - current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks); - - cameraOrbitIn(current_zoom_fraction * mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale")); - } - else - { - F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec(); - cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks))); - } - } -} - - -//----------------------------------------------------------------------------- -// getCameraMinOffGround() -//----------------------------------------------------------------------------- -F32 LLAgent::getCameraMinOffGround() -{ - if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - return 0.f; - } - else - { - if (gSavedSettings.getBOOL("DisableCameraConstraints")) - { - return -1000.f; - } - else - { - return 0.5f; - } - } -} - - -//----------------------------------------------------------------------------- -// resetCamera() -//----------------------------------------------------------------------------- -void LLAgent::resetCamera() -{ - // Remove any pitch from the avatar - LLVector3 at = 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 LLAgent::changeCameraToMouselook(BOOL animate) -{ - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - - // visibility changes at end of animation - gViewerWindow->getWindow()->resetBusyCount(); - - // Menus should not remain open on switching to mouselook... - LLMenuGL::sMenuContainer->hideMenus(); - - // unpause avatar animation - mPauseRequest = NULL; - - LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); - - gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); - gSavedSettings.setBOOL("MouselookBtnState", TRUE); - gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE); - gSavedSettings.setBOOL("BuildBtnState", FALSE); - - if (mAvatarObject.notNull()) - { - mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE ); - mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT ); - } - - //gViewerWindow->stopGrab(); - LLSelectMgr::getInstance()->deselectAll(); - gViewerWindow->hideCursor(); - gViewerWindow->moveCursorToCenter(); - - if( mCameraMode != CAMERA_MODE_MOUSELOOK ) - { - gFocusMgr.setKeyboardFocus( NULL ); - if (gSavedSettings.getBOOL("AONoStandsInMouselook")) LLFloaterAO::stopMotion(LLFloaterAO::getCurrentStandId(), FALSE,TRUE); - - updateLastCamera(); - mCameraMode = CAMERA_MODE_MOUSELOOK; - U32 old_flags = mControlFlags; - setControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != mControlFlags) - { - mbFlagsDirty = TRUE; - } - - if (animate) - { - startCameraAnimation(); - } - else - { - mCameraAnimating = FALSE; - endAnimationUpdateUI(); - } - } -} - - -//----------------------------------------------------------------------------- -// changeCameraToDefault() -//----------------------------------------------------------------------------- -void LLAgent::changeCameraToDefault() -{ - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - - if (LLFollowCamMgr::getActiveFollowCamParams()) - { - changeCameraToFollow(); - } - else - { - changeCameraToThirdPerson(); - } -} - - -// Ventrella -//----------------------------------------------------------------------------- -// changeCameraToFollow() -//----------------------------------------------------------------------------- -void LLAgent::changeCameraToFollow(BOOL animate) -{ - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - - if( mCameraMode != CAMERA_MODE_FOLLOW ) - { - if (mCameraMode == CAMERA_MODE_MOUSELOOK) - { - animate = FALSE; - } - startCameraAnimation(); - - updateLastCamera(); - 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 (isAgentAvatarValid()) - { - mAvatarObject->mPelvisp->setPosition(LLVector3::zero); - mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE ); - mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT ); - } - - gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); - gSavedSettings.setBOOL("MouselookBtnState", FALSE); - gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE); - gSavedSettings.setBOOL("BuildBtnState", FALSE); - - // unpause avatar animation - mPauseRequest = NULL; - - U32 old_flags = mControlFlags; - clearControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != mControlFlags) - { - mbFlagsDirty = TRUE; - } - - if (animate) - { - startCameraAnimation(); - } - else - { - mCameraAnimating = FALSE; - endAnimationUpdateUI(); - } - } -} - -//----------------------------------------------------------------------------- -// changeCameraToThirdPerson() -//----------------------------------------------------------------------------- -void LLAgent::changeCameraToThirdPerson(BOOL animate) -{ - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - -// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) +SG - if ( (!gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) - && (mAvatarObject.notNull()) - && (mAvatarObject->isSitting()) - && gSavedSettings.getBOOL("SianaUnsitOnCamReset")) - { - setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up - } -// [/RLVa:KB] - - gViewerWindow->getWindow()->resetBusyCount(); - - mCameraZoomFraction = INITIAL_ZOOM_FRACTION; - - if (isAgentAvatarValid()) - { - if (!mAvatarObject->isSitting()) - { - mAvatarObject->mPelvisp->setPosition(LLVector3::zero); - } - mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE ); - mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT ); - } - - gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); - gSavedSettings.setBOOL("MouselookBtnState", FALSE); - gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE); - gSavedSettings.setBOOL("BuildBtnState", FALSE); - - LLVector3 at_axis; - - // unpause avatar animation - 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; - } - updateLastCamera(); - mCameraMode = CAMERA_MODE_THIRD_PERSON; - U32 old_flags = mControlFlags; - clearControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != mControlFlags) - { - mbFlagsDirty = TRUE; - } - - } - - // Remove any pitch from the avatar - if (isAgentAvatarValid() && mAvatarObject->getParent()) - { - LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation(); - at_axis = LLViewerCamera::getInstance()->getAtAxis(); - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - resetAxes(at_axis * ~obj_rot); - } - else - { - at_axis = mFrameAgent.getAtAxis(); - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - resetAxes(at_axis); - } - - - if (animate) - { - startCameraAnimation(); - } - else - { - mCameraAnimating = FALSE; - endAnimationUpdateUI(); - } -} - -//----------------------------------------------------------------------------- -// changeCameraToCustomizeAvatar() -//----------------------------------------------------------------------------- -void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_animate) -{ - if (LLViewerJoystick::getInstance()->getOverrideCamera()) - { - return; - } - - // - //setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up - // - gViewerWindow->getWindow()->resetBusyCount(); - - if (gFaceEditToolset) - { - LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); - } - - gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); - gSavedSettings.setBOOL("MouselookBtnState", FALSE); - gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE); - gSavedSettings.setBOOL("BuildBtnState", FALSE); - - if (camera_animate) - { - // - if(gSavedSettings.getBOOL("AppearanceCameraMovement")) - // - startCameraAnimation(); - } - - // Remove any pitch from the avatar - //LLVector3 at = 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 = mControlFlags; - clearControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != mControlFlags) - { - mbFlagsDirty = TRUE; - } - - gFocusMgr.setKeyboardFocus( NULL ); - gFocusMgr.setMouseCapture( NULL ); - - LLVOAvatar::onCustomizeStart(); - } - - if (isAgentAvatarValid()) - { - if(avatar_animate) - { - // Remove any pitch from the avatar - LLVector3 at = mFrameAgent.getAtAxis(); - at.mV[VZ] = 0.f; - at.normalize(); - gAgent.resetAxes(at); - - sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); - mCustomAnim = TRUE ; - mAvatarObject->startMotion(ANIM_AGENT_CUSTOMIZE); - LLMotion* turn_motion = mAvatarObject->findMotion(ANIM_AGENT_CUSTOMIZE); - - if (turn_motion) - { - mAnimationDuration = turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP; - - } - else - { - mAnimationDuration = gSavedSettings.getF32("ZoomTime"); - } - } - - - - gAgent.setFocusGlobal(LLVector3d::zero); - } - else - { - mCameraAnimating = FALSE; - endAnimationUpdateUI(); - } - - // - if(!gSavedSettings.getBOOL("AppearanceCameraMovement")) - { - //hmm - mCameraAnimating = FALSE; - endAnimationUpdateUI(); - } - -} - - -// -// Focus point management -// - -//----------------------------------------------------------------------------- -// startCameraAnimation() -//----------------------------------------------------------------------------- -void LLAgent::startCameraAnimation() -{ - mAnimationCameraStartGlobal = getCameraPositionGlobal(); - mAnimationFocusStartGlobal = mFocusGlobal; - mAnimationTimer.reset(); - mCameraAnimating = TRUE; - mAnimationDuration = gSavedSettings.getF32("ZoomTime"); -} - -//----------------------------------------------------------------------------- -// stopCameraAnimation() -//----------------------------------------------------------------------------- -void LLAgent::stopCameraAnimation() -{ - mCameraAnimating = FALSE; -} - -void LLAgent::clearFocusObject() -{ - if (mFocusObject.notNull()) - { - startCameraAnimation(); - - setFocusObject(NULL); - mFocusObjectOffset.clearVec(); - } -} - -void LLAgent::setFocusObject(LLViewerObject* object) -{ - mFocusObject = object; -} - -// Focus on a point, but try to keep camera position stable. -//----------------------------------------------------------------------------- -// setFocusGlobal() -//----------------------------------------------------------------------------- -void LLAgent::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 LLAgent::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 (isAgentAvatarValid()) - { - mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition()); - } - else - { - mFocusTargetGlobal = 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, (getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation()); - } - } - else - { - setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal)); - } - } - } - else // focus == mFocusTargetGlobal - { - if (focus.isExactlyZero()) - { - if (isAgentAvatarValid()) - { - mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition()); - } - else - { - mFocusTargetGlobal = 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 LLAgent::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, (getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation()); - } - } - else - { - setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal)); - } - - if( mCameraAnimating ) - { - const F64 ANIM_METERS_PER_SECOND = 10.0; - const F64 MIN_ANIM_SECONDS = 0.5; - F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND ); - setAnimationDuration( (F32)anim_duration ); - } - - updateFocusOffset(); -} - -//----------------------------------------------------------------------------- -// setSitCamera() -//----------------------------------------------------------------------------- -void LLAgent::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 LLAgent::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 (isAgentAvatarValid() && mAvatarObject->getParent()) - { - LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation(); - at_axis = LLViewerCamera::getInstance()->getAtAxis(); - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - resetAxes(at_axis * ~obj_rot); - } - else - { - at_axis = LLViewerCamera::getInstance()->getAtAxis(); - at_axis.mV[VZ] = 0.f; - at_axis.normalize(); - 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(getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID()); - } - - mFocusOnAvatar = focus_on_avatar; -} - //----------------------------------------------------------------------------- // heardChat() //----------------------------------------------------------------------------- @@ -4699,303 +2042,106 @@ void LLAgent::heardChat(const LLUUID& id) if (ll_rand(2) == 0) { LLViewerObject *chatter = gObjectList.findObject(mLastChatterID); - setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero); + gAgentCamera.setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero); } mLastChatterID = id; mChatTimer.reset(); } -//----------------------------------------------------------------------------- -// lookAtLastChat() -//----------------------------------------------------------------------------- -void LLAgent::lookAtLastChat() -{ - // Block if camera is animating or not in normal third person camera mode - if (mCameraAnimating || !cameraThirdPerson()) - { - return; - } - - LLViewerObject *chatter = gObjectList.findObject(mLastChatterID); - if (chatter) - { - LLVector3 delta_pos; - if (chatter->isAvatar()) - { - LLVOAvatar *chatter_av = (LLVOAvatar*)chatter; - if (isAgentAvatarValid() && chatter_av->mHeadp) - { - delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition(); - } - else - { - delta_pos = chatter->getPositionAgent() - getPositionAgent(); - } - delta_pos.normalize(); - - setControlFlags(AGENT_CONTROL_STOP); - - changeCameraToThirdPerson(); - - LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition(); - LLVector3 left = delta_pos % LLVector3::z_axis; - left.normalize(); - LLVector3 up = left % delta_pos; - up.normalize(); - new_camera_pos -= delta_pos * 0.4f; - new_camera_pos += left * 0.3f; - new_camera_pos += up * 0.2f; - if (chatter_av->mHeadp) - { - setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), mLastChatterID); - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); - } - else - { - setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID); - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); - } - setFocusOnAvatar(FALSE, TRUE); - } - else - { - delta_pos = chatter->getRenderPosition() - getPositionAgent(); - delta_pos.normalize(); - - setControlFlags(AGENT_CONTROL_STOP); - - changeCameraToThirdPerson(); - - LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition(); - LLVector3 left = delta_pos % LLVector3::z_axis; - left.normalize(); - LLVector3 up = left % delta_pos; - up.normalize(); - new_camera_pos -= delta_pos * 0.4f; - new_camera_pos += left * 0.3f; - new_camera_pos += up * 0.2f; - - setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID); - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); - setFocusOnAvatar(FALSE, TRUE); - } - } -} - -void LLAgent::lookAtObject(LLUUID object_id, ECameraPosition camera_pos) -{ - // Block if camera is animating or not in normal third person camera mode - if (mCameraAnimating || !cameraThirdPerson()) - { - return; - } - - LLViewerObject *chatter = gObjectList.findObject(object_id); - if (chatter) - { - LLVector3 delta_pos; - if (chatter->isAvatar()) - { - LLVOAvatar *chatter_av = (LLVOAvatar*)chatter; - if (!mAvatarObject.isNull() && chatter_av->mHeadp) - { - delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition(); - } - else - { - delta_pos = chatter->getPositionAgent() - getPositionAgent(); - } - delta_pos.normVec(); - - setControlFlags(AGENT_CONTROL_STOP); - - changeCameraToThirdPerson(); - - LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition(); - LLVector3 left = delta_pos % LLVector3::z_axis; - left.normVec(); - LLVector3 up = left % delta_pos; - up.normVec(); - new_camera_pos -= delta_pos * 0.4f; - new_camera_pos += left * 0.3f; - new_camera_pos += up * 0.2f; - - F32 radius = chatter_av->getVObjRadius(); - LLVector3d view_dist(radius, radius, 0.0f); - - if (chatter_av->mHeadp) - { - setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), object_id); - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); - - switch(camera_pos) - { - case CAMERA_POSITION_SELF: - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); - break; - case CAMERA_POSITION_OBJECT: - mCameraFocusOffsetTarget = view_dist; - break; - } - } - else - { - setFocusGlobal(chatter->getPositionGlobal(), object_id); - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); - - switch(camera_pos) - { - case CAMERA_POSITION_SELF: - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); - break; - case CAMERA_POSITION_OBJECT: - mCameraFocusOffsetTarget = view_dist; - break; - } - } - setFocusOnAvatar(FALSE, TRUE); - } - else - { - delta_pos = chatter->getRenderPosition() - getPositionAgent(); - delta_pos.normVec(); - - setControlFlags(AGENT_CONTROL_STOP); - - changeCameraToThirdPerson(); - - LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition(); - LLVector3 left = delta_pos % LLVector3::z_axis; - left.normVec(); - LLVector3 up = left % delta_pos; - up.normVec(); - new_camera_pos -= delta_pos * 0.4f; - new_camera_pos += left * 0.3f; - new_camera_pos += up * 0.2f; - - setFocusGlobal(chatter->getPositionGlobal(), object_id); - - switch(camera_pos) - { - case CAMERA_POSITION_SELF: - mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); - break; - case CAMERA_POSITION_OBJECT: - F32 radius = chatter->getVObjRadius(); - LLVector3d view_dist(radius, radius, 0.0f); - mCameraFocusOffsetTarget = view_dist; - break; - } - - setFocusOnAvatar(FALSE, TRUE); - } - } -} - const F32 SIT_POINT_EXTENTS = 0.2f; +LLSD ll_sdmap_from_vector3(const LLVector3& vec) +{ + LLSD ret; + ret["X"] = vec.mV[VX]; + ret["Y"] = vec.mV[VY]; + ret["Z"] = vec.mV[VZ]; + return ret; +} + +LLVector3 ll_vector3_from_sdmap(const LLSD& sd) +{ + LLVector3 ret; + ret.mV[VX] = F32(sd["X"].asReal()); + ret.mV[VY] = F32(sd["Y"].asReal()); + ret.mV[VZ] = F32(sd["Z"].asReal()); + return ret; +} + void LLAgent::setStartPosition( U32 location_id ) { - LLViewerObject *object; - - if ( !(gAgentID == LLUUID::null) ) - { - // we've got an ID for an agent viewerobject - object = gObjectList.findObject(gAgentID); - if (object) + if (gAgentID == LLUUID::null) { - // we've got the viewer object - // Sometimes the agent can be velocity interpolated off of - // this simulator. Clamp it to the region the agent is - // in, a little bit in on each side. - const F32 INSET = 0.5f; //meters - const F32 REGION_WIDTH = LLWorld::getInstance()->getRegionWidthInMeters(); + return; + } + if (gObjectList.findAvatar(gAgentID) == NULL) + { + llinfos << "setStartPosition - Can't find agent viewerobject id " << gAgentID << llendl; + return; + } + // we've got the viewer object + // Sometimes the agent can be velocity interpolated off of + // this simulator. Clamp it to the region the agent is + // in, a little bit in on each side. + const F32 INSET = 0.5f; //meters + const F32 REGION_WIDTH = LLWorld::getInstance()->getRegionWidthInMeters(); - LLVector3 agent_pos = getPositionAgent(); - LLVector3 agent_look_at = mFrameAgent.getAtAxis(); + LLVector3 agent_pos = getPositionAgent(); - if (isAgentAvatarValid()) - { - // the z height is at the agent's feet + if (isAgentAvatarValid()) + { + // the z height is at the agent's feet agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ]; - } + } - agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET ); - agent_pos.mV[VY] = llclamp( agent_pos.mV[VY], INSET, REGION_WIDTH - INSET ); + agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET ); + agent_pos.mV[VY] = llclamp( agent_pos.mV[VY], INSET, REGION_WIDTH - INSET ); - // Don't let them go below ground, or too high. - agent_pos.mV[VZ] = llclamp( agent_pos.mV[VZ], - mRegionp->getLandHeightRegion( agent_pos ), - LLWorld::getInstance()->getRegionMaxHeight() ); - // Send the CapReq + // Don't let them go below ground, or too high. + agent_pos.mV[VZ] = llclamp( agent_pos.mV[VZ], + mRegionp->getLandHeightRegion( agent_pos ), + LLWorld::getInstance()->getRegionMaxHeight() ); + std::string url = gAgent.getRegion()->getCapability("HomeLocation"); + if( !url.empty() ) + { + // Send the CapReq + LLSD request; + LLSD body; + LLSD homeLocation; - LLSD body; + homeLocation["LocationId"] = LLSD::Integer(location_id); + homeLocation["LocationPos"] = ll_sdmap_from_vector3(agent_pos); + homeLocation["LocationLookAt"] = ll_sdmap_from_vector3(mFrameAgent.getAtAxis()); - std::string url = gAgent.getRegion()->getCapability("HomeLocation"); - std::ostringstream strBuffer; - if( url.empty() ) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessageFast(_PREHASH_SetStartLocationRequest); - msg->nextBlockFast( _PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, getID()); - msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); - msg->nextBlockFast( _PREHASH_StartLocationData); - // corrected by sim - msg->addStringFast(_PREHASH_SimName, ""); - msg->addU32Fast(_PREHASH_LocationID, location_id); - msg->addVector3Fast(_PREHASH_LocationPos, agent_pos); - msg->addVector3Fast(_PREHASH_LocationLookAt,mFrameAgent.getAtAxis()); + body["HomeLocation"] = homeLocation; + + LLHTTPClient::post( url, body, new LLHomeLocationResponder() ); + } + else + { + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_SetStartLocationRequest); + msg->nextBlockFast( _PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, getID()); + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + msg->nextBlockFast( _PREHASH_StartLocationData); + // corrected by sim + msg->addStringFast(_PREHASH_SimName, ""); + msg->addU32Fast(_PREHASH_LocationID, location_id); + msg->addVector3Fast(_PREHASH_LocationPos, agent_pos); + msg->addVector3Fast(_PREHASH_LocationLookAt,mFrameAgent.getAtAxis()); - // Reliable only helps when setting home location. Last - // location is sent on quit, and we don't have time to ack - // the packets. - msg->sendReliable(mRegionp->getHost()); - + // Reliable only helps when setting home location. Last + // location is sent on quit, and we don't have time to ack + // the packets. + msg->sendReliable(mRegionp->getHost()); + } const U32 HOME_INDEX = 1; if( HOME_INDEX == location_id ) - { - setHomePosRegion( mRegionp->getHandle(), getPositionAgent() ); - } - } - else - { - strBuffer << location_id; - body["HomeLocation"]["LocationId"] = strBuffer.str(); - - strBuffer.str(""); - strBuffer << agent_pos.mV[VX]; - body["HomeLocation"]["LocationPos"]["X"] = strBuffer.str(); - - strBuffer.str(""); - strBuffer << agent_pos.mV[VY]; - body["HomeLocation"]["LocationPos"]["Y"] = strBuffer.str(); - - strBuffer.str(""); - strBuffer << agent_pos.mV[VZ]; - body["HomeLocation"]["LocationPos"]["Z"] = strBuffer.str(); - - strBuffer.str(""); - strBuffer << agent_look_at.mV[VX]; - body["HomeLocation"]["LocationLookAt"]["X"] = strBuffer.str(); - - strBuffer.str(""); - strBuffer << agent_look_at.mV[VY]; - body["HomeLocation"]["LocationLookAt"]["Y"] = strBuffer.str(); - - strBuffer.str(""); - strBuffer << agent_look_at.mV[VZ]; - body["HomeLocation"]["LocationLookAt"]["Z"] = strBuffer.str(); - - LLHTTPClient::post( url, body, new LLHomeLocationResponder() ); - } - } - else - { - llinfos << "setStartPosition - Can't find agent viewerobject id " << gAgentID << llendl; - } - } + { + setHomePosRegion( mRegionp->getHandle(), getPositionAgent() ); + } } void LLAgent::requestStopMotion( LLMotion* motion ) @@ -5045,29 +2191,29 @@ void LLAgent::onAnimStop(const LLUUID& id) } } -BOOL LLAgent::isGodlike() const +bool LLAgent::isGodlike() const { - return mAgentAccess.isGodlike(); + return mAgentAccess->isGodlike(); } U8 LLAgent::getGodLevel() const { - return mAgentAccess.getGodLevel(); + return mAgentAccess->getGodLevel(); } bool LLAgent::wantsPGOnly() const { - return mAgentAccess.wantsPGOnly(); + return mAgentAccess->wantsPGOnly(); } bool LLAgent::canAccessMature() const { - return mAgentAccess.canAccessMature(); + return mAgentAccess->canAccessMature(); } bool LLAgent::canAccessAdult() const { - return mAgentAccess.canAccessAdult(); + return mAgentAccess->canAccessAdult(); } bool LLAgent::canAccessMaturityInRegion( U64 region_handle ) const @@ -5102,37 +2248,37 @@ bool LLAgent::canAccessMaturityAtGlobal( LLVector3d pos_global ) const bool LLAgent::prefersPG() const { - return mAgentAccess.prefersPG(); + return mAgentAccess->prefersPG(); } bool LLAgent::prefersMature() const { - return mAgentAccess.prefersMature(); + return mAgentAccess->prefersMature(); } bool LLAgent::prefersAdult() const { - return mAgentAccess.prefersAdult(); + return mAgentAccess->prefersAdult(); } bool LLAgent::isTeen() const { - return mAgentAccess.isTeen(); + return mAgentAccess->isTeen(); } bool LLAgent::isMature() const { - return mAgentAccess.isMature(); + return mAgentAccess->isMature(); } bool LLAgent::isAdult() const { - return mAgentAccess.isAdult(); + return mAgentAccess->isAdult(); } void LLAgent::setTeen(bool teen) { - mAgentAccess.setTeen(teen); + mAgentAccess->setTeen(teen); } //static @@ -5177,32 +2323,32 @@ bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity) BOOL LLAgent::getAdminOverride() const { - return mAgentAccess.getAdminOverride(); + return mAgentAccess->getAdminOverride(); } void LLAgent::setMaturity(char text) { - mAgentAccess.setMaturity(text); + mAgentAccess->setMaturity(text); } void LLAgent::setAdminOverride(BOOL b) { - mAgentAccess.setAdminOverride(b); + mAgentAccess->setAdminOverride(b); } void LLAgent::setGodLevel(U8 god_level) { - mAgentAccess.setGodLevel(god_level); + mAgentAccess->setGodLevel(god_level); } void LLAgent::setAOTransition() { - mAgentAccess.setTransition(); + mAgentAccess->setTransition(); } const LLAgentAccess& LLAgent::getAgentAccess() { - return mAgentAccess; + return *mAgentAccess; } @@ -5430,7 +2576,7 @@ LLQuaternion LLAgent::getHeadRotation() return LLQuaternion::DEFAULT; } - if (!gAgent.cameraMouselook()) + if (!gAgentCamera.cameraMouselook()) { return mAvatarObject->getRotation(); } @@ -5610,12 +2756,12 @@ void LLAgent::getName(std::string& name) const LLColor4 &LLAgent::getEffectColor() { - return mEffectColor; + return *mEffectColor; } void LLAgent::setEffectColor(const LLColor4 &color) { - mEffectColor = color; + *mEffectColor = color; } void LLAgent::initOriginGlobal(const LLVector3d &origin_global) @@ -5623,6 +2769,41 @@ void LLAgent::initOriginGlobal(const LLVector3d &origin_global) mAgentOriginGlobal = origin_global; } +BOOL LLAgent::leftButtonGrabbed() const +{ + const BOOL camera_mouse_look = gAgentCamera.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 +{ + return (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0) + || (mControlsTakenCount[CONTROL_YAW_NEG_INDEX] > 0); +} + +BOOL LLAgent::forwardGrabbed() const +{ + return (mControlsTakenCount[CONTROL_AT_POS_INDEX] > 0); +} + +BOOL LLAgent::backwardGrabbed() const +{ + return (mControlsTakenCount[CONTROL_AT_NEG_INDEX] > 0); +} + +BOOL LLAgent::upGrabbed() const +{ + return (mControlsTakenCount[CONTROL_UP_POS_INDEX] > 0); +} + +BOOL LLAgent::downGrabbed() const +{ + return (mControlsTakenCount[CONTROL_UP_NEG_INDEX] > 0); +} + void update_group_floaters(const LLUUID& group_id) { LLFloaterGroupInfo::refreshGroup(group_id); @@ -6068,7 +3249,7 @@ void LLAgent::processControlRelease(LLMessageSystem *msg, void **) //static void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data) { - gAgent.mNumPendingQueries--; + gAgentQueryManager.mNumPendingQueries--; if (!isAgentAvatarValid()) { @@ -6076,7 +3257,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * return; } - if (gAgent.cameraCustomizeAvatar()) + if (gAgentCamera.cameraCustomizeAvatar()) { // ignore baked textures when in customize mode return; @@ -6099,12 +3280,12 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * if (texture_id.notNull() && (S32)texture_index < BAKED_NUM_INDICES - && gAgent.mActiveCacheQueries[ texture_index ] == query_id) + && gAgentQueryManager.mActiveCacheQueries[ texture_index ] == query_id) { //llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl; gAgent.getAvatarObject()->setCachedBakedTexture(getTextureIndex((EBakedTextureIndex)texture_index), texture_id); //avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id ); - gAgent.mActiveCacheQueries[ texture_index ] = 0; + gAgentQueryManager.mActiveCacheQueries[ texture_index ] = 0; num_results++; } } @@ -6113,7 +3294,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void * gAgent.getAvatarObject()->updateMeshTextures(); - if (gAgent.mNumPendingQueries == 0) + if (gAgentQueryManager.mNumPendingQueries == 0) { // RN: not sure why composites are disabled at this point gAgent.getAvatarObject()->setCompositeUpdatesEnabled(TRUE); @@ -6229,9 +3410,9 @@ bool LLAgent::teleportCore(bool is_local) // Close all pie menus, deselect land, etc. // Don't change the camera until we know teleport succeeded. JC // - if(gAgent.getFocusOnAvatar()) + if(gAgentCamera.getFocusOnAvatar()) // - resetView(FALSE); + gAgentCamera.resetView(FALSE); // local logic LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT); @@ -6458,7 +3639,7 @@ void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) // [/RLVa:KB] mbTeleportKeepsLookAt = true; - setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction U64 region_handle = to_region_handle(pos_global); LLVector3 pos_local = (LLVector3)(pos_global - from_region_handle(region_handle)); teleportRequest(region_handle, pos_local, getTeleportKeepsLookAt()); @@ -6617,968 +3798,6 @@ void LLAgent::requestLeaveGodMode() sendReliableMessage(); } -// wearables -LLAgent::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback() -{ - gAgent.createStandardWearablesAllDone(); -} - -LLAgent::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback() -{ - gAgent.sendAgentWearablesUpdate(); -} - -LLAgent::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback( - LLPointer cb, S32 index, LLWearable* wearable, U32 todo) : - mIndex(index), - mWearable(wearable), - mTodo(todo), - mCB(cb) -{ -} - -void LLAgent::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item) -{ - if (inv_item.isNull()) - return; - - gAgent.addWearabletoAgentInventoryDone(mIndex, inv_item, mWearable); - - if (mTodo & CALL_UPDATE) - { - gAgent.sendAgentWearablesUpdate(); - } - if (mTodo & CALL_RECOVERDONE) - { - gAgent.recoverMissingWearableDone(); - } - /* - * Do this for every one in the loop - */ - if (mTodo & CALL_CREATESTANDARDDONE) - { - gAgent.createStandardWearablesDone(mIndex); - } - if (mTodo & CALL_MAKENEWOUTFITDONE) - { - gAgent.makeNewOutfitDone(mIndex); - } -} - -void LLAgent::addWearabletoAgentInventoryDone( - S32 index, - const LLUUID& item_id, - LLWearable* wearable) -{ - if (item_id.isNull()) - return; - - LLUUID old_item_id = mWearableEntry[index].mItemID; - mWearableEntry[index].mItemID = item_id; - mWearableEntry[index].mWearable = wearable; - if (old_item_id.notNull()) - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - LLViewerInventoryItem* item = gInventory.getItem(item_id); - if(item && wearable) - { - // We're changing the asset id, so we both need to set it - // locally via setAssetUUID() and via setTransactionID() which - // will be decoded on the server. JC - item->setAssetUUID(wearable->getID()); - item->setTransactionID(wearable->getTransactionID()); - gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id); - item->updateServer(FALSE); - } - gInventory.notifyObservers(); -} - -void LLAgent::sendAgentWearablesUpdate() -{ - // First make sure that we have inventory items for each wearable - S32 i; - for(i=0; i < WT_COUNT; ++i) - { - LLWearable* wearable = mWearableEntry[ i ].mWearable; - if (wearable) - { - if( mWearableEntry[ i ].mItemID.isNull() ) - { - LLPointer cb = - new addWearableToAgentInventoryCallback( - LLPointer(NULL), - i, - wearable, - addWearableToAgentInventoryCallback::CALL_NONE); - addWearableToAgentInventory(cb, wearable); - } - else - { - gInventory.addChangedMask( LLInventoryObserver::LABEL, - mWearableEntry[i].mItemID ); - } - } - } - - // Then make sure the inventory is in sync with the avatar. - gInventory.notifyObservers(); - - // This isn't the proper place to be doing this, but it's a good "catch-all" - LLCOFMgr::instance().synchWearables(); - - // Send the AgentIsNowWearing - gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing); - - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); - - LL_DEBUGS("Wearables") << "sendAgentWearablesUpdate()" << LL_ENDL; - for(i=0; i < WT_COUNT; ++i) - { - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - - U8 type_u8 = (U8)i; - gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 ); - - LLWearable* wearable = mWearableEntry[ i ].mWearable; - if( wearable ) - { - LL_DEBUGS("Wearables") << "Sending wearable " << wearable->getName() << " mItemID = " << mWearableEntry[ i ].mItemID << LL_ENDL; - LLUUID item_id = mWearableEntry[i].mItemID; - const LLViewerInventoryItem *item = gInventory.getItem(item_id); - if (item && item->getIsLinkType()) - { - // Get the itemID that this item points to. i.e. make sure - // we are storing baseitems, not their links, in the database. - item_id = item->getLinkedUUID(); - } - gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); - } - else - { - LL_DEBUGS("Wearables") << "Not wearing wearable type " << LLWearable::typeToTypeName((EWearableType)i) << LL_ENDL; - gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null ); - } - - LL_DEBUGS("Wearables") << " " << LLWearable::typeToTypeLabel((EWearableType)i) << " : " << (wearable ? wearable->getID() : LLUUID::null) << LL_ENDL; - } - gAgent.sendReliableMessage(); -} - -void LLAgent::saveWearable( EWearableType type, BOOL send_update ) -{ - LLWearable* old_wearable = mWearableEntry[(S32)type].mWearable; - if( old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()) ) - { - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); - mWearableEntry[(S32)type].mWearable = new_wearable; - - LLInventoryItem* item = gInventory.getItem(mWearableEntry[(S32)type].mItemID); - if( item ) - { - // Update existing inventory item - LLPointer template_item = - new LLViewerInventoryItem(item->getUUID(), - item->getParentUUID(), - item->getPermissions(), - new_wearable->getID(), - new_wearable->getAssetType(), - item->getInventoryType(), - item->getName(), - item->getDescription(), - item->getSaleInfo(), - item->getFlags(), - item->getCreationDate()); - template_item->setTransactionID(new_wearable->getTransactionID()); - template_item->updateServer(FALSE); - gInventory.updateItem(template_item); - } - else - { - // Add a new inventory item (shouldn't ever happen here) - U32 todo = addWearableToAgentInventoryCallback::CALL_NONE; - if (send_update) - { - todo |= addWearableToAgentInventoryCallback::CALL_UPDATE; - } - LLPointer cb = - new addWearableToAgentInventoryCallback( - LLPointer(NULL), - (S32)type, - new_wearable, - todo); - addWearableToAgentInventory(cb, new_wearable); - return; - } - - getAvatarObject()->wearableUpdated( type ); - - if( send_update ) - { - sendAgentWearablesUpdate(); - } - } -} - -void LLAgent::saveWearableAs( - EWearableType type, - const std::string& new_name, - BOOL save_in_lost_and_found) -{ - if(!isWearableCopyable(type)) - { - llwarns << "LLAgent::saveWearableAs() not copyable." << llendl; - return; - } - LLWearable* old_wearable = getWearable(type); - if(!old_wearable) - { - llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; - return; - } - LLInventoryItem* item = gInventory.getItem(mWearableEntry[type].mItemID); - if(!item) - { - llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl; - return; - } - std::string trunc_name(new_name); - LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( - old_wearable, - trunc_name); - LLPointer cb = - new addWearableToAgentInventoryCallback( - LLPointer(NULL), - type, - new_wearable, - addWearableToAgentInventoryCallback::CALL_UPDATE); - LLUUID category_id; - if (save_in_lost_and_found) - { - category_id = gInventory.findCategoryUUIDForType( - LLAssetType::AT_LOST_AND_FOUND); - } - else - { - // put in same folder as original - category_id = item->getParentUUID(); - } - - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - category_id, - new_name, - cb); - -/* - LLWearable* old_wearable = getWearable( type ); - if( old_wearable ) - { - std::string old_name = old_wearable->getName(); - old_wearable->setName( new_name ); - LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); - old_wearable->setName( old_name ); - - LLUUID category_id; - LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID ); - if( item ) - { - new_wearable->setPermissions(item->getPermissions()); - if (save_in_lost_and_found) - { - category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); - } - else - { - // put in same folder as original - category_id = item->getParentUUID(); - } - LLInventoryView* view = LLInventoryView::getActiveInventory(); - if(view) - { - view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); - } - } - - mWearableEntry[ type ].mWearable = new_wearable; - LLPointer cb = - new addWearableToAgentInventoryCallback( - LLPointer(NULL), - type, - addWearableToAgentInventoryCallback::CALL_UPDATE); - addWearableToAgentInventory(cb, new_wearable, category_id); - } -*/ -} - -void LLAgent::revertWearable( EWearableType type ) -{ - LLWearable* wearable = mWearableEntry[(S32)type].mWearable; - if( wearable ) - { - wearable->writeToAvatar( TRUE ); - } - sendAgentSetAppearance(); -} - -void LLAgent::revertAllWearables() -{ - for( S32 i=0; i < WT_COUNT; i++ ) - { - revertWearable( (EWearableType)i ); - } -} - -void LLAgent::saveAllWearables() -{ - //if(!gInventory.isLoaded()) - //{ - // return; - //} - - for( S32 i=0; i < WT_COUNT; i++ ) - { - saveWearable( (EWearableType)i, FALSE ); - } - sendAgentWearablesUpdate(); -} - -// Called when the user changes the name of a wearable inventory item that is currenlty being worn. -void LLAgent::setWearableName( const LLUUID& item_id, const std::string& new_name ) -{ - for( S32 i=0; i < WT_COUNT; i++ ) - { - if( mWearableEntry[i].mItemID == item_id ) - { - LLWearable* old_wearable = mWearableEntry[i].mWearable; - llassert( old_wearable ); - - std::string old_name = old_wearable->getName(); - old_wearable->setName( new_name ); - LLWearable* new_wearable = gWearableList.createCopy( old_wearable ); - LLInventoryItem* item = gInventory.getItem(item_id); - if(item) - { - new_wearable->setPermissions(item->getPermissions()); - } - old_wearable->setName( old_name ); - - mWearableEntry[i].mWearable = new_wearable; - sendAgentWearablesUpdate(); - break; - } - } -} - - -BOOL LLAgent::isWearableModifiable(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - if(!item_id.isNull()) - { - LLInventoryItem* item = gInventory.getItem(item_id); - if(item && item->getPermissions().allowModifyBy(gAgent.getID(), - gAgent.getGroupID())) - { - return TRUE; - } - } - return FALSE; -} - -BOOL LLAgent::isWearableCopyable(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - if(!item_id.isNull()) - { - LLInventoryItem* item = gInventory.getItem(item_id); - if(item && item->getPermissions().allowCopyBy(gAgent.getID(), - gAgent.getGroupID())) - { - return TRUE; - } - } - return FALSE; -} - -U32 LLAgent::getWearablePermMask(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - if(!item_id.isNull()) - { - LLInventoryItem* item = gInventory.getItem(item_id); - if(item) - { - return item->getPermissions().getMaskOwner(); - } - } - return PERM_NONE; -} - -LLInventoryItem* LLAgent::getWearableInventoryItem(EWearableType type) -{ - LLUUID item_id = getWearableItem(type); - LLInventoryItem* item = NULL; - if(item_id.notNull()) - { - item = gInventory.getItem(item_id); - } - return item; -} - -LLWearable* LLAgent::getWearableFromWearableItem( const LLUUID& item_id ) -{ - for( S32 i=0; i < WT_COUNT; i++ ) - { - if( mWearableEntry[i].mItemID == item_id ) - { - return mWearableEntry[i].mWearable; - } - } - return NULL; -} - - -void LLAgent::sendAgentWearablesRequest() -{ - gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - sendReliableMessage(); -} - -// Used to enable/disable menu items. -// static -BOOL LLAgent::selfHasWearable( void* userdata ) -{ - EWearableType type = (EWearableType)(intptr_t)userdata; - return gAgent.getWearable( type ) != NULL; -} - -BOOL LLAgent::isWearingItem( const LLUUID& item_id ) -{ - const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id); - return (getWearableFromWearableItem(base_item_id) != NULL); -} - -// static -void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void** user_data ) -{ - // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates - // that may result from AgentWearablesRequest having been sent more than once. - static bool first = true; - if (!first) return; - first = false; - - LLUUID agent_id; - gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); - - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( avatar && (agent_id == avatar->getID()) ) - { - gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgent.mAgentWearablesUpdateSerialNum ); - - S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData); - if( num_wearables < 4 ) - { - // Transitional state. Avatars should always have at least their body parts (hair, eyes, shape and skin). - // The fact that they don't have any here (only a dummy is sent) implies that this account existed - // before we had wearables, or that the database has gotten messed up. - return; - } - - //lldebugs << "processAgentInitialWearablesUpdate()" << llendl; - // Add wearables - LLUUID asset_id_array[ WT_COUNT ]; - S32 i; - for( i=0; i < num_wearables; i++ ) - { - U8 type_u8 = 0; - gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i ); - if( type_u8 >= WT_COUNT ) - { - continue; - } - EWearableType type = (EWearableType) type_u8; - - LLUUID item_id; - gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i ); - - LLUUID asset_id; - gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i ); - if( asset_id.isNull() ) - { - LLWearable::removeFromAvatar( type, FALSE ); - } - else - { - LLAssetType::EType asset_type = LLWearable::typeToAssetType( type ); - if( asset_type == LLAssetType::AT_NONE ) - { - continue; - } - - gAgent.mWearableEntry[type].mItemID = item_id; - asset_id_array[type] = asset_id; - } - - LL_DEBUGS("Wearables") << " " << LLWearable::typeToTypeLabel(type) << " " << asset_id << " item id " << gAgent.mWearableEntry[type].mItemID.asString() << LL_ENDL; - } - - LLCOFMgr::instance().fetchCOF(); - - // now that we have the asset ids...request the wearable assets - for( i = 0; i < WT_COUNT; i++ ) - { - LL_DEBUGS("Wearables") << " fetching " << asset_id_array[i] << LL_ENDL; - if( !gAgent.mWearableEntry[i].mItemID.isNull() ) - { - gWearableList.getAsset( - asset_id_array[i], - LLStringUtil::null, - LLWearable::typeToAssetType( (EWearableType) i ), - LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i ); - } - } - - // Not really sure where else to put this - gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle, NULL); - } -} - -// A single wearable that the avatar was wearing on start-up has arrived from the database. -// static -void LLAgent::onInitialWearableAssetArrived( LLWearable* wearable, void* userdata ) -{ - EWearableType type = (EWearableType)(intptr_t)userdata; - - LLVOAvatar* avatar = gAgent.getAvatarObject(); - if( !avatar ) - { - return; - } - - if( wearable ) - { - llassert( type == wearable->getType() ); - gAgent.mWearableEntry[ type ].mWearable = wearable; - - // disable composites if initial textures are baked - avatar->setupComposites(); - gAgent.queryWearableCache(); - - wearable->writeToAvatar( FALSE ); - avatar->setCompositeUpdatesEnabled(TRUE); - gInventory.addChangedMask( LLInventoryObserver::LABEL, gAgent.mWearableEntry[type].mItemID ); - } - else - { - // Somehow the asset doesn't exist in the database. - gAgent.recoverMissingWearable( type ); - } - - gInventory.notifyObservers(); - - // Have all the wearables that the avatar was wearing at log-in arrived? - if( !gAgent.mWearablesLoaded ) - { - gAgent.mWearablesLoaded = TRUE; - for( S32 i = 0; i < WT_COUNT; i++ ) - { - if( !gAgent.mWearableEntry[i].mItemID.isNull() && !gAgent.mWearableEntry[i].mWearable ) - { - gAgent.mWearablesLoaded = FALSE; - break; - } - } - } - - if( gAgent.mWearablesLoaded ) - { - // Make sure that the server's idea of the avatar's wearables actually match the wearables. - gAgent.sendAgentSetAppearance(); - - // 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() ) - { - avatar->requestLayerSetUploads(); - } - } -} - -// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the -// database. If for some reason, we can't load one of those assets, we can try to reconstruct it so that -// the user isn't left without a shape, for example. (We can do that only after the inventory has loaded.) -void LLAgent::recoverMissingWearable( EWearableType type ) -{ - // Try to recover by replacing missing wearable with a new one. - LLNotifications::instance().add("ReplacedMissingWearable"); - lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; - LLWearable* new_wearable = gWearableList.createNewWearable(type); - - S32 type_s32 = (S32) type; - mWearableEntry[type_s32].mWearable = new_wearable; - new_wearable->writeToAvatar( TRUE ); - - // Add a new one in the lost and found folder. - // (We used to overwrite the "not found" one, but that could potentially - // destory content.) JC - LLUUID lost_and_found_id = - gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); - LLPointer cb = - new addWearableToAgentInventoryCallback( - LLPointer(NULL), - type_s32, - new_wearable, - addWearableToAgentInventoryCallback::CALL_RECOVERDONE); - addWearableToAgentInventory( cb, new_wearable, lost_and_found_id, TRUE); -} - -void LLAgent::recoverMissingWearableDone() -{ - // Have all the wearables that the avatar was wearing at log-in arrived or been fabricated? - mWearablesLoaded = TRUE; - for( S32 i = 0; i < WT_COUNT; i++ ) - { - if( !mWearableEntry[i].mItemID.isNull() && !mWearableEntry[i].mWearable ) - { - mWearablesLoaded = FALSE; - break; - } - } - - if( mWearablesLoaded ) - { - // Make sure that the server's idea of the avatar's wearables actually match the wearables. - sendAgentSetAppearance(); - } - else - { - gInventory.addChangedMask( LLInventoryObserver::LABEL, LLUUID::null ); - gInventory.notifyObservers(); - } -} - -void LLAgent::createStandardWearables(BOOL female) -{ - llwarns << "Creating Standard " << (female ? "female" : "male" ) - << " Wearables" << llendl; - - if (mAvatarObject.isNull()) - { - return; - } - - if(female) mAvatarObject->setSex(SEX_FEMALE); - else mAvatarObject->setSex(SEX_MALE); - - BOOL create[WT_COUNT] = - { - TRUE, //WT_SHAPE - TRUE, //WT_SKIN - TRUE, //WT_HAIR - TRUE, //WT_EYES - TRUE, //WT_SHIRT - TRUE, //WT_PANTS - TRUE, //WT_SHOES - TRUE, //WT_SOCKS - FALSE, //WT_JACKET - FALSE, //WT_GLOVES - TRUE, //WT_UNDERSHIRT - TRUE, //WT_UNDERPANTS - FALSE, //WT_SKIRT - FALSE, //WT_ALPHA - FALSE, //WT_TATTOO - FALSE, //WT_PHYSICS - }; - - for( S32 i=0; i < WT_COUNT; i++ ) - { - bool once = false; - LLPointer donecb = NULL; - if( create[i] ) - { - if (!once) - { - once = true; - donecb = new createStandardWearablesAllDoneCallback; - } - llassert( mWearableEntry[i].mWearable == NULL ); - LLWearable* wearable = gWearableList.createNewWearable((EWearableType)i); - mWearableEntry[i].mWearable = wearable; - // no need to update here... - LLPointer cb = - new addWearableToAgentInventoryCallback( - donecb, - i, - wearable, - addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE); - addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE); - } - } -} -void LLAgent::createStandardWearablesDone(S32 index) -{ - LLWearable* wearable = mWearableEntry[index].mWearable; - - if (wearable) - { - wearable->writeToAvatar(TRUE); - } -} - -void LLAgent::createStandardWearablesAllDone() -{ - // ... because sendAgentWearablesUpdate will notify inventory - // observers. - mWearablesLoaded = TRUE; - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); - - // Treat this as the first texture entry message, if none received yet - mAvatarObject->onFirstTEMessageReceived(); -} - -void LLAgent::makeNewOutfit( - const std::string& new_folder_name, - const LLDynamicArray& wearables_to_include, - const LLDynamicArray& attachments_to_include, - BOOL rename_clothing) -{ - if (mAvatarObject.isNull()) - { - return; - } - - BOOL fUseLinks = !gSavedSettings.getBOOL("UseInventoryLinks") || - !gHippoGridManager->getConnectedGrid()->supportsInvLinks(); - BOOL fUseOutfits = gSavedSettings.getBOOL("UseOutfitFolders") && - gHippoGridManager->getConnectedGrid()->supportsInvLinks(); - - LLAssetType::EType typeDest = (fUseOutfits) ? LLAssetType::AT_MY_OUTFITS : LLAssetType::AT_CLOTHING; - LLAssetType::EType typeFolder = (fUseOutfits) ? LLAssetType::AT_OUTFIT : LLAssetType::AT_NONE; - - // First, make a folder for the outfit. - LLUUID folder_id = gInventory.createNewCategory(gInventory.findCategoryUUIDForType(typeDest), typeFolder, new_folder_name); - - bool found_first_item = false; - - /////////////////// - // Wearables - - if( wearables_to_include.count() ) - { - // Then, iterate though each of the wearables and save copies of them in the folder. - S32 i; - S32 count = wearables_to_include.count(); - LLPointer cbdone = NULL; - for( i = 0; i < count; ++i ) - { - S32 index = wearables_to_include[i]; - LLWearable* old_wearable = mWearableEntry[ index ].mWearable; - if( old_wearable ) - { - LLViewerInventoryItem* item = gInventory.getItem(mWearableEntry[index].mItemID); - if (fUseOutfits) - { - std::string strOrdering = llformat("@%d", item->getWearableType() * 100); - - link_inventory_item( - gAgent.getID(), - item->getLinkedUUID(), - folder_id, - item->getName(), - strOrdering, - LLAssetType::AT_LINK, - LLPointer(NULL)); - } - else - { - std::string new_name = item->getName(); - if (rename_clothing) - { - new_name = new_folder_name; - new_name.append(" "); - new_name.append(old_wearable->getTypeLabel()); - LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN); - } - - if (fUseLinks || isWearableCopyable((EWearableType)index)) - { - LLWearable* new_wearable = gWearableList.createCopy(old_wearable); - if (rename_clothing) - { - new_wearable->setName(new_name); - } - - S32 todo = addWearableToAgentInventoryCallback::CALL_NONE; - if (!found_first_item) - { - found_first_item = true; - /* set the focus to the first item */ - todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE; - /* send the agent wearables update when done */ - cbdone = new sendAgentWearablesUpdateCallback; - } - LLPointer cb = - new addWearableToAgentInventoryCallback( - cbdone, - index, - new_wearable, - todo); - if (isWearableCopyable((EWearableType)index)) - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getLinkedUUID(), - folder_id, - new_name, - cb); - } - else - { - move_inventory_item( - gAgent.getID(), - gAgent.getSessionID(), - item->getLinkedUUID(), - folder_id, - new_name, - cb); - } - } - else - { - link_inventory_item( - gAgent.getID(), - item->getLinkedUUID(), - folder_id, - item->getName(), // Apparently, links cannot have arbitrary names... - item->getDescription(), - LLAssetType::AT_LINK, - LLPointer(NULL)); - } - } - } - } - gInventory.notifyObservers(); - } - - - /////////////////// - // Attachments - - if( attachments_to_include.count() ) - { - for( S32 i = 0; i < attachments_to_include.count(); i++ ) - { - S32 attachment_pt = attachments_to_include[i]; - LLViewerJointAttachment* attachment = get_if_there(mAvatarObject->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL ); - if(!attachment) continue; - 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) continue; - const LLUUID& item_id = attached_object->getAttachmentItemID(); - if (item_id.isNull()) continue; - LLInventoryItem* item = gInventory.getItem(item_id); - if (!item) continue; - if (fUseOutfits) - { - link_inventory_item( - gAgent.getID(), - item->getLinkedUUID(), - folder_id, - item->getName(), - item->getDescription(), - LLAssetType::AT_LINK, - LLPointer(NULL)); - } - else - { - if (fUseLinks || item->getPermissions().allowCopyBy(gAgent.getID())) - { - const LLUUID& old_folder_id = item->getParentUUID(); - - move_inventory_item( - gAgent.getID(), - gAgent.getSessionID(), - item->getLinkedUUID(), - folder_id, - item->getName(), - LLPointer(NULL)); - - if (item->getPermissions().allowCopyBy(gAgent.getID())) - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getLinkedUUID(), - old_folder_id, - item->getName(), - LLPointer(NULL)); - } - } - else - { - link_inventory_item( - gAgent.getID(), - item->getLinkedUUID(), - folder_id, - item->getName(), - item->getDescription(), - LLAssetType::AT_LINK, - LLPointer(NULL)); - } - } - } - } - } -} - -void LLAgent::makeNewOutfitDone(S32 index) -{ - LLUUID first_item_id = mWearableEntry[index].mItemID; - // Open the inventory and select the first item we added. - if( first_item_id.notNull() ) - { - LLInventoryView* view = LLInventoryView::getActiveInventory(); - if(view) - { - view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO); - } - } -} - - -void LLAgent::addWearableToAgentInventory( - LLPointer cb, - LLWearable* wearable, - const LLUUID& category_id, - BOOL notify) -{ - create_inventory_item( - gAgent.getID(), - gAgent.getSessionID(), - category_id, - wearable->getTransactionID(), - wearable->getName(), - wearable->getDescription(), - wearable->getAssetType(), - LLInventoryType::IT_WEARABLE, - wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), - cb); -} - //----------------------------------------------------------------------------- // sendAgentSetAppearance() //----------------------------------------------------------------------------- @@ -7586,7 +3805,7 @@ void LLAgent::sendAgentSetAppearance() { if (!isAgentAvatarValid()) return; - if (mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar()) + if (gAgentQueryManager.mNumPendingQueries > 0 && !gAgentCamera.cameraCustomizeAvatar()) { return; } @@ -7621,7 +3840,7 @@ void LLAgent::sendAgentSetAppearance() // is texture data current relative to wearables? // KLW - TAT this will probably need to check the local queue. - BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && mWearablesLoaded; + BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && gAgentWearables.areWearablesLoaded(); for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ ) { @@ -7653,7 +3872,7 @@ void LLAgent::sendAgentSetAppearance() { // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num]; const EWearableType wearable_type = wearable_dict->mWearablesVec[i]; - const LLWearable* wearable = getWearable(wearable_type); + const LLWearable* wearable = gAgentWearables.getWearable(wearable_type); if (wearable) { hash ^= wearable->getID(); @@ -7722,7 +3941,7 @@ void LLAgent::sendAgentSetAppearance() static bool send_physics_params = false; - send_physics_params |= !!getWearable(WT_PHYSICS); + send_physics_params |= !!gAgentWearables.getWearable(WT_PHYSICS); S32 transmitted_params = 0; for (LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarObject->getFirstVisualParam(); param; @@ -7758,514 +3977,6 @@ void LLAgent::sendAgentDataUpdateRequest() sendReliableMessage(); } -void LLAgent::removeWearable( EWearableType type ) -{ - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - - if ( (gAgent.isTeen()) - && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS)) - { - // Can't take off underclothing in simple UI mode or on PG accounts - return; - } - -// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.1.3b) - if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(type)) ) - { - return; - } -// [/RLVa:KB] - - if( old_wearable ) - { - if( old_wearable->isDirty() ) - { - LLSD payload; - payload["wearable_type"] = (S32)type; - // Bring up view-modal dialog: Save changes? Yes, No, Cancel - LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgent::onRemoveWearableDialog); - return; - } - else - { - removeWearableFinal( type ); - } - } -} - -// static -bool LLAgent::onRemoveWearableDialog(const LLSD& notification, const LLSD& response ) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger(); - switch( option ) - { - case 0: // "Save" - gAgent.saveWearable( type ); - gAgent.removeWearableFinal( type ); - break; - - case 1: // "Don't Save" - gAgent.removeWearableFinal( type ); - break; - - case 2: // "Cancel" - break; - - default: - llassert(0); - break; - } - return false; -} - -// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal. -void LLAgent::removeWearableFinal( EWearableType type ) -{ - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - - gInventory.addChangedMask( LLInventoryObserver::LABEL, mWearableEntry[type].mItemID ); - - mWearableEntry[ type ].mWearable = NULL; - mWearableEntry[ type ].mItemID.setNull(); - - queryWearableCache(); - - if( old_wearable ) - { - old_wearable->removeFromAvatar( TRUE ); - } - - // Update the server - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); - gInventory.notifyObservers(); -} - -void LLAgent::copyWearableToInventory( EWearableType type ) -{ - LLWearable* wearable = mWearableEntry[ type ].mWearable; - if( wearable ) - { - // Save the old wearable if it has changed. - if( wearable->isDirty() ) - { - wearable = gWearableList.createCopyFromAvatar( wearable ); - mWearableEntry[ type ].mWearable = wearable; - } - - // Make a new entry in the inventory. (Put it in the same folder as the original item if possible.) - LLUUID category_id; - LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID ); - if( item ) - { - category_id = item->getParentUUID(); - wearable->setPermissions(item->getPermissions()); - } - LLPointer cb = - new addWearableToAgentInventoryCallback( - LLPointer(NULL), - type, - wearable); - addWearableToAgentInventory(cb, wearable, category_id); - } -} - - -// A little struct to let setWearable() communicate more than one value with onSetWearableDialog(). -struct LLSetWearableData -{ - LLSetWearableData( const LLUUID& new_item_id, LLWearable* new_wearable ) : - mNewItemID( new_item_id ), mNewWearable( new_wearable ) {} - LLUUID mNewItemID; - LLWearable* mNewWearable; -}; - -static bool isFirstPhysicsWearable(EWearableType type, LLInventoryItem *new_item, LLWearable *new_wearable) -{ - if (type == WT_PHYSICS && gSavedSettings.getWarning("FirstPhysicsWearable")) - { - class WearableDelayedCallback - { - public: - static void setDelayedWearable( const LLSD& notification, const LLSD& response, LLUUID item_id, LLWearable *wearable ) - { - if(LLNotification::getSelectedOption(notification, response) == 0) //User selected wear - { - gSavedSettings.setWarning("FirstPhysicsWearable",FALSE); - LLInventoryItem *item = gInventory.getItem(item_id); - if(item) - gAgent.setWearable(item,wearable); //re-enter. - } - } - }; - LLNotifications::instance().add("FirstPhysicsWearable",LLSD(),LLSD(),boost::bind(WearableDelayedCallback::setDelayedWearable, _1, _2, new_item->getUUID(),new_wearable)); - return true; - } - return false; -} - -BOOL LLAgent::needsReplacement(EWearableType wearableType, S32 remove) -{ - return TRUE; - /*if (remove) return TRUE; - - return getWearable(wearableType) ? TRUE : FALSE;*/ -} - -// Assumes existing wearables are not dirty. -void LLAgent::setWearableOutfit( - const LLInventoryItem::item_array_t& items, - const LLDynamicArray< LLWearable* >& wearables, - BOOL remove ) -{ - lldebugs << "setWearableOutfit() start" << llendl; - - BOOL wearables_to_remove[WT_COUNT]; - wearables_to_remove[WT_SHAPE] = FALSE; - wearables_to_remove[WT_SKIN] = FALSE; - wearables_to_remove[WT_HAIR] = FALSE; - wearables_to_remove[WT_EYES] = FALSE; -// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.1.3b) | Added: RLVa-0.2.2a - wearables_to_remove[WT_SHIRT] = remove && gRlvWearableLocks.canRemove(WT_SHIRT); - wearables_to_remove[WT_PANTS] = remove && gRlvWearableLocks.canRemove(WT_PANTS); - wearables_to_remove[WT_SHOES] = remove && gRlvWearableLocks.canRemove(WT_SHOES); - wearables_to_remove[WT_SOCKS] = remove && gRlvWearableLocks.canRemove(WT_SOCKS); - wearables_to_remove[WT_JACKET] = remove && gRlvWearableLocks.canRemove(WT_JACKET); - wearables_to_remove[WT_GLOVES] = remove && gRlvWearableLocks.canRemove(WT_GLOVES); - wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) && remove && gRlvWearableLocks.canRemove(WT_UNDERSHIRT); - wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) && remove && gRlvWearableLocks.canRemove(WT_UNDERPANTS); - wearables_to_remove[WT_SKIRT] = remove && gRlvWearableLocks.canRemove(WT_SKIRT); - wearables_to_remove[WT_ALPHA] = remove && gRlvWearableLocks.canRemove(WT_ALPHA); - wearables_to_remove[WT_TATTOO] = remove && gRlvWearableLocks.canRemove(WT_TATTOO); - wearables_to_remove[WT_PHYSICS] = remove && gRlvWearableLocks.canRemove(WT_PHYSICS); -// [/RLVa:KB] - - S32 count = wearables.count(); - llassert( items.count() == count ); - - S32 i; - for( i = 0; i < count; i++ ) - { - LLWearable* new_wearable = wearables[i]; - LLPointer new_item = items[i]; - - EWearableType type = new_wearable->getType(); - wearables_to_remove[type] = FALSE; - - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - if( old_wearable ) - { - const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; - if( (old_wearable->getID() == new_wearable->getID()) && - (old_item_id == new_item->getUUID()) ) - { - lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl; - continue; - } - - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - - // Assumes existing wearables are not dirty. - if( old_wearable->isDirty() ) - { - llassert(0); - continue; - } - } - - if (isFirstPhysicsWearable(type, new_item, new_wearable)) - { - return; - } - - mWearableEntry[ type ].mItemID = new_item->getUUID(); - mWearableEntry[ type ].mWearable = new_wearable; - } - - std::vector wearables_being_removed; - - for( i = 0; i < WT_COUNT; i++ ) - { - if( wearables_to_remove[i] ) - { - wearables_being_removed.push_back(mWearableEntry[ i ].mWearable); - mWearableEntry[ i ].mWearable = NULL; - - gInventory.addChangedMask(LLInventoryObserver::LABEL, mWearableEntry[ i ].mItemID); - mWearableEntry[ i ].mItemID.setNull(); - } - } - - gInventory.notifyObservers(); - - queryWearableCache(); - - std::vector::iterator wearable_iter; - - for( wearable_iter = wearables_being_removed.begin(); - wearable_iter != wearables_being_removed.end(); - ++wearable_iter) - { - LLWearable* wearablep = *wearable_iter; - if (wearablep) - { - wearablep->removeFromAvatar( TRUE ); - } - } - - for( i = 0; i < count; i++ ) - { - wearables[i]->writeToAvatar( TRUE ); - } - - // Start rendering & update the server - mWearablesLoaded = TRUE; - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); - - lldebugs << "setWearableOutfit() end" << llendl; -} - - -// User has picked "wear on avatar" from a menu. -void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable ) -{ - EWearableType type = new_wearable->getType(); - - LLWearable* old_wearable = mWearableEntry[ type ].mWearable; - -// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) - // Block if: we can't wear on that layer; or we're already wearing something there we can't take off - if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canWear(type)) ) - { - return; - } -// [/RLVa:KB] - - if (isFirstPhysicsWearable(type, new_item, new_wearable)) - { - return; - } - - if( old_wearable ) - { - const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; - if( (old_wearable->getID() == new_wearable->getID()) && - (old_item_id == new_item->getUUID()) ) - { - lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl; - return; - } - - if( old_wearable->isDirty() ) - { - // Bring up modal dialog: Save changes? Yes, No, Cancel - LLSD payload; - payload["item_id"] = new_item->getUUID(); - LLNotifications::instance().add( "WearableSave", LLSD(), payload, boost::bind(LLAgent::onSetWearableDialog, _1, _2, new_wearable)); - return; - } - } - - setWearableFinal( new_item, new_wearable ); -} - -// static -bool LLAgent::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable ) -{ - S32 option = LLNotification::getSelectedOption(notification, response); - LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID()); - if( !new_item ) - { - delete wearable; - return false; - } - - switch( option ) - { - case 0: // "Save" - gAgent.saveWearable( wearable->getType() ); - gAgent.setWearableFinal( new_item, wearable ); - break; - - case 1: // "Don't Save" - gAgent.setWearableFinal( new_item, wearable ); - break; - - case 2: // "Cancel" - break; - - default: - llassert(0); - break; - } - - delete wearable; - return false; -} - -// Called from setWearable() and onSetWearableDialog() to actually set the wearable. -void LLAgent::setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable ) -{ - EWearableType type = new_wearable->getType(); - - // Replace the old wearable with a new one. - llassert( new_item->getAssetUUID() == new_wearable->getID() ); - LLUUID old_item_id = mWearableEntry[ type ].mItemID; - mWearableEntry[ type ].mItemID = new_item->getUUID(); - mWearableEntry[ type ].mWearable = new_wearable; - - if (old_item_id.notNull()) - { - gInventory.addChangedMask( LLInventoryObserver::LABEL, old_item_id ); - gInventory.notifyObservers(); - } - - //llinfos << "LLVOAvatar::setWearable()" << llendl; - queryWearableCache(); - new_wearable->writeToAvatar( TRUE ); - - // Update the server - sendAgentWearablesUpdate(); - sendAgentSetAppearance(); -} - -void LLAgent::queryWearableCache() -{ - if (!mWearablesLoaded) - { - return; - } - - // Look up affected baked textures. - // If they exist: - // disallow updates for affected layersets (until dataserver responds with cache request.) - // If cache miss, turn updates back on and invalidate composite. - // If cache hit, modify baked texture entries. - // - // Cache requests contain list of hashes for each baked texture entry. - // Response is list of valid baked texture assets. (same message) - - gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID()); - gMessageSystem->addS32Fast(_PREHASH_SerialNum, mTextureCacheQueryID); - - S32 num_queries = 0; - for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ ) - { - const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index); - LLUUID hash; - for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++) - { - // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num]; - const EWearableType wearable_type = wearable_dict->mWearablesVec[i]; - const LLWearable* wearable = getWearable(wearable_type); - if (wearable) - { - hash ^= wearable->getID(); - } - } - if (hash.notNull()) - { - hash ^= wearable_dict->mHashID; - num_queries++; - // *NOTE: make sure at least one request gets packed - - //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl; - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - gMessageSystem->addUUIDFast(_PREHASH_ID, hash); - gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index); - } - - mActiveCacheQueries[ baked_index ] = mTextureCacheQueryID; - } - - llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; - gMessageSystem->sendReliable(getRegion()->getHost()); - mNumPendingQueries++; - mTextureCacheQueryID++; -} - -// User has picked "remove from avatar" from a menu. -// static -void LLAgent::userRemoveWearable( void* userdata ) -{ - EWearableType type = (EWearableType)(intptr_t)userdata; - - if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES) ) //&& - //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) - { - gAgent.removeWearable( type ); - } -} - -void LLAgent::userRemoveAllClothes( void* userdata ) -{ - // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty. - if( gFloaterCustomize ) - { - gFloaterCustomize->askToSaveIfDirty( LLAgent::userRemoveAllClothesStep2, NULL ); - } - else - { - LLAgent::userRemoveAllClothesStep2( TRUE, NULL ); - } -} - -void LLAgent::userRemoveAllClothesStep2( BOOL proceed, void* userdata ) -{ - if( proceed ) - { - gAgent.removeWearable( WT_SHIRT ); - gAgent.removeWearable( WT_PANTS ); - gAgent.removeWearable( WT_SHOES ); - gAgent.removeWearable( WT_SOCKS ); - gAgent.removeWearable( WT_JACKET ); - gAgent.removeWearable( WT_GLOVES ); - gAgent.removeWearable( WT_UNDERSHIRT ); - gAgent.removeWearable( WT_UNDERPANTS ); - gAgent.removeWearable( WT_SKIRT ); - gAgent.removeWearable( WT_ALPHA ); - gAgent.removeWearable( WT_TATTOO ); - gAgent.removeWearable( WT_PHYSICS ); - } -} - -void LLAgent::userRemoveAllAttachments( void* userdata ) -{ - LLVOAvatar* avatarp = gAgent.getAvatarObject(); - if(!avatarp) - { - llwarns << "No avatar found." << llendl; - return; - } - - llvo_vec_t objects_to_remove; - - for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); - iter != avatarp->mAttachmentPoints.end();) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - 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) -// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b - if ( (attached_object) && ((!rlv_handler_t::isEnabled()) || (!gRlvAttachmentLocks.isLockedAttachment(attached_object))) ) -// [/RLVa:KB] - { - objects_to_remove.push_back(attached_object); - } - } - } - userRemoveMultipleAttachments(objects_to_remove); -} void LLAgent::observeFriends() { @@ -8329,271 +4040,106 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename) }//end for (all message sets in xml file) } -// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to -// get attachments into desired state with minimal number of adds/removes. -//void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array) -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a -void LLAgent::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly) -// [/SL:KB] +// Draw a representation of current autopilot target +void LLAgent::renderAutoPilotTarget() { - // Possible cases: - // already wearing but not in request set -> take off. - // already wearing and in request set -> leave alone. - // not wearing and in request set -> put on. - - LLVOAvatar* pAvatar = gAgent.getAvatarObject(); - if (!pAvatar) return; - - std::set requested_item_ids; - std::set current_item_ids; - for (S32 i=0; igetLinkedUUID()); - - // Build up list of objects to be removed and items currently attached. - llvo_vec_t objects_to_remove; - for (LLVOAvatar::attachment_map_t::iterator iter = pAvatar->mAttachmentPoints.begin(); - iter != pAvatar->mAttachmentPoints.end();) + if (mAutoPilot) { - 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 *objectp = (*attachment_iter); - if (objectp) - { - LLUUID object_item_id = objectp->getAttachmentItemID(); - if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) - { - // Object currently worn, was requested. - // Flag as currently worn so we won't have to add it again. - current_item_ids.insert(object_item_id); - } - else - { - // object currently worn, not requested. - objects_to_remove.push_back(objectp); - } - } - } - } + F32 height_meters; + LLVector3d target_global; - LLInventoryModel::item_array_t items_to_add; - for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin(); - it != obj_item_array.end(); - ++it) - { - LLUUID linked_id = (*it).get()->getLinkedUUID(); - if (current_item_ids.find(linked_id) != current_item_ids.end()) - { - // Requested attachment is already worn. - } - else - { - // Requested attachment is not worn yet. - items_to_add.push_back(*it); - } - } - // S32 remove_count = objects_to_remove.size(); - // S32 add_count = items_to_add.size(); - // llinfos << "remove " << remove_count << " add " << add_count << llendl; + glMatrixMode(GL_MODELVIEW); + gGL.pushMatrix(); - // Remove everything in objects_to_remove -// userRemoveMultipleAttachments(objects_to_remove); -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a - if (!fAttachOnly) - { - userRemoveMultipleAttachments(objects_to_remove); - } -// [/SL:KB] + // not textured + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // Add everything in items_to_add - userAttachMultipleAttachments(items_to_add); -} + // lovely green + glColor4f(0.f, 1.f, 1.f, 1.f); -void LLAgent::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove) -{ - if (!gAgent.getAvatarObject()) return; + target_global = mAutoPilotTargetGlobal; -// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.1.3b) | Modified: RLVa-1.2.0a - // RELEASE-RLVa: [SL-2.0.0] Check our callers and verify that erasing elements from the passed vector won't break random things - if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) ) - { - llvo_vec_t::iterator itObj = objects_to_remove.begin(); - while (itObj != objects_to_remove.end()) - { - const LLViewerObject* pAttachObj = *itObj; - if (gRlvAttachmentLocks.isLockedAttachment(pAttachObj)) - { - itObj = objects_to_remove.erase(itObj); + gGL.translatef((F32)(target_global.mdV[VX]), (F32)(target_global.mdV[VY]), (F32)(target_global.mdV[VZ])); - // Fall-back code: re-add the attachment if it got removed from COF somehow (compensates for possible bugs elsewhere) - LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; - LLLinkedItemIDMatches f(pAttachObj->getAttachmentItemID()); - gInventory.collectDescendentsIf(LLCOFMgr::instance().getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH, f); - RLV_ASSERT( 0 != items.count() ); - if (0 == items.count()) - LLCOFMgr::instance().addAttachment(pAttachObj->getAttachmentItemID()); - } - else - { - ++itObj; - } - } - } -// [/RLVa:KB] + height_meters = 1.f; - if (objects_to_remove.empty()) - return; + glScalef(height_meters, height_meters, height_meters); - gMessageSystem->newMessage("ObjectDetach"); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - for (llvo_vec_t::iterator it = objects_to_remove.begin(); - it != objects_to_remove.end(); - ++it) - { - LLViewerObject *objectp = *it; - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); - } - gMessageSystem->sendReliable(gAgent.getRegionHost()); -} + gSphere.render(1500.f); -void LLAgent::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array) -{ -// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a - // RELEASE-RLVa: [SL-2.0.0] Check our callers and verify that erasing elements from the passed vector won't break random things - if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) - { - // Fall-back code: everything should really already have been pruned before we get this far - for (S32 idxItem = obj_item_array.count() - 1; idxItem >= 0; idxItem--) - { - const LLInventoryItem* pItem = obj_item_array.get(idxItem).get(); - if (!gRlvAttachmentLocks.canAttach(pItem)) - { - obj_item_array.remove(idxItem); - RLV_ASSERT(false); - } - } - } -// [/RLVa:KB] - - // Build a compound message to send all the objects that need to be rezzed. - S32 obj_count = obj_item_array.count(); - - // Limit number of packets to send - const S32 MAX_PACKETS_TO_SEND = 10; - const S32 OBJECTS_PER_PACKET = 4; - const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET; - if( obj_count > MAX_OBJECTS_TO_SEND ) - { - obj_count = MAX_OBJECTS_TO_SEND; - } - - // Create an id to keep the parts of the compound message together - LLUUID compound_msg_id; - compound_msg_id.generate(); - LLMessageSystem* msg = gMessageSystem; - - for(S32 i = 0; i < obj_count; ++i) - { - if( 0 == (i % OBJECTS_PER_PACKET) ) - { - // Start a new message chunk - msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_HeaderData); - msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); - msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); - msg->addBOOLFast(_PREHASH_FirstDetachAll, false ); - } - - const LLInventoryItem* item = obj_item_array.get(i).get(); - bool replace = !gHippoGridManager->getConnectedGrid()->supportsInvLinks(); - msg->nextBlockFast(_PREHASH_ObjectData ); - msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); - msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); - msg->addU8Fast(_PREHASH_AttachmentPt, replace? 0 : ATTACHMENT_ADD); // Wear at the previous or default attachment point - pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); - msg->addStringFast(_PREHASH_Name, item->getName()); - msg->addStringFast(_PREHASH_Description, item->getDescription()); - - if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) ) - { - // End of message chunk - msg->sendReliable( gAgent.getRegion()->getHost() ); - } + gGL.popMatrix(); } } void LLAgent::showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity) { const LLVector3d posglobal = LLVector3d(F64(global_x), F64(global_y), F64(0)); - LLSimInfo* siminfo; - siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(posglobal); - std::string sim_name; - LLWorldMap::getInstance()->simNameFromPosGlobal( posglobal, sim_name ); + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(posglobal); + if(mPendingLure) + delete mPendingLure; + mPendingLure = new SHLureRequest(fromname,posglobal,x,y,z); + + if(siminfo) //We already have an entry? Go right on to displaying it. + { + onFoundLureDestination(siminfo); + } + else + { + U16 grid_x = (U16)(global_x / REGION_WIDTH_UNITS); + U16 grid_y = (U16)(global_y / REGION_WIDTH_UNITS); + LLWorldMap::getInstance()->sendMapBlockRequest(grid_x, grid_y, grid_x, grid_y, true); //Will call onFoundLureDestination on response + } +} + +void LLAgent::onFoundLureDestination(LLSimInfo *siminfo) +{ + if(!mPendingLure) + return; + + if(!siminfo) + siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(mPendingLure->mPosGlobal); if(siminfo) { - llinfos << fromname << "'s teleport lure is to " << sim_name << " (" << maturity << ")" << llendl; + const std::string sim_name = siminfo->getName(); + const std::string maturity = siminfo->getAccessString(); + + llinfos << mPendingLure->mAvatarName << "'s teleport lure is to " << sim_name << " (" << maturity << ")" << llendl; LLStringUtil::format_map_t args; - args["[NAME]"] = fromname; - args["[DESTINATION]"] = LLURLDispatcher::buildSLURL(sim_name.c_str(), S32(x), S32(y), S32(z)); - std::string msg = LLTrans::getString("TeleportLureMaturity", args); - if (maturity != "") + args["[NAME]"] = mPendingLure->mAvatarName; + args["[DESTINATION]"] = LLURLDispatcher::buildSLURL(sim_name, (S32)mPendingLure->mPosLocal[0], (S32)mPendingLure->mPosLocal[1], (S32)mPendingLure->mPosLocal[2] ); + std::string msg = LLTrans::getString("TeleportOfferMaturity", args); + if (!maturity.empty()) { msg.append(llformat(" (%s)", maturity.c_str())); } LLChat chat(msg); LLFloaterChat::addChat(chat); } - else - { - LLAgent::lure_show = TRUE; - LLAgent::lure_name = fromname; - LLAgent::lure_posglobal = posglobal; - LLAgent::lure_global_x = U16(global_x / 256); - LLAgent::lure_global_y = U16(global_y / 256); - LLAgent::lure_x = x; - LLAgent::lure_y = y; - LLAgent::lure_z = z; - LLAgent::lure_maturity = maturity; - LLWorldMap::getInstance()->sendMapBlockRequest(lure_global_x, lure_global_y, lure_global_x, lure_global_y, true); - } -} - -void LLAgent::onFoundLureDestination() -{ - LLAgent::lure_show = FALSE; - LLSimInfo* siminfo; - siminfo = LLWorldMap::getInstance()->simInfoFromPosGlobal(LLAgent::lure_posglobal); - std::string sim_name; - LLWorldMap::getInstance()->simNameFromPosGlobal(LLAgent::lure_posglobal, sim_name ); - if(siminfo) - { - llinfos << LLAgent::lure_name << "'s teleport lure is to " << sim_name << " (" << LLAgent::lure_maturity << ")" << llendl; - LLStringUtil::format_map_t args; - args["[NAME]"] = LLAgent::lure_name; - args["[DESTINATION]"] = LLURLDispatcher::buildSLURL(sim_name, S32(LLAgent::lure_x), S32(LLAgent::lure_y), S32(LLAgent::lure_z)); - std::string msg = LLTrans::getString("TeleportOfferMaturity", args); - if (LLAgent::lure_maturity != "") - { - msg.append(llformat(" (%s)", LLAgent::lure_maturity.c_str())); - } - LLChat chat(msg); - LLFloaterChat::addChat(chat); - } else llwarns << "Grand scheme failed" << llendl; + delete mPendingLure; + mPendingLure = NULL; } +/********************************************************************************/ + +LLAgentQueryManager gAgentQueryManager; + +LLAgentQueryManager::LLAgentQueryManager() : + mWearablesCacheQueryID(0), + mNumPendingQueries(0), + mUpdateSerialNum(0) +{ + for (U32 i = 0; i < BAKED_NUM_INDICES; i++) + { + mActiveCacheQueries[i] = 0; + } +} + +LLAgentQueryManager::~LLAgentQueryManager() +{ +} // EOF diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index f697e4778..37f52d643 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -36,65 +36,20 @@ #include #include "indra_constants.h" -#include "llmath.h" -#include "llcontrol.h" -#include "llcoordframe.h" -#include "llevent.h" -#include "llagentaccess.h" + +#include "llevent.h" // LLObservable base class #include "llagentconstants.h" -#include "llanimationstates.h" -#include "lldbstrings.h" -#include "llhudeffectlookat.h" -#include "llhudeffectpointat.h" -#include "llinventorymodel.h" -#include "llmemory.h" -#include "llstring.h" -#include "lluuid.h" -#include "m3math.h" -#include "m4math.h" -#include "llquaternion.h" -#include "lltimer.h" -#include "v3dmath.h" -#include "v3math.h" -#include "v4color.h" -#include "v4math.h" -//#include "vmath.h" -#include "stdenums.h" -#include "llwearable.h" +#include "llagentdata.h" // gAgentID, gAgentSessionID #include "llcharacter.h" -#include "llinventory.h" +#include "llcoordframe.h" // for mFrameAgent +#include "llvoavatardefines.h" #include "llviewerinventory.h" -#include "llviewerobject.h" -#include "llagentdata.h" +#include "llinventorymodel.h" +#include "v3dmath.h" -// Ventrella -#include "llfollowcam.h" -// end Ventrella - -const U8 AGENT_STATE_TYPING = 0x04; // Typing indication -const U8 AGENT_STATE_EDITING = 0x10; // Set when agent has objects selected - -const BOOL ANIMATE = TRUE; - -typedef enum e_camera_modes -{ - CAMERA_MODE_THIRD_PERSON, - CAMERA_MODE_MOUSELOOK, - CAMERA_MODE_CUSTOMIZE_AVATAR, - CAMERA_MODE_FOLLOW -} ECameraMode; - -typedef enum e_camera_position -{ - CAMERA_POSITION_SELF, /** Camera positioned at our position */ - CAMERA_POSITION_OBJECT /** Camera positioned at observed object's position */ -} ECameraPosition; - -typedef enum e_anim_request -{ - ANIM_REQUEST_START, - ANIM_REQUEST_STOP -} EAnimRequest; +extern const BOOL ANIMATE; +extern const U8 AGENT_STATE_TYPING; // Typing indication +extern const U8 AGENT_STATE_EDITING; // Set when agent has objects selected class LLChat; class LLVOAvatar; @@ -106,6 +61,18 @@ class LLPermissions; class LLHost; class LLFriendObserver; class LLPickInfo; +class LLViewerObject; +class LLAgentDropGroupViewerNode; +class LLAgentAccess; +class LLSimInfo; + +typedef std::vector llvo_vec_t; + +enum EAnimRequest +{ + ANIM_REQUEST_START, + ANIM_REQUEST_STOP +}; struct LLGroupData { @@ -118,11 +85,6 @@ struct LLGroupData std::string mName; }; -inline bool operator==(const LLGroupData &a, const LLGroupData &b) -{ - return (a.mID == b.mID); -} - BOOL isAgentAvatarValid(); // forward declarations @@ -134,261 +96,396 @@ class LLAgent : public LLObservable LOG_CLASS(LLAgent); public: - // When the agent hasn't typed anything for this duration, it leaves the - // typing state (for both chat and IM). - static const F32 TYPING_TIMEOUT_SECS; + friend class LLAgentDropGroupViewerNode; +/******************************************************************************** + ** ** + ** INITIALIZATION + **/ + + //-------------------------------------------------------------------- + // Constructors / Destructors + //-------------------------------------------------------------------- +public: LLAgent(); ~LLAgent(); void init(); void cleanup(); - // - // MANIPULATORS - // - // TODO: Put all non-const functions here. +//Avatar object decoupled from agent in v2. Access changed to global gAgentAvatarp pointer. Stuff below will vanish. + void setAvatarObject(LLVOAvatar *avatar); //Legacy + LLVOAvatar *getAvatarObject() const { return mAvatarObject; } +private: + LLPointer mAvatarObject; - // Called whenever the agent moves. Puts camera back in default position, - // deselects items, etc. - void resetView(BOOL reset_camera = TRUE, BOOL change_camera = FALSE); + //-------------------------------------------------------------------- + // Login + //-------------------------------------------------------------------- +public: + void onAppFocusGained(); + void setFirstLogin(BOOL b) { mFirstLogin = b; } + // Return TRUE if the database reported this login as the first for this particular user. + BOOL isFirstLogin() const { return mFirstLogin; } + BOOL isInitialized() const { return mInitialized; } +public: + std::string mMOTD; // Message of the day +private: + BOOL mInitialized; + BOOL mFirstLogin; - // Called on camera movement, to allow the camera to be unlocked from the - // default position behind the avatar. - void unlockView(); - - void onAppFocusGained(); - - void sendMessage(); // Send message to this agent's region. - void sendReliableMessage(); - void resetClientTag(); - LLVector3d calcCameraPositionTargetGlobal(BOOL *hit_limit = NULL); // Calculate the camera position target - LLVector3d calcFocusPositionTargetGlobal(); - LLVector3d calcThirdPersonFocusOffset(); - // target for this mode - LLVector3d getCameraPositionGlobal() const; - const LLVector3 &getCameraPositionAgent() const; - F32 calcCameraFOVZoomFactor(); - F32 getCameraMinOffGround(); // minimum height off ground for this mode, meters - void endAnimationUpdateUI(); - void setKey(const S32 direction, S32 &key); // sets key to +1 for +direction, -1 for -direction - void handleScrollWheel(S32 clicks); // mousewheel driven zoom + //-------------------------------------------------------------------- + // Session + //-------------------------------------------------------------------- +public: + const LLUUID& getID() const { return gAgentID; } + const LLUUID& getSessionID() const { return gAgentSessionID; } + // Note: NEVER send this value in the clear or over any weakly + // encrypted channel (such as simple XOR masking). If you are unsure + // ask Aaron or MarkL. + const LLUUID& getSecureSessionID() const { return mSecureSessionID; } +public: + LLUUID mSecureSessionID; // Secure token for this login session - void setAvatarObject(LLVOAvatar *avatar); +/** Initialization + ** ** + *******************************************************************************/ - // rendering state bitmask helpers - void startTyping(); - void stopTyping(); - void setRenderState(U8 newstate); - void clearRenderState(U8 clearstate); - U8 getRenderState(); +/******************************************************************************** + ** ** + ** IDENTITY + **/ - // Set the home data + //-------------------------------------------------------------------- + // Name + //-------------------------------------------------------------------- +public: + void getName(std::string& name); //Legacy + void buildFullname(std::string &name) const; //Legacy + //*TODO remove, is not used as of August 20, 2009 + void buildFullnameAndTitle(std::string &name) const; + + //-------------------------------------------------------------------- + // Gender + //-------------------------------------------------------------------- +public: + // On the very first login, gender isn't chosen until the user clicks + // in a dialog. We don't render the avatar until they choose. + BOOL isGenderChosen() const { return mGenderChosen; } + void setGenderChosen(BOOL b) { mGenderChosen = b; } + private: + BOOL mGenderChosen; + + //-------------------------------------------------------------------- + // Client Tagging + //-------------------------------------------------------------------- +public: + void resetClientTag(); + +/** Identity + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** POSITION + **/ + + //-------------------------------------------------------------------- + // Position + //-------------------------------------------------------------------- +public: + LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const; + LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const; + const LLVector3d &getPositionGlobal() const; + const LLVector3 &getPositionAgent(); + // Call once per frame to update position, angles (radians). + void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y); // call once per frame to update position, angles radians + void setPositionAgent(const LLVector3 ¢er); +protected: + void propagate(const F32 dt); // ! BUG ! Should roll into updateAgentPosition +private: + mutable LLVector3d mPositionGlobal; + + //-------------------------------------------------------------------- + // Velocity + //-------------------------------------------------------------------- +public: + LLVector3 getVelocity() const; + F32 getVelocityZ() const { return getVelocity().mV[VZ]; } // ! HACK ! + + //-------------------------------------------------------------------- + // Coordinate System + //-------------------------------------------------------------------- +public: + const LLCoordFrame& getFrameAgent() const { return mFrameAgent; } + void initOriginGlobal(const LLVector3d &origin_global); // Only to be used in ONE place! - djs 08/07/02 + void resetAxes(); + void resetAxes(const LLVector3 &look_at); // Makes reasonable left and up + // The following three get*Axis functions return direction avatar is looking, not camera. + const LLVector3& getAtAxis() const { return mFrameAgent.getAtAxis(); } + const LLVector3& getUpAxis() const { return mFrameAgent.getUpAxis(); } + const LLVector3& getLeftAxis() const { return mFrameAgent.getLeftAxis(); } + LLQuaternion getQuat() const; // Returns the quat that represents the rotation of the agent in the absolute frame +private: + LLVector3d mAgentOriginGlobal; // Origin of agent coords from global coords + LLCoordFrame mFrameAgent; // Agent position and view, agent-region coordinates + + + //-------------------------------------------------------------------- + // Home + //-------------------------------------------------------------------- +public: + void setStartPosition(U32 location_id); // Marks current location as start, sends information to servers + void setHomePosRegion( const U64& region_handle, const LLVector3& pos_region ); + BOOL getHomePosGlobal(LLVector3d* pos_global); +private: + BOOL mHaveHomePosition; + U64 mHomeRegionHandle; + LLVector3 mHomePosRegion; + + //-------------------------------------------------------------------- + // Region + //-------------------------------------------------------------------- +public: void setRegion(LLViewerRegion *regionp); LLViewerRegion *getRegion() const; const LLHost& getRegionHost() const; - std::string getSLURL() const; + BOOL inPrelude(); + std::string getSLURL() const; //Return uri for current region + void buildLocationString(std::string& str); //Build a description string for current location - void updateAgentPosition(const F32 dt, const F32 yaw, const S32 mouse_x, const S32 mouse_y); // call once per frame to update position, angles radians - void updateLookAt(const S32 mouse_x, const S32 mouse_y); + // + struct SHLureRequest + { + SHLureRequest(const std::string& avatar_name, const LLVector3d& pos_global, const int x, const int y, const int z) : + mAvatarName(avatar_name), mPosGlobal(pos_global) + { mPosLocal[0] = x; mPosLocal[1] = y; mPosLocal[2] = z;} + const std::string mAvatarName; + const LLVector3d mPosGlobal; + int mPosLocal[3]; + }; + SHLureRequest *mPendingLure; + void showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity); + void onFoundLureDestination(LLSimInfo *siminfo = NULL); + static LLVector3 exlStartMeasurePoint; + static LLVector3 exlEndMeasurePoint; + // + +private: + LLViewerRegion *mRegionp; - void updateCamera(); // call once per frame to update camera location/orientation - void resetCamera(); // slam camera into its default position - void setupSitCamera(); - void setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; } - - 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 - // Ventrella - void changeCameraToFollow(BOOL animate = TRUE); - //end Ventrella - - 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 setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos = LLVector3::zero, const LLVector3 &camera_focus = LLVector3::zero); - void clearFocusObject(); - void setFocusObject(LLViewerObject* object); - void setObjectTracking(BOOL track) { mTrackFocusObject = track; } -// void setLookingAtAvatar(BOOL looking); + //-------------------------------------------------------------------- + // History + //-------------------------------------------------------------------- +public: + S32 getRegionsVisited() const; + F64 getDistanceTraveled() const; + void setDistanceTraveled(F64 dist) { mDistanceTraveled = dist; } + + const LLVector3d &getLastPositionGlobal() const { return mLastPositionGlobal; } + void setLastPositionGlobal(const LLVector3d &pos) { mLastPositionGlobal = pos; } +private: + std::set mRegionsVisited; // Stat - what distinct regions has the avatar been to? + F64 mDistanceTraveled; // Stat - how far has the avatar moved? + LLVector3d mLastPositionGlobal; // Used to calculate travel distance + +/** Position + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** ACTIONS + **/ + + //-------------------------------------------------------------------- + // Fidget + //-------------------------------------------------------------------- + // Trigger random fidget animations +public: + void fidget(); + static void stopFidget(); +private: + LLFrameTimer mFidgetTimer; + LLFrameTimer mFocusObjectFadeTimer; + LLFrameTimer mMoveTimer; + F32 mNextFidgetTime; + S32 mCurrentFidget; + //-------------------------------------------------------------------- + // Fly + //-------------------------------------------------------------------- +public: + BOOL getFlying() const; + void setFlying(BOOL fly); + static void toggleFlying(); + static bool enableFlying(); + BOOL canFly(); // Does this parcel allow you to fly? + + //-------------------------------------------------------------------- + // Chat + //-------------------------------------------------------------------- +public: void heardChat(const LLUUID& id); - void lookAtLastChat(); - void lookAtObject(LLUUID avatar_id, ECameraPosition camera_pos); - F32 getTypingTime() { return mTypingTimer.getElapsedTimeF32(); } + F32 getTypingTime() { return mTypingTimer.getElapsedTimeF32(); } + LLUUID getLastChatter() const { return mLastChatterID; } + F32 getNearChatRadius() { return mNearChatRadius; } +protected: + void ageChat(); // Helper function to prematurely age chat when agent is moving +private: + LLFrameTimer mChatTimer; + LLUUID mLastChatterID; + F32 mNearChatRadius; + + //-------------------------------------------------------------------- + // Typing + //-------------------------------------------------------------------- +public: + void startTyping(); + void stopTyping(); +public: + // When the agent hasn't typed anything for this duration, it leaves the + // typing state (for both chat and IM). + static const F32 TYPING_TIMEOUT_SECS; +private: + LLFrameTimer mTypingTimer; + //-------------------------------------------------------------------- + // AFK + //-------------------------------------------------------------------- +public: void setAFK(); void clearAFK(); BOOL getAFK() const; + + //-------------------------------------------------------------------- + // Run + //-------------------------------------------------------------------- +public: + enum EDoubleTapRunMode + { + DOUBLETAP_NONE, + DOUBLETAP_FORWARD, + DOUBLETAP_BACKWARD, + DOUBLETAP_SLIDELEFT, + DOUBLETAP_SLIDERIGHT + }; - void setAlwaysRun() { mbAlwaysRun = true; } - void clearAlwaysRun() { mbAlwaysRun = false; } + void setAlwaysRun() { mbAlwaysRun = true; } + void clearAlwaysRun() { mbAlwaysRun = false; } + void setRunning() { mbRunning = true; } + void clearRunning() { mbRunning = false; } + void sendWalkRun(bool running); + bool getAlwaysRun() const { return mbAlwaysRun; } + bool getRunning() const { return mbRunning; } +public: + LLFrameTimer mDoubleTapRunTimer; + EDoubleTapRunMode mDoubleTapRunMode; +private: + bool mbAlwaysRun; // Should the avatar run by default rather than walk? + bool mbRunning; // Is the avatar trying to run right now? + bool mbTeleportKeepsLookAt; // Try to keep look-at after teleport is complete - void setRunning() { mbRunning = true; } - void clearRunning() { mbRunning = false; } + //-------------------------------------------------------------------- + // Sit and stand + //-------------------------------------------------------------------- +public: + void standUp(); + /// @brief ground-sit at agent's current position + void sitDown(); + //-------------------------------------------------------------------- + // Busy + //-------------------------------------------------------------------- +public: void setBusy(); void clearBusy(); BOOL getBusy() const; - - void setAdminOverride(BOOL b); - void setGodLevel(U8 god_level); - void setFirstLogin(BOOL b) { mFirstLogin = b; } - void setGenderChosen(BOOL b) { mGenderChosen = b; } - - // update internal datastructures and update the server with the - // new contribution level. Returns true if the group id was found - // and contribution could be set. - BOOL setGroupContribution(const LLUUID& group_id, S32 contribution); - BOOL setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile); - void setHideGroupTitle(BOOL hide) { mHideGroupTitle = hide; } - - // - // ACCESSORS - // - // TODO: Put all read functions here, make them const - - const LLUUID& getID() const { return gAgentID; } - const LLUUID& getSessionID() const { return gAgentSessionID; } +private: + BOOL mIsBusy; - const LLUUID& getSecureSessionID() const { return mSecureSessionID; } - // Note: NEVER send this value in the clear or over any weakly - // encrypted channel (such as simple XOR masking). If you are unsure - // ask Aaron or MarkL. - - BOOL isGodlike() const; - U8 getGodLevel() const; - // note: this is a prime candidate for pulling out into a Maturity class - // rather than just expose the preference setting, we're going to actually - // expose what the client code cares about -- what the user should see - // based on a combination of the is* and prefers* flags, combined with God bit. - bool wantsPGOnly() const; - bool canAccessMature() const; - bool canAccessAdult() const; - bool canAccessMaturityInRegion( U64 region_handle ) const; - bool canAccessMaturityAtGlobal( LLVector3d pos_global ) const; - bool prefersPG() const; - bool prefersMature() const; - bool prefersAdult() const; - bool isTeen() const; - bool isMature() const; - bool isAdult() const; - void setTeen(bool teen); - void setMaturity(char text); - static int convertTextToMaturity(char text); - bool sendMaturityPreferenceToServer(int preferredMaturity); + //-------------------------------------------------------------------- + // Grab + //-------------------------------------------------------------------- +public: + BOOL leftButtonGrabbed() const; + BOOL rotateGrabbed() const; + BOOL forwardGrabbed() const; + BOOL backwardGrabbed() const; + BOOL upGrabbed() const; + BOOL downGrabbed() const; + + //-------------------------------------------------------------------- + // Controls + //-------------------------------------------------------------------- +public: + U32 getControlFlags(); + void setControlFlags(U32 mask); // performs bitwise mControlFlags |= mask + void clearControlFlags(U32 mask); // performs bitwise mControlFlags &= ~mask + BOOL controlFlagsDirty() const; + void enableControlFlagReset(); + void resetControlFlags(); + BOOL anyControlGrabbed() const; // True iff a script has taken over a control + BOOL isControlGrabbed(S32 control_index) const; + // Send message to simulator to force grabbed controls to be + // released, in case of a poorly written script. + void forceReleaseControls(); + void setFlagsDirty() { mbFlagsDirty = TRUE; } + +private: + S32 mControlsTakenCount[TOTAL_CONTROLS]; + S32 mControlsTakenPassedOnCount[TOTAL_CONTROLS]; + U32 mControlFlags; // Replacement for the mFooKey's + BOOL mbFlagsDirty; + BOOL mbFlagsNeedReset; // ! HACK ! For preventing incorrect flags sent when crossing region boundaries + + //-------------------------------------------------------------------- + // Animations + //-------------------------------------------------------------------- +public: + void stopCurrentAnimations(); + void requestStopMotion(LLMotion* motion); + void onAnimStop(const LLUUID& id); + void sendAnimationRequests(LLDynamicArray &anim_ids, EAnimRequest request); + void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request); + void endAnimationUpdateUI(); + void unpauseAnimation() { mPauseRequest = NULL; } + BOOL getCustomAnim() const { return mCustomAnim; } + void setCustomAnim(BOOL anim) { mCustomAnim = anim; } + BOOL mCustomAnim; // Current animation is ANIM_AGENT_CUSTOMIZE ? + LLPointer mPauseRequest; + BOOL mViewsPushed; // Keep track of whether or not we have pushed views - const LLAgentAccess& getAgentAccess(); - - // This function can go away after the AO transition (see llstartup.cpp) - void setAOTransition(); - - BOOL isGroupTitleHidden() const { return mHideGroupTitle; } - BOOL isGroupMember() const { return !mGroupID.isNull(); } // This is only used for building titles! - const LLUUID &getGroupID() const { return mGroupID; } - ECameraMode getCameraMode() const { return mCameraMode; } - BOOL getFocusOnAvatar() const { return mFocusOnAvatar; } - LLPointer& getFocusObject() { return mFocusObject; } - F32 getFocusObjectDist() const { return mFocusObjectDist; } - BOOL inPrelude(); - BOOL canManageEstate() const; - BOOL getAdminOverride() const; +/** Animation + ** ** + *******************************************************************************/ - LLUUID getLastChatter() const { return mLastChatterID; } - bool getAlwaysRun() const { return mbAlwaysRun; } - bool getRunning() const { return mbRunning; } +/******************************************************************************** + ** ** + ** MOVEMENT + **/ - const LLUUID& getInventoryRootID() const { return mInventoryRootID; } + //-------------------------------------------------------------------- + // Movement from user input + //-------------------------------------------------------------------- + // All set the appropriate animation flags. + // All turn off autopilot and make sure the camera is behind the avatar. + // Direction is either positive, zero, or negative +public: + void moveAt(S32 direction, bool reset_view = true); + void moveAtNudge(S32 direction); + void moveLeft(S32 direction); + void moveLeftNudge(S32 direction); + void moveUp(S32 direction); + void moveYaw(F32 mag, bool reset_view = true); + void movePitch(F32 mag); - void buildFullname(std::string &name) const; - void buildFullnameAndTitle(std::string &name) const; - - // Check against all groups in the entire agent group list. - BOOL isInGroup(const LLUUID& group_id) const; - BOOL hasPowerInGroup(const LLUUID& group_id, U64 power) const; - // Check for power in just the active group. - BOOL hasPowerInActiveGroup(const U64 power) const; - U64 getPowerInGroup(const LLUUID& group_id) const; - - // Get group information by group_id. if not in group, data is - // left unchanged and method returns FALSE. otherwise, values are - // copied and returns TRUE. - BOOL getGroupData(const LLUUID& group_id, LLGroupData& data) const; - // Get just the agent's contribution to the given group. - S32 getGroupContribution(const LLUUID& group_id) const; - - // return TRUE if the database reported this login as the first - // for this particular user. - BOOL isFirstLogin() const { return mFirstLogin; } - - // On the very first login, gender isn't chosen until the user clicks - // in a dialog. We don't render the avatar until they choose. - BOOL isGenderChosen() const { return mGenderChosen; } - - // utility to build a location string - void buildLocationString(std::string& str); - - LLQuaternion getHeadRotation(); - LLVOAvatar *getAvatarObject() const { return mAvatarObject; } - - BOOL needsRenderAvatar(); // TRUE when camera mode is such that your own avatar should draw - // Not const because timers can't be accessed in const-fashion. - BOOL needsRenderHead(); - 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); } - - LLVector3 getPosAgentFromGlobal(const LLVector3d &pos_global) const; - LLVector3d getPosGlobalFromAgent(const LLVector3 &pos_agent) const; - - // Get the data members - const LLVector3& getAtAxis() const { return mFrameAgent.getAtAxis(); } // direction avatar is looking, not camera - const LLVector3& getUpAxis() const { return mFrameAgent.getUpAxis(); } // direction avatar is looking, not camera - const LLVector3& getLeftAxis() const { return mFrameAgent.getLeftAxis(); } // direction avatar is looking, not camera - - LLCoordFrame getFrameAgent() const { return mFrameAgent; } - LLVector3 getVelocity() const; - F32 getVelocityZ() const { return getVelocity().mV[VZ]; } // a hack - - const LLVector3d &getPositionGlobal() const; - const LLVector3 &getPositionAgent(); - S32 getRegionsVisited() const; - F64 getDistanceTraveled() const; - - const LLVector3d &getFocusGlobal() const { return mFocusGlobal; } - const LLVector3d &getFocusTargetGlobal() const { return mFocusTargetGlobal; } - - BOOL getJump() const { return mbJump; } - BOOL getAutoPilot() const { return mAutoPilot; } - LLVector3d getAutoPilotTargetGlobal() const { return mAutoPilotTargetGlobal; } - - LLQuaternion getQuat() const; // returns the quat that represents the rotation - // of the agent in the absolute frame -// BOOL getLookingAtAvatar() const; - - void getName(std::string& name); - - const LLColor4 &getEffectColor(); - void setEffectColor(const LLColor4 &color); - - // - // UTILITIES - // - - // Set the physics data - void slamLookAt(const LLVector3 &look_at); - - void setPositionAgent(const LLVector3 ¢er); - - void resetAxes(); - void resetAxes(const LLVector3 &look_at); // makes reasonable left and up - - // Move the avatar's frame + //-------------------------------------------------------------------- + // Move the avatar's frame + //-------------------------------------------------------------------- +public: void rotate(F32 angle, const LLVector3 &axis); void rotate(F32 angle, F32 x, F32 y, F32 z); void rotate(const LLMatrix3 &matrix); @@ -399,531 +496,23 @@ public: LLVector3 getReferenceUpVector(); F32 clampPitchToLimits(F32 angle); - void setThirdPersonHeadOffset(LLVector3 offset) { mThirdPersonHeadOffset = offset; } - // Flight management - BOOL getFlying() const { return mControlFlags & AGENT_CONTROL_FLY; } - void setFlying(BOOL fly); - void toggleFlying(); - - static BOOL getPhantom(); - static void setPhantom(BOOL phantom); - static void togglePhantom(); - - static BOOL isTPosed() { return mForceTPose; } - static void setTPosed(BOOL TPose) { mForceTPose = TPose; } - static void toggleTPosed(); - - // Does this parcel allow you to fly? - BOOL canFly(); - - // Animation functions - void stopCurrentAnimations(); - void requestStopMotion( LLMotion* motion ); - void onAnimStop(const LLUUID& id); - - void sendAnimationRequests(LLDynamicArray &anim_ids, EAnimRequest request); - void sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request); - - LLVector3 calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y); - BOOL calcCameraMinDistance(F32 &obj_min_distance); - - void startCameraAnimation(); - void stopCameraAnimation(); - - void cameraZoomIn(const F32 factor); // zoom in by fraction of current distance - 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 - - 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 - - void cameraPanIn(const F32 meters); - void cameraPanLeft(const F32 meters); - void cameraPanUp(const F32 meters); - - void updateLastCamera(); - void updateFocusOffset(); - void validateFocusObject(); - - void setUsingFollowCam( bool using_follow_cam); - - F32 calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global ); - - // marks current location as start, sends information to servers - void setStartPosition(U32 location_id); - - // Movement from user input. All set the appropriate animation flags. - // All turn off autopilot and make sure the camera is behind the avatar. - // direction is either positive, zero, or negative - void moveAt(S32 direction, bool reset_view = true); - void moveAtNudge(S32 direction); - void moveLeft(S32 direction); - void moveLeftNudge(S32 direction); - void moveUp(S32 direction); - void moveYaw(F32 mag, bool reset_view = true); - void movePitch(S32 direction); - - 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; } - - 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; } - - U32 getControlFlags(); - void setControlFlags(U32 mask); // performs bitwise mControlFlags |= mask - void clearControlFlags(U32 mask); // performs bitwise mControlFlags &= ~mask - BOOL controlFlagsDirty() const; - void enableControlFlagReset(); - void resetControlFlags(); - - void propagate(const F32 dt); // BUG: should roll into updateAgentPosition - - void startAutoPilotGlobal(const LLVector3d &pos_global, const std::string& behavior_name = std::string(), const LLQuaternion *target_rotation = NULL, - void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL, F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f); - + //-------------------------------------------------------------------- + // Autopilot + //-------------------------------------------------------------------- +public: + BOOL getAutoPilot() const { return mAutoPilot; } + LLVector3d getAutoPilotTargetGlobal() const { return mAutoPilotTargetGlobal; } + void startAutoPilotGlobal(const LLVector3d &pos_global, + const std::string& behavior_name = std::string(), + const LLQuaternion *target_rotation = NULL, + void (*finish_callback)(BOOL, void *) = NULL, void *callback_data = NULL, + F32 stop_distance = 0.f, F32 rotation_threshold = 0.03f); void startFollowPilot(const LLUUID &leader_id); void stopAutoPilot(BOOL user_cancel = FALSE); void setAutoPilotGlobal(const LLVector3d &pos_global); void autoPilot(F32 *delta_yaw); // autopilot walking action, angles in radians void renderAutoPilotTarget(); - - // - // teportation methods - // - - // go to a named location home - void teleportRequest( - const U64& region_handle, - const LLVector3& pos_local, - bool look_at_from_camera = false); - - // teleport to a landmark - void teleportViaLandmark(const LLUUID& landmark_id); - - // go home - void teleportHome() { teleportViaLandmark(LLUUID::null); } - - // to an invited location - void teleportViaLure(const LLUUID& lure_id, BOOL godlike); - - // to a global location - this will probably need to be - // deprecated. - void teleportViaLocation(const LLVector3d& pos_global); - - // to a global location, preserving camera rotation - void teleportViaLocationLookAt(const LLVector3d& pos_global); - - // cancel the teleport, may or may not be allowed by server - void teleportCancel(); - - void setTargetVelocity(const LLVector3 &vel); - const LLVector3 &getTargetVelocity() const; - - const std::string getTeleportSourceSLURL() const { return mTeleportSourceSLURL; } - - // Setting the ability for this avatar to proxy for another avatar. - //static void processAddModifyAbility(LLMessageSystem* msg, void**); - //static void processGrantedProxies(LLMessageSystem* msg, void**); - //static void processRemoveModifyAbility(LLMessageSystem* msg, void**); - //BOOL isProxyFor(const LLUUID& agent_id);// *FIX should be const - - static void processAgentDataUpdate(LLMessageSystem *msg, void **); - static void processAgentGroupDataUpdate(LLMessageSystem *msg, void **); - static void processAgentDropGroup(LLMessageSystem *msg, void **); - static void processScriptControlChange(LLMessageSystem *msg, void **); - static void processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data); - //static void processControlTake(LLMessageSystem *msg, void **); - //static void processControlRelease(LLMessageSystem *msg, void **); - - // This method checks to see if this agent can modify an object - // based on the permissions and the agent's proxy status. - BOOL isGrantedProxy(const LLPermissions& perm); - - BOOL allowOperation(PermissionBit op, - const LLPermissions& perm, - U64 group_proxy_power = 0, - U8 god_minimum = GOD_MAINTENANCE); - - friend std::ostream& operator<<(std::ostream &s, const LLAgent &sphere); - - void initOriginGlobal(const LLVector3d &origin_global); // Only to be used in ONE place! - djs 08/07/02 - - BOOL 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)); } - BOOL rotateGrabbed() const { return ( (mControlsTakenCount[CONTROL_YAW_POS_INDEX] > 0) - ||(mControlsTakenCount[CONTROL_YAW_NEG_INDEX] > 0)); } - BOOL forwardGrabbed() const { return ( (mControlsTakenCount[CONTROL_AT_POS_INDEX] > 0)); } - BOOL backwardGrabbed() const { return ( (mControlsTakenCount[CONTROL_AT_NEG_INDEX] > 0)); } - BOOL upGrabbed() const { return ( (mControlsTakenCount[CONTROL_UP_POS_INDEX] > 0)); } - BOOL downGrabbed() const { return ( (mControlsTakenCount[CONTROL_UP_NEG_INDEX] > 0)); } - - // True iff a script has taken over a control. - BOOL anyControlGrabbed() const; - - BOOL isControlGrabbed(S32 control_index) const; - - // Send message to simulator to force grabbed controls to be - // released, in case of a poorly written script. - void forceReleaseControls(); - - BOOL sitCameraEnabled() { return mSitCameraEnabled; } - - F32 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); } - - // look at behavior - BOOL setLookAt(ELookAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); - ELookAtType getLookAtType(); - - // point at behavior - BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); - EPointAtType getPointAtType(); - - void setHomePosRegion( const U64& region_handle, const LLVector3& pos_region ); - BOOL getHomePosGlobal( LLVector3d* pos_global ); - void setCameraAnimating( BOOL b ) { mCameraAnimating = b; } - BOOL getCameraAnimating( ) { return mCameraAnimating; } - void setAnimationDuration( F32 seconds ) { mAnimationDuration = seconds; } - - F32 getNearChatRadius() { return mNearChatRadius; } - - enum EDoubleTapRunMode - { - DOUBLETAP_NONE, - DOUBLETAP_FORWARD, - DOUBLETAP_BACKWARD, - DOUBLETAP_SLIDELEFT, - DOUBLETAP_SLIDERIGHT - }; - - enum ETeleportState - { - TELEPORT_NONE = 0, // No teleport in progress - TELEPORT_START = 1, // Transition to REQUESTED. Viewer has sent a TeleportRequest to the source simulator - TELEPORT_REQUESTED = 2, // Waiting for source simulator to respond - TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator - TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator - TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches" - TELEPORT_LOCAL = 6, // Teleporting in-sim without showing the progress screen - }; - - ETeleportState getTeleportState() const { return mTeleportState; } - void setTeleportState( ETeleportState state ); - const std::string& getTeleportMessage() const { return mTeleportMessage; } - void setTeleportMessage(const std::string& message) - { - mTeleportMessage = message; - } - - // trigger random fidget animations - void fidget(); - - void requestEnterGodMode(); - void requestLeaveGodMode(); - - void sendAgentSetAppearance(); - - void sendAgentDataUpdateRequest(); - - // Ventrella - LLFollowCam mFollowCam; - // end Ventrella - - //-------------------------------------------------------------------- - // Wearables - //-------------------------------------------------------------------- - void setWearable( LLInventoryItem* new_item, LLWearable* wearable ); - static bool onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable ); - void setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable ); - void setWearableOutfit( const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove ); - void queryWearableCache(); - - BOOL isWearableModifiable(EWearableType type); - BOOL isWearableCopyable(EWearableType type); - BOOL needsReplacement(EWearableType wearableType, S32 remove); - U32 getWearablePermMask(EWearableType type); - - LLInventoryItem* getWearableInventoryItem(EWearableType type); - - LLWearable* getWearable( EWearableType type ) { return (type < WT_COUNT) ? mWearableEntry[ type ].mWearable : NULL; } - BOOL isWearingItem( const LLUUID& item_id ); - LLWearable* getWearableFromWearableItem( const LLUUID& item_id ); - const LLUUID& getWearableItem( EWearableType type ) { return (type < WT_COUNT) ? mWearableEntry[ type ].mItemID : LLUUID::null; } - - static EWearableType getTEWearableType( S32 te ); - static LLUUID getDefaultTEImageID( S32 te ); - - void copyWearableToInventory( EWearableType type ); - - void makeNewOutfit( - const std::string& new_folder_name, - const LLDynamicArray& wearables_to_include, - const LLDynamicArray& attachments_to_include, - BOOL rename_clothing); - void makeNewOutfitDone(S32 index); - - void removeWearable( EWearableType type ); - static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response ); - void removeWearableFinal( EWearableType type ); - - void sendAgentWearablesUpdate(); - - /** - * @brief Only public because of addWearableToAgentInventoryCallback. - * - * NOTE: Do not call this method unless you are the inventory callback. - * NOTE: This can suffer from race conditions when working on the - * same values for index. - * @param index The index in mWearableEntry. - * @param item_id The inventory item id of the new wearable to wear. - * @param wearable The actual wearable data. - */ - void addWearabletoAgentInventoryDone( - S32 index, - const LLUUID& item_id, - LLWearable* wearable); - - void saveWearableAs( EWearableType type, const std::string& new_name, BOOL save_in_lost_and_found ); - void saveWearable( EWearableType type, BOOL send_update = TRUE ); - void saveAllWearables(); - - void revertWearable( EWearableType type ); - void revertAllWearables(); - - void setWearableName( const LLUUID& item_id, const std::string& new_name ); - void createStandardWearables(BOOL female); - void createStandardWearablesDone(S32 index); - void createStandardWearablesAllDone(); - - BOOL areWearablesLoaded() { return mWearablesLoaded; } - - void sendWalkRun(bool running); - - void observeFriends(); - void friendsChanged(); - - // statics - static void stopFidget(); - static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data); - static void userRemoveWearable( void* userdata ); // userdata is EWearableType - static void userRemoveAllClothes( void* userdata ); // userdata is NULL - static void userRemoveAllClothesStep2(BOOL proceed, void* userdata ); // userdata is NULL - static void userRemoveAllAttachments( void* userdata); // userdata is NULL - static BOOL selfHasWearable( void* userdata ); // userdata is EWearableType - -// static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array); -// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a - // Not the best way to go about this but other attempts changed far too much LL code to be a viable solution - static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false); -// [/SL:KB] - static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array); - static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); - - //debug methods - static void clearVisualParams(void *); - - // whether look-at reset after teleport - bool getTeleportKeepsLookAt() { return mbTeleportKeepsLookAt; } - -protected: - // stuff to do for any sort of teleport. Returns true if the - // teleport can proceed. - bool teleportCore(bool is_local = false); - - - // helper function to prematurely age chat when agent is moving - void ageChat(); - - // internal wearable functions - void sendAgentWearablesRequest(); - static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata); - void recoverMissingWearable(EWearableType type); - void recoverMissingWearableDone(); - void addWearableToAgentInventory(LLPointer cb, - LLWearable* wearable, const LLUUID& category_id = LLUUID::null, - BOOL notify = TRUE); -public: - // TODO: Make these private! - LLUUID mSecureSessionID; // secure token for this login session - - F32 mDrawDistance; - - U64 mGroupPowers; - BOOL mHideGroupTitle; - std::string mGroupTitle; // honorific, like "Sir" - std::string mGroupName; - LLUUID mGroupID; - //LLUUID mGroupInsigniaID; - LLUUID mInventoryRootID; - LLUUID mMapID; - F64 mMapOriginX; // Global x coord of mMapID's bottom left corner. - F64 mMapOriginY; // Global y coord of mMapID's bottom left corner. - S32 mMapWidth; // Width of map in meters - S32 mMapHeight; // Height of map in meters - std::string mMOTD; // message of the day - - LLPointer mLookAt; - LLPointer mPointAt; - - LLDynamicArray mGroups; - - F32 mHUDTargetZoom; // target zoom level for HUD objects (used when editing) - F32 mHUDCurZoom; // current animated zoom level for HUD objects - - BOOL mInitialized; - - // - static BOOL lure_show; - static std::string lure_name; - static LLVector3d lure_posglobal; - static U16 lure_global_x; - static U16 lure_global_y; - static int lure_x; - static int lure_y; - static int lure_z; - static std::string lure_maturity; - - static LLVector3 exlStartMeasurePoint; - static LLVector3 exlEndMeasurePoint; - // - - S32 mNumPendingQueries; - S32* mActiveCacheQueries; - - BOOL mForceMouselook; - - static void parseTeleportMessages(const std::string& xml_filename); - //we should really define ERROR and PROGRESS enums here - //but I don't really feel like doing that, so I am just going - //to expose the mappings....yup - static std::map sTeleportErrorMessages; - static std::map sTeleportProgressMessages; - - LLFrameTimer mDoubleTapRunTimer; - EDoubleTapRunMode mDoubleTapRunMode; - - // - static void showLureDestination(const std::string fromname, const int global_x, const int global_y, const int x, const int y, const int z, const std::string maturity); - static void onFoundLureDestination(); - // - private: - static BOOL exlPhantom; - static BOOL mForceTPose; - bool mbTeleportKeepsLookAt; // try to keep look-at after teleport is complete - bool mbAlwaysRun; // should the avatar run by default rather than walk - bool mbRunning; // is the avatar trying to run right now - - LLAgentAccess mAgentAccess; - - ETeleportState mTeleportState; - std::string mTeleportMessage; - - S32 mControlsTakenCount[TOTAL_CONTROLS]; - S32 mControlsTakenPassedOnCount[TOTAL_CONTROLS]; - - LLViewerRegion *mRegionp; - LLVector3d mAgentOriginGlobal; // Origin of agent coords from global coords - mutable LLVector3d mPositionGlobal; - - std::string mTeleportSourceSLURL; // SLURL where last TP began. - - std::set mRegionsVisited; // stat - what distinct regions has the avatar been to? - F64 mDistanceTraveled; // stat - how far has the avatar moved? - LLVector3d mLastPositionGlobal; // Used to calculate travel distance - - LLPointer mAvatarObject; // NULL until avatar object sent down from simulator - - U8 mRenderState; // Current behavior state of agent - LLFrameTimer mTypingTimer; - - ECameraMode mCameraMode; // target mode after transition animation is done - ECameraMode mLastCameraMode; - BOOL mViewsPushed; // keep track of whether or not we have pushed views. - - BOOL mCustomAnim ; //current animation is ANIM_AGENT_CUSTOMIZE ? - BOOL mShowAvatar; // should we render the avatar? - BOOL mCameraAnimating; // camera is transitioning from one mode to another - LLVector3d mAnimationCameraStartGlobal; // camera start position, global coords - LLVector3d mAnimationFocusStartGlobal; // camera focus point, global coords - LLFrameTimer mAnimationTimer; // seconds that transition animation has been active - F32 mAnimationDuration; // seconds - 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 - LLVector3d mCameraFocusOffset; // offset from focus point in build mode - LLVector3d mCameraFocusOffsetTarget; // target towards which we are lerping the camera's focus offset - LLVector3 mCameraOffsetDefault; // default third-person camera offset - LLVector4 mCameraCollidePlane; // colliding plane for camera - F32 mCurrentCameraDistance; // current camera offset from avatar - F32 mTargetCameraDistance; // target camera offset from avatar - F32 mCameraZoomFraction; // mousewheel driven fraction of zoom - LLVector3 mCameraLag; // third person camera lag - LLVector3 mThirdPersonHeadOffset; // head offset for third person camera position - LLVector3 mCameraPositionAgent; // camera position in agent coordinates - LLVector3 mCameraVirtualPositionAgent; // camera virtual position (target) before performing FOV zoom - BOOL mSitCameraEnabled; // use provided camera information when sitting? - LLVector3 mSitCameraPos; // root relative camera pos when sitting - LLVector3 mSitCameraFocus; // root relative camera target when sitting - LLVector3d mCameraSmoothingLastPositionGlobal; - LLVector3d mCameraSmoothingLastPositionAgent; - BOOL mCameraSmoothingStop; - - LLVector3 mCameraUpVector; // camera's up direction in world coordinates (determines the 'roll' of the view) - - LLPointer mSitCameraReferenceObject; // object to which camera is related when sitting - - BOOL mFocusOnAvatar; - LLVector3d mFocusGlobal; - LLVector3d mFocusTargetGlobal; - LLPointer mFocusObject; - F32 mFocusObjectDist; - LLVector3 mFocusObjectOffset; - F32 mFocusDotRadius; // meters - BOOL mTrackFocusObject; - F32 mUIOffset; - - LLCoordFrame mFrameAgent; // Agent position and view, agent-region coordinates - - BOOL mIsBusy; - - S32 mAtKey; // Either 1, 0, or -1... indicates that movement-key is pressed - S32 mWalkKey; // like AtKey, but causes less forward thrust - S32 mLeftKey; - S32 mUpKey; - F32 mYawKey; - S32 mPitchKey; - - F32 mOrbitLeftKey; - F32 mOrbitRightKey; - F32 mOrbitUpKey; - F32 mOrbitDownKey; - F32 mOrbitInKey; - F32 mOrbitOutKey; - - F32 mPanUpKey; - F32 mPanDownKey; - F32 mPanLeftKey; - F32 mPanRightKey; - F32 mPanInKey; - F32 mPanOutKey; - - U32 mControlFlags; // replacement for the mFooKey's - BOOL mbFlagsDirty; - BOOL mbFlagsNeedReset; // HACK for preventing incorrect flags sent when crossing region boundaries - - BOOL mbJump; - BOOL mAutoPilot; BOOL mAutoPilotFlyOnStop; LLVector3d mAutoPilotTargetGlobal; @@ -937,92 +526,347 @@ private: void (*mAutoPilotFinishedCallback)(BOOL, void *); void* mAutoPilotCallbackData; LLUUID mLeaderID; + +/** Movement + ** ** + *******************************************************************************/ - std::set mProxyForAgents; +/******************************************************************************** + ** ** + ** TELEPORT + **/ - LLColor4 mEffectColor; +public: + enum ETeleportState + { + TELEPORT_NONE = 0, // No teleport in progress + TELEPORT_START = 1, // Transition to REQUESTED. Viewer has sent a TeleportRequest to the source simulator + TELEPORT_REQUESTED = 2, // Waiting for source simulator to respond + TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator + TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator + TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches" + TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen + }; - BOOL mHaveHomePosition; - U64 mHomeRegionHandle; - LLVector3 mHomePosRegion; - LLFrameTimer mChatTimer; - LLUUID mLastChatterID; - F32 mNearChatRadius; +public: + static void parseTeleportMessages(const std::string& xml_filename); + const std::string& getTeleportSourceSLURL() const { return mTeleportSourceSLURL; } +public: + // ! TODO ! Define ERROR and PROGRESS enums here instead of exposing the mappings. + static std::map sTeleportErrorMessages; + static std::map sTeleportProgressMessages; +public: + std::string mTeleportSourceSLURL; // SLURL where last TP began. + //-------------------------------------------------------------------- + // Teleport Actions + //-------------------------------------------------------------------- +public: + void teleportRequest(const U64& region_handle, + const LLVector3& pos_local, // Go to a named location home + bool look_at_from_camera = false); + void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark + void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home + void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location + void teleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated + void teleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation + void teleportCancel(); // May or may not be allowed by server + bool getTeleportKeepsLookAt() { return mbTeleportKeepsLookAt; } // Whether look-at reset after teleport +protected: + bool teleportCore(bool is_local = false); // Stuff for all teleports; returns true if the teleport can proceed - LLFrameTimer mFidgetTimer; - LLFrameTimer mFocusObjectFadeTimer; - F32 mNextFidgetTime; - S32 mCurrentFidget; - BOOL mFirstLogin; - BOOL mGenderChosen; + //-------------------------------------------------------------------- + // Teleport State + //-------------------------------------------------------------------- +public: + ETeleportState getTeleportState() const { return mTeleportState; } + void setTeleportState(ETeleportState state); +private: + ETeleportState mTeleportState; + + //-------------------------------------------------------------------- + // Teleport Message + //-------------------------------------------------------------------- +public: + const std::string& getTeleportMessage() const { return mTeleportMessage; } + void setTeleportMessage(const std::string& message) { mTeleportMessage = message; } +private: + std::string mTeleportMessage; + +/** Teleport + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** ACCESS + **/ + +public: + // Checks if agent can modify an object based on the permissions and the agent's proxy status. + BOOL isGrantedProxy(const LLPermissions& perm); + BOOL allowOperation(PermissionBit op, + const LLPermissions& perm, + U64 group_proxy_power = 0, + U8 god_minimum = GOD_MAINTENANCE); + const LLAgentAccess& getAgentAccess(); + BOOL canManageEstate() const; + BOOL getAdminOverride() const; + // ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp). + void setAOTransition(); +private: + LLAgentAccess *mAgentAccess; //-------------------------------------------------------------------- - // Wearables + // God //-------------------------------------------------------------------- - struct LLWearableEntry - { - LLWearableEntry() : mItemID( LLUUID::null ), mWearable( NULL ) {} +public: + bool isGodlike() const; + U8 getGodLevel() const; + void setAdminOverride(BOOL b); + void setGodLevel(U8 god_level); + void requestEnterGodMode(); + void requestLeaveGodMode(); - LLUUID mItemID; // ID of the inventory item in the agent's inventory. - LLWearable* mWearable; - }; - LLWearableEntry mWearableEntry[ WT_COUNT ]; - U32 mAgentWearablesUpdateSerialNum; - BOOL mWearablesLoaded; - S32 mTextureCacheQueryID; + //-------------------------------------------------------------------- + // Maturity + //-------------------------------------------------------------------- +public: + // Note: this is a prime candidate for pulling out into a Maturity class. + // Rather than just expose the preference setting, we're going to actually + // expose what the client code cares about -- what the user should see + // based on a combination of the is* and prefers* flags, combined with god bit. + bool wantsPGOnly() const; + bool canAccessMature() const; + bool canAccessAdult() const; + bool canAccessMaturityInRegion( U64 region_handle ) const; + bool canAccessMaturityAtGlobal( LLVector3d pos_global ) const; + bool prefersPG() const; + bool prefersMature() const; + bool prefersAdult() const; + bool isTeen() const; + bool isMature() const; + bool isAdult() const; + void setTeen(bool teen); + void setMaturity(char text); + static int convertTextToMaturity(char text); + bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"? + + + +/** Access + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** RENDERING + **/ + +public: + LLQuaternion getHeadRotation(); + BOOL needsRenderAvatar(); // TRUE when camera mode is such that your own avatar should draw + BOOL needsRenderHead(); + void setShowAvatar(BOOL show) { mShowAvatar = show; } + BOOL getShowAvatar() const { return mShowAvatar; } + +private: + BOOL mShowAvatar; // Should we render the avatar? U32 mAppearanceSerialNum; - LLAnimPauseRequest mPauseRequest; - class createStandardWearablesAllDoneCallback : public LLRefCount - { - protected: - ~createStandardWearablesAllDoneCallback(); - }; - class sendAgentWearablesUpdateCallback : public LLRefCount - { - protected: - ~sendAgentWearablesUpdateCallback(); - }; + //-------------------------------------------------------------------- + // Rendering state bitmap helpers + //-------------------------------------------------------------------- +public: + void setRenderState(U8 newstate); + void clearRenderState(U8 clearstate); + U8 getRenderState(); +private: + U8 mRenderState; // Current behavior state of agent - class addWearableToAgentInventoryCallback : public LLInventoryCallback - { - public: - enum { - CALL_NONE = 0, - CALL_UPDATE = 1, - CALL_RECOVERDONE = 2, - CALL_CREATESTANDARDDONE = 4, - CALL_MAKENEWOUTFITDONE = 8 - } EType; + //-------------------------------------------------------------------- + // HUD + //-------------------------------------------------------------------- +public: + const LLColor4 &getEffectColor(); + void setEffectColor(const LLColor4 &color); +private: + LLColor4 *mEffectColor; - /** - * @brief Construct a callback for dealing with the wearables. - * - * Would like to pass the agent in here, but we can't safely - * count on it being around later. Just use gAgent directly. - * @param cb callback to execute on completion (??? unused ???) - * @param index Index for the wearable in the agent - * @param wearable The wearable data. - * @param todo Bitmask of actions to take on completion. - */ - addWearableToAgentInventoryCallback( - LLPointer cb, - S32 index, - LLWearable* wearable, - U32 todo = CALL_NONE); - virtual void fire(const LLUUID& inv_item); +/** Rendering + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** GROUPS + **/ + +public: + const LLUUID &getGroupID() const { return mGroupID; } + // Get group information by group_id, or FALSE if not in group. + BOOL getGroupData(const LLUUID& group_id, LLGroupData& data) const; + // Get just the agent's contribution to the given group. + S32 getGroupContribution(const LLUUID& group_id) const; + // Update internal datastructures and update the server. + BOOL setGroupContribution(const LLUUID& group_id, S32 contribution); + BOOL setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile); + const std::string &getGroupName() const { return mGroupName; } +private: + std::string mGroupName; + LLUUID mGroupID; - private: - S32 mIndex; - LLWearable* mWearable; - U32 mTodo; - LLPointer mCB; - }; + //-------------------------------------------------------------------- + // Group Membership + //-------------------------------------------------------------------- +public: + // Checks against all groups in the entire agent group list. + BOOL isInGroup(const LLUUID& group_id) const; +protected: + // Only used for building titles. + BOOL isGroupMember() const { return !mGroupID.isNull(); } +public: + LLDynamicArray mGroups; + //-------------------------------------------------------------------- + // Group Title + //-------------------------------------------------------------------- +public: + void setHideGroupTitle(BOOL hide) { mHideGroupTitle = hide; } + BOOL isGroupTitleHidden() const { return mHideGroupTitle; } + const std::string& getGroupTitle() const { return mGroupTitle; } +private: + std::string mGroupTitle; // Honorific, like "Sir" + BOOL mHideGroupTitle; + + //-------------------------------------------------------------------- + // Group Powers + //-------------------------------------------------------------------- +public: + BOOL hasPowerInGroup(const LLUUID& group_id, U64 power) const; + BOOL hasPowerInActiveGroup(const U64 power) const; + U64 getPowerInGroup(const LLUUID& group_id) const; + U64 mGroupPowers; + + //-------------------------------------------------------------------- + // Friends + //-------------------------------------------------------------------- +public: + void observeFriends(); + void friendsChanged(); +private: LLFriendObserver* mFriendObserver; + std::set mProxyForAgents; + +/** Groups + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** MESSAGING + **/ + + //-------------------------------------------------------------------- + // Send + //-------------------------------------------------------------------- +public: + void sendMessage(); // Send message to this agent's region. + void sendReliableMessage(); + void sendAgentSetAppearance(); + void sendAgentDataUpdateRequest(); + + //-------------------------------------------------------------------- + // Receive + //-------------------------------------------------------------------- +public: + static void processAgentDataUpdate(LLMessageSystem *msg, void **); + static void processAgentGroupDataUpdate(LLMessageSystem *msg, void **); + static void processAgentDropGroup(LLMessageSystem *msg, void **); + static void processScriptControlChange(LLMessageSystem *msg, void **); + static void processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data); + +/** Messaging + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** DEBUGGING + **/ + +public: + static void clearVisualParams(void *); + friend std::ostream& operator<<(std::ostream &s, const LLAgent &sphere); + +/** Debugging + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** Phantom mode! + **/ + + public: + static BOOL getPhantom(); + static void setPhantom(BOOL phantom); + static void togglePhantom(); +private: + static BOOL exlPhantom; +/** PHANTOM + ** ** + *******************************************************************************/ + +/******************************************************************************** + ** ** + ** Depreciated stuff. Move when ready. + **/ +public: + const LLUUID& getInventoryRootID() const { return mInventoryRootID; } + void setInventoryRootID(const LLUUID &id) { mInventoryRootID = id; } + //What's this t-posed stuff from? + static BOOL isTPosed() { return mForceTPose; } + static void setTPosed(BOOL TPose) { mForceTPose = TPose; } + static void toggleTPosed(); + +private: + LLUUID mInventoryRootID; + static BOOL mForceTPose; + + +/** DEPRECIATED + ** ** + *******************************************************************************/ + }; extern LLAgent gAgent; + +inline bool operator==(const LLGroupData &a, const LLGroupData &b) +{ + return (a.mID == b.mID); +} + +class LLAgentQueryManager +{ + friend class LLAgent; + friend class LLAgentWearables; + +public: + LLAgentQueryManager(); + virtual ~LLAgentQueryManager(); + + BOOL hasNoPendingQueries() const { return getNumPendingQueries() == 0; } + S32 getNumPendingQueries() const { return mNumPendingQueries; } +private: + S32 mNumPendingQueries; + S32 mWearablesCacheQueryID; //mTextureCacheQueryID; + U32 mUpdateSerialNum; //mAgentWearablesUpdateSerialNum + S32 mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES]; +}; + +extern LLAgentQueryManager gAgentQueryManager; + extern std::string gAuthString; // diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp new file mode 100644 index 000000000..a53c23897 --- /dev/null +++ b/indra/newview/llagentcamera.cpp @@ -0,0 +1,3071 @@ +/** + * @file llagentcamera.cpp + * @brief LLAgent class implementation + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llagentcamera.h" + +#include "pipeline.h" + +#include "llagent.h" +#include "llanimationstates.h" +#include "llfloatercamera.h" +#include "llfloatergroups.h" +#include "llhudmanager.h" +#include "lljoystickbutton.h" +#include "llselectmgr.h" +#include "llsmoothstep.h" +#include "lltoolmgr.h" +#include "llviewercamera.h" +#include "llviewercontrol.h" +#include "llviewerjoystick.h" +#include "llviewermenu.h" +#include "llviewerobjectlist.h" +#include "llviewerregion.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llwindow.h" +#include "llworld.h" +#include "llfloatertools.h" //For gFloaterTools +#include "floaterao.h" //For LLFloaterAO +#include "llfloatercustomize.h" //For gFloaterCustomize + +using namespace LLVOAvatarDefines; + +extern LLMenuBarGL* gMenuBarView; + +// 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 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.f;//0.1f; +const F32 MIN_CAMERA_DISTANCE = 0.f;//0.1f; + +const F32 AVATAR_ZOOM_MIN_X_FACTOR = 0.f;//0.55f; +const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.f;//0.7f; +const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 0.f;//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.1f; + +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; + +const F32 CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST = 3.5f; + +const F32 GROUND_TO_AIR_CAMERA_TRANSITION_TIME = 0.5f; +const F32 GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME = 0.5f; + +const F32 OBJECT_EXTENTS_PADDING = 0.5f; + +// The agent instance. +LLAgentCamera gAgentCamera; + +//----------------------------------------------------------------------------- +// LLAgentCamera() +//----------------------------------------------------------------------------- +LLAgentCamera::LLAgentCamera() : + mInitialized(false), + + mDrawDistance( DEFAULT_FAR_PLANE ), + + mLookAt(NULL), + mPointAt(NULL), + + mHUDTargetZoom(1.f), + mHUDCurZoom(1.f), + + mForceMouselook(FALSE), + + 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), + + mCameraOffsetDefault(), + 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), + + mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed + mWalkKey(0), // like AtKey, but causes less forward thrust + mLeftKey(0), + mUpKey(0), + mYawKey(0.f), + mPitchKey(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) +{ + mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT ); + + clearGeneralKeys(); + clearOrbitKeys(); + clearPanKeys(); +} + +// Requires gSavedSettings to be initialized. +//----------------------------------------------------------------------------- +// init() +//----------------------------------------------------------------------------- +void LLAgentCamera::init() +{ + // *Note: this is where LLViewerCamera::getInstance() used to be constructed. + + mDrawDistance = gSavedSettings.getF32("RenderFarClip"); + + 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->getDisplayAspectRatio() ); // default, overridden in LLViewerWindow::reshape + LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape + + mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild")); + + mCameraOffsetDefault = gSavedSettings.getVector3("CameraOffsetDefault");//Legacy + /*mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset"); + + mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("CameraOffsetRearView"); + mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("CameraOffsetFrontView"); + mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("CameraOffsetGroupView"); + + mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("FocusOffsetRearView"); + mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("FocusOffsetFrontView"); + mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("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); +} + +void LLAgentCamera::setAvatarObject(LLVOAvatar* avatar) +{ + if (!mLookAt) + { + mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); + } + if (!mPointAt) + { + mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); + } + + if (!mLookAt.isNull()) + { + mLookAt->setSourceObject(avatar); + } + if (!mPointAt.isNull()) + { + mPointAt->setSourceObject(avatar); + } +} + +//----------------------------------------------------------------------------- +// LLAgent() +//----------------------------------------------------------------------------- +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 (gAgent.getAutoPilot()) + { + gAgent.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(); + } + + if (gMenuHolder != NULL) + { + // Hide all popup menus + gMenuHolder->hideMenus(); + } + } + + static const LLCachedControl freeze_time("FreezeTime",false); + if (change_camera && !freeze_time) + { + 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); + }*/ + gFloaterTools->close(); + + gViewerWindow->showCursor(); + + // Switch back to basic toolset + LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); + } + + if (reset_camera && !freeze_time) + { + if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson()) + { + // leaving mouse-steer mode + LLVector3 agent_at_axis = gAgent.getAtAxis(); + agent_at_axis -= projected_vec(agent_at_axis, gAgent.getReferenceUpVector()); + agent_at_axis.normalize(); + gAgent.resetAxes(lerp(gAgent.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 (isAgentAvatarValid()) + { + setFocusGlobal(LLVector3d::zero, gAgent.getAvatarObject()->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(); + gAgent.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() || + //mFocusObject->isMesh() || + gSavedSettings.getBOOL("DisableCameraConstraints")) + { + 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() - gAgent.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 (gSavedSettings.getBOOL("AscentDisableMinZoomDist")) + { + return mCameraZoomFraction; + } + 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 = 65535.f*4.f;//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(); + BOOL disable_min = gSavedSettings.getBOOL("AscentDisableMinZoomDist"); + if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD) + { + mHUDTargetZoom = fraction; + } + else if (mFocusOnAvatar && cameraThirdPerson() && !disable_min) + { + 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 (!disable_min) + { + if (mFocusObject.notNull()) + { + if (mFocusObject->isAvatar()) + { + min_zoom = AVATAR_MIN_ZOOM; + } + else + { + min_zoom = OBJECT_MIN_ZOOM; + } + } + } + else + { + min_zoom = 0.f; + } + LLVector3d camera_offset_dir = mCameraFocusOffsetTarget; + camera_offset_dir.normalize(); + //mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom); + mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 65535.*4., 1.f, 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)) + { + gAgent.yaw(radians); + } + 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) + { + gAgent.pitch(angle); + } + else + { + LLVector3 camera_offset_unit(mCameraFocusOffsetTarget); + camera_offset_unit.normalize(); + + F32 angle_from_up = acos( camera_offset_unit * gAgent.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 = 0.f;//LAND_MIN_ZOOM; + F32 current_distance = (F32)camera_offset_unit.normalize(); + F32 new_distance = current_distance * fraction; + + if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist")) + { + 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*/ INT_MAX - DIST_FUDGE//, + /*LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE )*/; + + if (new_distance > max_distance) + { + // screw cam constraints + //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; + + static const LLCachedControl freeze_time("FreezeTime",false); + if (!freeze_time && 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) +{ + LLVOAvatar *pAvatar = gAgent.getAvatarObject(); // bleh + + static LLVector3 last_at_axis; + + if (!isAgentAvatarValid()) return; + + LLQuaternion av_inv_rot = ~pAvatar->mRoot.getWorldRotation(); + LLVector3 root_at = LLVector3::x_axis * pAvatar->mRoot.getWorldRotation(); + + if ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) && + (root_at * last_at_axis > 0.95f)) + { + LLVector3 vel = pAvatar->getVelocity(); + if (vel.magVecSquared() > 4.f) + { + setLookAt(LOOKAT_TARGET_IDLE, pAvatar, vel * av_inv_rot); + } + else + { + // *FIX: rotate mframeagent by sit object's rotation? + LLQuaternion look_rotation = pAvatar->isSitting() ? pAvatar->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); // use camera's current rotation + LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot; + setLookAt(LOOKAT_TARGET_IDLE, pAvatar, look_offset); + } + last_at_axis = root_at; + return; + } + + last_at_axis = root_at; + + if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode()) + { + setLookAt(LOOKAT_TARGET_NONE, pAvatar, 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->getWindowWidth() ) - 0.5f; + F32 y_from_center = + ((F32) mouse_y / (F32) gViewerWindow->getWindowHeight() ) - 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, pAvatar, headLookAxis); + } +} + +//----------------------------------------------------------------------------- +// updateCamera() +//----------------------------------------------------------------------------- +void LLAgentCamera::updateCamera() +{ + //static LLFastTimer::DeclareTimer ftm("Camera"); + //LLFastTimer t(ftm); + + LLVOAvatar *pAvatar = gAgent.getAvatarObject(); + + // - changed camera_skyward to the new global "mCameraUpVector" + mCameraUpVector = LLVector3::z_axis; + //LLVector3 camera_skyward(0.f, 0.f, 1.f); + + U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode; + + validateFocusObject(); + + if (isAgentAvatarValid() && + pAvatar->isSitting() && + camera_mode == CAMERA_MODE_MOUSELOOK) + { + //changed camera_skyward to the new global "mCameraUpVector" + mCameraUpVector = mCameraUpVector * pAvatar->getRenderRotation(); + } + + if (cameraThirdPerson() && mFocusOnAvatar && LLFollowCamMgr::getActiveFollowCamParams()) + { + changeCameraToFollow(); + } + + //NOTE - this needs to be integrated into a general upVector system here within llAgent. + if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar ) + { + mCameraUpVector = mFollowCam.getUpVector(); + } + + if (mSitCameraEnabled) + { + if (mSitCameraReferenceObject->isDead()) + { + setSitCamera(LLUUID::null); + } + } + + // Update UI with our camera inputs + LLFloaterCamera* camera_floater = LLFloaterCamera::getInstance();//LLFloaterReg::findTypedInstance("camera"); + if (camera_floater) + { + camera_floater->mRotate->setToggleState(gAgentCamera.getOrbitRightKey() > 0.f, // left + gAgentCamera.getOrbitUpKey() > 0.f, // top + gAgentCamera.getOrbitLeftKey() > 0.f, // right + gAgentCamera.getOrbitDownKey() > 0.f); // bottom + + camera_floater->mTrack->setToggleState(gAgentCamera.getPanLeftKey() > 0.f, // left + gAgentCamera.getPanUpKey() > 0.f, // top + gAgentCamera.getPanRightKey() > 0.f, // right + gAgentCamera.getPanDownKey() > 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 (gAgentCamera.getOrbitUpKey() || gAgentCamera.getOrbitDownKey()) + { + F32 input_rate = gAgentCamera.getOrbitUpKey() - gAgentCamera.getOrbitDownKey(); + cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped ); + } + + if (gAgentCamera.getOrbitLeftKey() || gAgentCamera.getOrbitRightKey()) + { + F32 input_rate = gAgentCamera.getOrbitLeftKey() - gAgentCamera.getOrbitRightKey(); + cameraOrbitAround(input_rate * ORBIT_AROUND_RATE / gFPSClamped); + } + + if (gAgentCamera.getOrbitInKey() || gAgentCamera.getOrbitOutKey()) + { + F32 input_rate = gAgentCamera.getOrbitInKey() - gAgentCamera.getOrbitOutKey(); + + 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 (gAgentCamera.getPanInKey() || gAgentCamera.getPanOutKey()) + { + F32 input_rate = gAgentCamera.getPanInKey() - gAgentCamera.getPanOutKey(); + cameraPanIn(input_rate * PAN_RATE / gFPSClamped); + } + + if (gAgentCamera.getPanRightKey() || gAgentCamera.getPanLeftKey()) + { + F32 input_rate = gAgentCamera.getPanRightKey() - gAgentCamera.getPanLeftKey(); + cameraPanLeft(input_rate * -PAN_RATE / gFPSClamped ); + } + + if (gAgentCamera.getPanUpKey() || gAgentCamera.getPanDownKey()) + { + F32 input_rate = gAgentCamera.getPanUpKey() - gAgentCamera.getPanDownKey(); + cameraPanUp(input_rate * PAN_RATE / gFPSClamped ); + } + + // Clear camera keyboard keys. + gAgentCamera.clearOrbitKeys(); + gAgentCamera.clearPanKeys(); + + // lerp camera focus offset + mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE)); + + if ( mCameraMode == CAMERA_MODE_FOLLOW ) + { + if (isAgentAvatarValid()) + { + //-------------------------------------------------------------------------------- + // 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 = pAvatar->isSitting() ? pAvatar->getRenderRotation() : gAgent.getFrameAgent().getQuaternion(); + + LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams(); + if (current_cam) + { + mFollowCam.copyParams(*current_cam); + mFollowCam.setSubjectPositionAndRotation( pAvatar->getRenderPosition(), avatarRotationForFollowCam ); + mFollowCam.update(); + LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); + } + else + { + changeCameraToThirdPerson(TRUE); + } + } + } + + BOOL hit_limit; + LLVector3d camera_pos_global; + LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit); + mCameraVirtualPositionAgent = gAgent.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); + + gAgent.setShowAvatar(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 ) + { + gAgent.setShowAvatar(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; + + gAgent.endAnimationUpdateUI(); + gAgent.setShowAvatar(TRUE); + } + + if (isAgentAvatarValid() && (mCameraMode != CAMERA_MODE_MOUSELOOK)) + { + pAvatar->updateAttachmentVisibility(mCameraMode); + } + } + else + { + camera_pos_global = camera_target_global; + mFocusGlobal = focus_target_global; + gAgent.setShowAvatar(TRUE); + } + + // smoothing + if (TRUE) + { + LLVector3d agent_pos = gAgent.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 + bool in_build_mode = LLToolMgr::getInstance()->inBuildMode(); + mCameraSmoothingStop = mCameraSmoothingStop || in_build_mode; + + 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 = gAgent.getPosAgentFromGlobal(mFocusGlobal); + + mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global); + + // Move the camera + + LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent); + //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent); + + //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 = gAgent.getPositionGlobal(); + if (!gAgent.getLastPositionGlobal().isExactlyZero()) + { + LLVector3d delta = global_pos - gAgent.getLastPositionGlobal(); + gAgent.setDistanceTraveled(gAgent.getDistanceTraveled() + delta.magVec()); + } + gAgent.setLastPositionGlobal(global_pos); + + if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !pAvatar->isSitting() && cameraMouselook()) + { + LLVector3 head_pos = pAvatar->mHeadp->getWorldPosition() + + LLVector3(0.08f, 0.f, 0.05f) * pAvatar->mHeadp->getWorldRotation() + + LLVector3(0.1f, 0.f, 0.f) * pAvatar->mPelvisp->getWorldRotation(); + LLVector3 diff = mCameraPositionAgent - head_pos; + diff = diff * ~pAvatar->mRoot.getWorldRotation(); + + LLJoint* torso_joint = pAvatar->mTorsop; + LLJoint* chest_joint = pAvatar->mChestp; + LLVector3 torso_scale = torso_joint->getScale(); + LLVector3 chest_scale = chest_joint->getScale(); + + // shorten avatar skeleton to avoid foot interpenetration + if (!pAvatar->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 = pAvatar->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; + } + + pAvatar->mPelvisp->setPosition(pAvatar->mPelvisp->getPosition() + diff); + + pAvatar->mRoot.updateWorldMatrixChildren(); + + for (LLVOAvatar::attachment_map_t::iterator iter = pAvatar->mAttachmentPoints.begin(); + iter != pAvatar->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::updateLastCamera() +{ + mLastCameraMode = mCameraMode; +} + +void LLAgentCamera::updateFocusOffset() +{ + validateFocusObject(); + if (mFocusObject.notNull()) + { + LLVector3d obj_pos = gAgent.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->getWindowWidth())))); + F32 apparent_angle = fraction_of_fov * LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); // radians + F32 offset = tan(apparent_angle); + + if( rect.mLeft < (gViewerWindow->getWindowWidth() - 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, gAgentCamera.getFocusGlobal()); + mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f)); + return mUIOffset * range; +} + +//----------------------------------------------------------------------------- +// calcFocusPositionTargetGlobal() +//----------------------------------------------------------------------------- +LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal() +{ + if (mFocusObject.notNull() && mFocusObject->isDead()) + { + clearFocusObject(); + } + + if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar) + { + mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus()); + return mFocusTargetGlobal; + } + else if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + LLVector3d at_axis(1.0, 0.0, 0.0); + LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion(); + if (isAgentAvatarValid() && gAgent.getAvatarObject()->getParent()) + { + LLViewerObject* root_object = (LLViewerObject*)gAgent.getAvatarObject()->getRoot(); + if (!root_object->flagCameraDecoupled()) + { + agent_rot *= ((LLViewerObject*)(gAgent.getAvatarObject()->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(gAgent.getPosGlobalFromAgent(focus_agent)); + } + return mFocusTargetGlobal; + } + else if (mSitCameraEnabled && isAgentAvatarValid() && gAgent.getAvatarObject()->isSitting() && mSitCameraReferenceObject.notNull()) + { + // sit camera + LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition(); + LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation(); + + LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot); + return gAgent.getPosGlobalFromAgent(target_pos); + } + else + { + return gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(); + } +} + +LLVector3d LLAgentCamera::calcThirdPersonFocusOffset() +{ + // ...offset from avatar + LLVector3d focus_offset; + focus_offset.setVec(gSavedSettings.getVector3("FocusOffsetDefault")); + LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion(); + if (isAgentAvatarValid() && gAgent.getAvatarObject()->getParent()) + { + agent_rot *= ((LLViewerObject*)(gAgent.getAvatarObject()->getParent()))->getRenderRotation(); + } + + //focus_offset = convert_from_llsd(mFocusOffsetInitial[mCameraPreset]->get(), TYPE_VEC3D, ""); + return focus_offset * agent_rot; +} + +void LLAgentCamera::setupSitCamera() +{ + // agent frame entering this function is in world coordinates + if (isAgentAvatarValid() && gAgent.getAvatarObject()->getParent()) + { + LLQuaternion parent_rot = ((LLViewerObject*)gAgent.getAvatarObject()->getParent())->getRenderRotation(); + // slam agent coordinate frame to proper parent local version + LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis(); + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis * ~parent_rot); + } +} + +//----------------------------------------------------------------------------- +// getCameraPositionAgent() +//----------------------------------------------------------------------------- +const LLVector3 &LLAgentCamera::getCameraPositionAgent() const +{ + return LLViewerCamera::getInstance()->getOrigin(); +} + +//----------------------------------------------------------------------------- +// getCameraPositionGlobal() +//----------------------------------------------------------------------------- +LLVector3d LLAgentCamera::getCameraPositionGlobal() const +{ + return gAgent.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; + if (!gSavedSettings.getBOOL("AscentDisableMinZoomDist")) + 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 = !isAgentAvatarValid() ? + gAgent.getPositionGlobal() : + gAgent.getPosGlobalFromAgent(gAgent.getAvatarObject()->mRoot.getWorldPosition()); + + LLVOAvatar *pAvatar = gAgent.getAvatarObject(); + BOOL isConstrained = FALSE; + LLVector3d head_offset; + head_offset.setVec(mThirdPersonHeadOffset); + + LLVector3d camera_position_global; + + if (mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar) + { + camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition()); + } + else if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + if (!isAgentAvatarValid() || pAvatar->mDrawable.isNull()) + { + llwarns << "Null avatar drawable!" << llendl; + return LLVector3d::zero; + } + head_offset.clearVec(); + if (pAvatar->isSitting() && pAvatar->getParent()) + { + pAvatar->updateHeadOffset(); + head_offset.mdV[VX] = pAvatar->mHeadOffset.mV[VX]; + head_offset.mdV[VY] = pAvatar->mHeadOffset.mV[VY]; + head_offset.mdV[VZ] = pAvatar->mHeadOffset.mV[VZ] + 0.1f; + const LLMatrix4& mat = ((LLViewerObject*) pAvatar->getParent())->getRenderMatrix(); + camera_position_global = gAgent.getPosGlobalFromAgent + ((gAgent.getAvatarObject()->getPosition()+ + LLVector3(head_offset)*pAvatar->getRotation()) * mat); + } + else + { + head_offset.mdV[VZ] = pAvatar->mHeadOffset.mV[VZ]; + if (pAvatar->isSitting()) + { + head_offset.mdV[VZ] += 0.1; + } + camera_position_global = gAgent.getPosGlobalFromAgent(pAvatar->getRenderPosition());//frame_center_global; + head_offset = head_offset * pAvatar->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 + && isAgentAvatarValid() + && pAvatar->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 = gAgent.getPosGlobalFromAgent(target_pos); + } + else + { + local_camera_offset = mCameraZoomFraction * getCameraOffsetInitial() * gSavedSettings.getF32("CameraOffsetScale"); + + // are we sitting down? + if (isAgentAvatarValid() && pAvatar->getParent()) + { + LLQuaternion parent_rot = ((LLViewerObject*)gAgent.getAvatarObject()->getParent())->getRenderRotation(); + // slam agent coordinate frame to proper parent local version + LLVector3 at_axis = gAgent.getFrameAgent().getAtAxis() * parent_rot; + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis * ~parent_rot); + + local_camera_offset = local_camera_offset * gAgent.getFrameAgent().getQuaternion() * parent_rot; + } + else + { + local_camera_offset = gAgent.getFrameAgent().rotateToAbsolute( local_camera_offset ); + } + + if (!mCameraCollidePlane.isExactlyZero() && (!isAgentAvatarValid() || !pAvatar->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 = gAgent.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 = !isAgentAvatarValid() ? LLVector3::zero : pAvatar->getRenderPosition(); + camera_offset.setVec( local_camera_offset ); + camera_position_global = frame_center_global + head_offset + camera_offset; + + if (isAgentAvatarValid()) + { + LLVector3d camera_lag_d; + F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE); + LLVector3 target_lag; + LLVector3 vel = gAgent.getVelocity(); + + // lag by appropriate amount for flying + F32 time_in_air = pAvatar->mTimeInAir.getElapsedTimeF32(); + if(!mCameraAnimating && pAvatar->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) + { + LLVector3 frame_at_axis = gAgent.getFrameAgent().getAtAxis(); + frame_at_axis -= projected_vec(frame_at_axis, gAgent.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 == pAvatar->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 convert_from_llsd(mCameraOffsetInitial[mCameraPreset]->get(), TYPE_VEC3, ""); + return mCameraOffsetDefault; +} + + +//----------------------------------------------------------------------------- +// 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 = gAgent.getFrameAgent().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 (!gSavedSettings.getBOOL("EnableMouselook") || LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + // visibility changes at end of animation + gViewerWindow->getWindow()->resetBusyCount(); + + // Menus should not remain open on switching to mouselook... + LLMenuGL::sMenuContainer->hideMenus(); + //LLUI::clearPopups(); + + // unpause avatar animation + gAgent.unpauseAnimation(); + + LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset); + + gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); + gSavedSettings.setBOOL("MouselookBtnState", TRUE); + gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE); + gSavedSettings.setBOOL("BuildBtnState", FALSE); + if (isAgentAvatarValid()) + { + gAgent.getAvatarObject()->stopMotion(ANIM_AGENT_BODY_NOISE); + gAgent.getAvatarObject()->stopMotion(ANIM_AGENT_BREATHE_ROT); + } + + //gViewerWindow->stopGrab(); + LLSelectMgr::getInstance()->deselectAll(); + gViewerWindow->hideCursor(); + gViewerWindow->moveCursorToCenter(); + + if (mCameraMode != CAMERA_MODE_MOUSELOOK) + { + gFocusMgr.setKeyboardFocus( NULL ); + if (gSavedSettings.getBOOL("AONoStandsInMouselook")) LLFloaterAO::stopMotion(LLFloaterAO::getCurrentStandId(), FALSE,TRUE); + + updateLastCamera(); + mCameraMode = CAMERA_MODE_MOUSELOOK; + const U32 old_flags = gAgent.getControlFlags(); + gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK); + if (old_flags != gAgent.getControlFlags()) + { + gAgent.setFlagsDirty(); + } + + if (animate) + { + startCameraAnimation(); + } + else + { + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } + } +} + + +//----------------------------------------------------------------------------- +// changeCameraToDefault() +//----------------------------------------------------------------------------- +void LLAgentCamera::changeCameraToDefault() +{ + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + if (LLFollowCamMgr::getActiveFollowCamParams()) + { + changeCameraToFollow(); + } + else + { + changeCameraToThirdPerson(); + } +} + + +//----------------------------------------------------------------------------- +// changeCameraToFollow() +//----------------------------------------------------------------------------- +void LLAgentCamera::changeCameraToFollow(BOOL animate) +{ + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + if(mCameraMode != CAMERA_MODE_FOLLOW) + { + if (mCameraMode == CAMERA_MODE_MOUSELOOK) + { + animate = FALSE; + } + startCameraAnimation(); + + updateLastCamera(); + 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 (isAgentAvatarValid()) + { + gAgent.getAvatarObject()->mPelvisp->setPosition(LLVector3::zero); + gAgent.getAvatarObject()->startMotion( ANIM_AGENT_BODY_NOISE ); + gAgent.getAvatarObject()->startMotion( ANIM_AGENT_BREATHE_ROT ); + } + + gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); + gSavedSettings.setBOOL("MouselookBtnState", FALSE); + gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE); + gSavedSettings.setBOOL("BuildBtnState", FALSE); + // unpause avatar animation + gAgent.unpauseAnimation(); + + gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); + + if (animate) + { + startCameraAnimation(); + } + else + { + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } + } +} + +//----------------------------------------------------------------------------- +// changeCameraToThirdPerson() +//----------------------------------------------------------------------------- +void LLAgentCamera::changeCameraToThirdPerson(BOOL animate) +{ + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + gViewerWindow->getWindow()->resetBusyCount(); + + mCameraZoomFraction = INITIAL_ZOOM_FRACTION; + + if (isAgentAvatarValid()) + { + if (!gAgent.getAvatarObject()->isSitting()) + { + gAgent.getAvatarObject()->mPelvisp->setPosition(LLVector3::zero); + } + gAgent.getAvatarObject()->startMotion(ANIM_AGENT_BODY_NOISE); + gAgent.getAvatarObject()->startMotion(ANIM_AGENT_BREATHE_ROT); + } + + gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); + gSavedSettings.setBOOL("MouselookBtnState", FALSE); + gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE); + gSavedSettings.setBOOL("BuildBtnState", FALSE); + + LLVector3 at_axis; + + // unpause avatar animation + gAgent.unpauseAnimation(); + + 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; + } + updateLastCamera(); + mCameraMode = CAMERA_MODE_THIRD_PERSON; + U32 old_flags = gAgent.getControlFlags(); + gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); + if (old_flags != gAgent.getControlFlags()) + { + gAgent.setFlagsDirty(); + } + } + + // Remove any pitch from the avatar + if (isAgentAvatarValid() && gAgent.getAvatarObject()->getParent()) + { + LLQuaternion obj_rot = ((LLViewerObject*)gAgent.getAvatarObject()->getParent())->getRenderRotation(); + at_axis = LLViewerCamera::getInstance()->getAtAxis(); + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis * ~obj_rot); + } + else + { + at_axis = gAgent.getFrameAgent().getAtAxis(); + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis); + } + + + if (animate) + { + startCameraAnimation(); + } + else + { + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } +} + +//----------------------------------------------------------------------------- +// changeCameraToCustomizeAvatar() +//----------------------------------------------------------------------------- +void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_animate) +{ + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { + return; + } + + // + //gAgent.standUp(); // force stand up + // + gViewerWindow->getWindow()->resetBusyCount(); + + if (gFaceEditToolset) + { + LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset); + } + + gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); + gSavedSettings.setBOOL("MouselookBtnState", FALSE); + gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE); + gSavedSettings.setBOOL("BuildBtnState", FALSE); + + if (camera_animate) + { + // + if(gSavedSettings.getBOOL("AppearanceCameraMovement")) + // + startCameraAnimation(); + } + + if (mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR) + { + updateLastCamera(); + mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR; + U32 old_flags = gAgent.getControlFlags(); + gAgent.clearControlFlags(AGENT_CONTROL_MOUSELOOK); + if (old_flags != gAgent.getControlFlags()) + { + gAgent.setFlagsDirty(); + } + + gFocusMgr.setKeyboardFocus( NULL ); + gFocusMgr.setMouseCapture( NULL ); + + LLVOAvatar::onCustomizeStart(); + + if (isAgentAvatarValid()) + { + if(avatar_animate) + { + // Remove any pitch or rotation from the avatar + LLVector3 at = gAgent.getAtAxis(); + at.mV[VZ] = 0.f; + at.normalize(); + gAgent.resetAxes(at); + + gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START); + gAgent.setCustomAnim(TRUE); + gAgent.getAvatarObject()->startMotion(ANIM_AGENT_CUSTOMIZE); + LLMotion* turn_motion = gAgent.getAvatarObject()->findMotion(ANIM_AGENT_CUSTOMIZE); + + if (turn_motion) + { + // delay camera animation long enough to play through turn animation + setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP); + } + else + { + setAnimationDuration(gSavedSettings.getF32("ZoomTime")); + } + //gAgentAvatarp->invalidateAll(); + //gAgentAvatarp->updateMeshTextures(); + } + + gAgentCamera.setFocusGlobal(LLVector3d::zero); + } + } + else + { + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } + + // + if(!gSavedSettings.getBOOL("AppearanceCameraMovement")) + { + //hmm + mCameraAnimating = FALSE; + gAgent.endAnimationUpdateUI(); + } + /*LLVector3 agent_at = gAgent.getAtAxis(); + agent_at.mV[VZ] = 0.f; + agent_at.normalize(); + + // default focus point for customize avatar + LLVector3 focus_target = isAgentAvatarValid() + ? gAgentAvatarp->mHeadp->getWorldPosition() + : gAgent.getPositionAgent(); + + LLVector3d camera_offset(agent_at * -1.0); + // push camera up and out from avatar + camera_offset.mdV[VZ] = 0.1f; + camera_offset *= CUSTOMIZE_AVATAR_CAMERA_DEFAULT_DIST; + LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target); + setAnimationDuration(gSavedSettings.getF32("ZoomTime")); + setCameraPosAndFocusGlobal(focus_target_global + camera_offset, focus_target_global, gAgent.getID());*/ +} + + +/*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 +// + +void LLAgentCamera::setAnimationDuration(F32 duration) +{ + if (mCameraAnimating) + { + // do not cut any existing camera animation short + F32 animation_left = llmax(0.f, mAnimationDuration - mAnimationTimer.getElapsedTimeF32()); + mAnimationDuration = llmax(duration, animation_left); + } + else + { + mAnimationDuration = duration; + } +} + +//----------------------------------------------------------------------------- +// startCameraAnimation() +//----------------------------------------------------------------------------- +void LLAgentCamera::startCameraAnimation() +{ + mAnimationCameraStartGlobal = getCameraPositionGlobal(); + mAnimationFocusStartGlobal = mFocusGlobal; + setAnimationDuration(gSavedSettings.getF32("ZoomTime")); + mAnimationTimer.reset(); + mCameraAnimating = TRUE; +} + +//----------------------------------------------------------------------------- +// 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 (isAgentAvatarValid()) + { + mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgent.getAvatarObject()->mHeadp->getWorldPosition()); + } + else + { + mFocusTargetGlobal = gAgent.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, (gAgent.getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation()); + } + } + else + { + setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.getPosAgentFromGlobal(mFocusTargetGlobal)); + } + } + } + else // focus == mFocusTargetGlobal + { + if (focus.isExactlyZero()) + { + if (isAgentAvatarValid()) + { + mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(gAgent.getAvatarObject()->mHeadp->getWorldPosition()); + } + else + { + mFocusTargetGlobal = gAgent.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() && !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.isExactlyZero() ? 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, (gAgent.getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation()); + } + } + else + { + setLookAt(LOOKAT_TARGET_FOCUS, NULL, gAgent.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 (isAgentAvatarValid() && gAgent.getAvatarObject()->getParent()) + { + LLQuaternion obj_rot = ((LLViewerObject*)gAgent.getAvatarObject()->getParent())->getRenderRotation(); + at_axis = LLViewerCamera::getInstance()->getAtAxis(); + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.resetAxes(at_axis * ~obj_rot); + } + else + { + at_axis = LLViewerCamera::getInstance()->getAtAxis(); + at_axis.mV[VZ] = 0.f; + at_axis.normalize(); + gAgent.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(gAgent.getPositionGlobal() + calcThirdPersonFocusOffset(), gAgent.getID()); + } + + mFocusOnAvatar = focus_on_avatar; +} + + +BOOL LLAgentCamera::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position) +{ + if(gSavedSettings.getBOOL("PrivateLookAt")) + { + if(!mLookAt || mLookAt->isDead()) + return FALSE; + position.clearVec(); + return mLookAt->setLookAt(LOOKAT_TARGET_NONE, gAgent.getAvatarObject(), position); + } + if(object && object->isAttachment()) + { + LLViewerObject* parent = object; + while(parent) + { + if (parent == gAgent.getAvatarObject()) + { + // looking at an attachment on ourselves, which we don't want to do + object = gAgent.getAvatarObject(); + position.clearVec(); + } + parent = (LLViewerObject*)parent->getParent(); + } + } + if(!mLookAt || mLookAt->isDead()) + { + mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT); + mLookAt->setSourceObject(gAgent.getAvatarObject()); + } + + return mLookAt->setLookAt(target_type, object, position); +} + +void LLAgentCamera::lookAtObject(LLUUID object_id, ECameraPosition camera_pos) +{ + // Block if camera is animating or not in normal third person camera mode + if (mCameraAnimating || !cameraThirdPerson()) + { + return; + } + + LLViewerObject *chatter = gObjectList.findObject(object_id); + if (chatter) + { + LLVector3 delta_pos; + if (chatter->isAvatar()) + { + LLVOAvatar *chatter_av = (LLVOAvatar*)chatter; + if (!gAgent.getAvatarObject() && chatter_av->mHeadp) + { + delta_pos = chatter_av->mHeadp->getWorldPosition() - gAgent.getAvatarObject()->mHeadp->getWorldPosition(); + } + else + { + delta_pos = chatter->getPositionAgent() - gAgent.getPositionAgent(); + } + delta_pos.normVec(); + + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + changeCameraToThirdPerson(); + + LLVector3 new_camera_pos = gAgent.getAvatarObject()->mHeadp->getWorldPosition(); + LLVector3 left = delta_pos % LLVector3::z_axis; + left.normVec(); + LLVector3 up = left % delta_pos; + up.normVec(); + new_camera_pos -= delta_pos * 0.4f; + new_camera_pos += left * 0.3f; + new_camera_pos += up * 0.2f; + + F32 radius = chatter_av->getVObjRadius(); + LLVector3d view_dist(radius, radius, 0.0f); + + if (chatter_av->mHeadp) + { + setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), object_id); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); + + switch(camera_pos) + { + case CAMERA_POSITION_SELF: + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); + break; + case CAMERA_POSITION_OBJECT: + mCameraFocusOffsetTarget = view_dist; + break; + } + } + else + { + setFocusGlobal(chatter->getPositionGlobal(), object_id); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); + + switch(camera_pos) + { + case CAMERA_POSITION_SELF: + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); + break; + case CAMERA_POSITION_OBJECT: + mCameraFocusOffsetTarget = view_dist; + break; + } + } + setFocusOnAvatar(FALSE, TRUE); + } + else + { + delta_pos = chatter->getRenderPosition() - gAgent.getPositionAgent(); + delta_pos.normVec(); + + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + changeCameraToThirdPerson(); + + LLVector3 new_camera_pos = gAgent.getAvatarObject()->mHeadp->getWorldPosition(); + LLVector3 left = delta_pos % LLVector3::z_axis; + left.normVec(); + LLVector3 up = left % delta_pos; + up.normVec(); + new_camera_pos -= delta_pos * 0.4f; + new_camera_pos += left * 0.3f; + new_camera_pos += up * 0.2f; + + setFocusGlobal(chatter->getPositionGlobal(), object_id); + + switch(camera_pos) + { + case CAMERA_POSITION_SELF: + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); + break; + case CAMERA_POSITION_OBJECT: + F32 radius = chatter->getVObjRadius(); + LLVector3d view_dist(radius, radius, 0.0f); + mCameraFocusOffsetTarget = view_dist; + break; + } + + setFocusOnAvatar(FALSE, TRUE); + } + } +} + +//----------------------------------------------------------------------------- +// lookAtLastChat() +//----------------------------------------------------------------------------- +void LLAgentCamera::lookAtLastChat() +{ + // Block if camera is animating or not in normal third person camera mode + if (mCameraAnimating || !cameraThirdPerson()) + { + return; + } + + LLViewerObject *chatter = gObjectList.findObject(gAgent.getLastChatter()); + if (!chatter) + { + return; + } + + LLVector3 delta_pos; + if (chatter->isAvatar()) + { + LLVOAvatar *chatter_av = (LLVOAvatar*)chatter; + if (isAgentAvatarValid() && chatter_av->mHeadp) + { + delta_pos = chatter_av->mHeadp->getWorldPosition() - gAgent.getAvatarObject()->mHeadp->getWorldPosition(); + } + else + { + delta_pos = chatter->getPositionAgent() - gAgent.getPositionAgent(); + } + delta_pos.normalize(); + + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + changeCameraToThirdPerson(); + + LLVector3 new_camera_pos = gAgent.getAvatarObject()->mHeadp->getWorldPosition(); + LLVector3 left = delta_pos % LLVector3::z_axis; + left.normalize(); + LLVector3 up = left % delta_pos; + up.normalize(); + new_camera_pos -= delta_pos * 0.4f; + new_camera_pos += left * 0.3f; + new_camera_pos += up * 0.2f; + + //setFocusOnAvatar(FALSE, FALSE); + + if (chatter_av->mHeadp) + { + setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), gAgent.getLastChatter()); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()); + } + else + { + setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter()); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); + } + setFocusOnAvatar(FALSE, TRUE); + } + else + { + delta_pos = chatter->getRenderPosition() - gAgent.getPositionAgent(); + delta_pos.normalize(); + + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + changeCameraToThirdPerson(); + + LLVector3 new_camera_pos = gAgent.getAvatarObject()->mHeadp->getWorldPosition(); + LLVector3 left = delta_pos % LLVector3::z_axis; + left.normalize(); + LLVector3 up = left % delta_pos; + up.normalize(); + new_camera_pos -= delta_pos * 0.4f; + new_camera_pos += left * 0.3f; + new_camera_pos += up * 0.2f; + + //setFocusOnAvatar(FALSE, FALSE); + + + setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter()); + mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal(); + setFocusOnAvatar(FALSE, TRUE); + } +} + +BOOL LLAgentCamera::setPointAt(EPointAtType target_type, LLViewerObject *object, LLVector3 position) +{ + // disallow pointing at attachments and avatars + if (object && (object->isAttachment() || object->isAvatar()) || gSavedSettings.getBOOL("DisablePointAtAndBeam")) + { + return FALSE; + } + if (!mPointAt || mPointAt->isDead()) + { + mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT); + mPointAt->setSourceObject(gAgent.getAvatarObject()); + } + 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; +} + +void LLAgentCamera::clearGeneralKeys() +{ + mAtKey = 0; + mWalkKey = 0; + mLeftKey = 0; + mUpKey = 0; + mYawKey = 0.f; + mPitchKey = 0.f; +} + +void LLAgentCamera::clearOrbitKeys() +{ + mOrbitLeftKey = 0.f; + mOrbitRightKey = 0.f; + mOrbitUpKey = 0.f; + mOrbitDownKey = 0.f; + mOrbitInKey = 0.f; + mOrbitOutKey = 0.f; +} + +void LLAgentCamera::clearPanKeys() +{ + mPanRightKey = 0.f; + mPanLeftKey = 0.f; + mPanUpKey = 0.f; + mPanDownKey = 0.f; + mPanInKey = 0.f; + mPanOutKey = 0.f; +} + +// static +S32 LLAgentCamera::directionToKey(S32 direction) +{ + if (direction > 0) return 1; + if (direction < 0) return -1; + return 0; +} + + +// EOF diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h new file mode 100644 index 000000000..c09ba546c --- /dev/null +++ b/indra/newview/llagentcamera.h @@ -0,0 +1,378 @@ +/** + * @file llagent.h + * @brief LLAgent class header file + * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLAGENTCAMERA_H +#define LL_LLAGENTCAMERA_H + +#include "llfollowcam.h" // Ventrella +#include "llhudeffectlookat.h" // EPointAtType +#include "llhudeffectpointat.h" // ELookAtType + +class LLPickInfo; +class LLVOAvatar; +class LLControlVariable; + + +//-------------------------------------------------------------------- +// Types +//-------------------------------------------------------------------- +enum ECameraMode +{ + CAMERA_MODE_THIRD_PERSON, + CAMERA_MODE_MOUSELOOK, + CAMERA_MODE_CUSTOMIZE_AVATAR, + CAMERA_MODE_FOLLOW +}; +typedef enum e_camera_position +{ + CAMERA_POSITION_SELF, /** Camera positioned at our position */ + CAMERA_POSITION_OBJECT /** Camera positioned at observed object's position */ +} ECameraPosition; + +//------------------------------------------------------------------------ +// LLAgentCamera +//------------------------------------------------------------------------ +class LLAgentCamera +{ + LOG_CLASS(LLAgentCamera); + +public: + //-------------------------------------------------------------------- + // Constructors / Destructors + //-------------------------------------------------------------------- +public: + LLAgentCamera(); + virtual ~LLAgentCamera(); + void init(); + void cleanup(); + void setAvatarObject(LLVOAvatar* avatar); + bool isInitialized() { return mInitialized; } +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 + F32 calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global ); + // Ventrella + void changeCameraToFollow(BOOL animate = TRUE); + //end 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; } + ECameraMode getLastCameraMode() const { return mLastCameraMode; } + void updateCamera(); // Call once per frame to update camera location/orientation + void resetCamera(); // Slam camera into its default position + void updateLastCamera(); // Set last camera to current camera + +private: + ECameraMode mCameraMode; // Target mode after transition animation is done + ECameraMode mLastCameraMode; + F32 mUIOffset; + /** Determines default camera offset depending on the current camera preset */ + LLVector3 getCameraOffsetInitial(); + +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 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); } + void clearCameraLag() { mCameraLag.clearVec(); } +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) + + //-------------------------------------------------------------------- + // 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 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); + void startCameraAnimation(); + void stopCameraAnimation(); +private: + LLFrameTimer mAnimationTimer; // Seconds that transition animation has been active + 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& 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 + LLVector3 mCameraOffsetDefault; + BOOL mFocusOnAvatar; + LLVector3d mFocusGlobal; + LLVector3d mFocusTargetGlobal; + LLPointer mFocusObject; + F32 mFocusObjectDist; + LLVector3 mFocusObjectOffset; + F32 mFocusDotRadius; // Meters + BOOL mTrackFocusObject; + + //-------------------------------------------------------------------- + // 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); + void lookAtObject(LLUUID object_id, ECameraPosition camera_pos); + ELookAtType getLookAtType(); + void lookAtLastChat(); + void slamLookAt(const LLVector3 &look_at); // Set the physics data + BOOL setPointAt(EPointAtType target_type, LLViewerObject *object = NULL, LLVector3 position = LLVector3::zero); + EPointAtType getPointAtType(); +public: + LLPointer mLookAt; + LLPointer 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(); +public: + F32 mDrawDistance; + + //-------------------------------------------------------------------- + // 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 + + +/******************************************************************************** + ** ** + ** KEYS + **/ + +public: + S32 getAtKey() const { return mAtKey; } + S32 getWalkKey() const { return mWalkKey; } + S32 getLeftKey() const { return mLeftKey; } + S32 getUpKey() const { return mUpKey; } + F32 getYawKey() const { return mYawKey; } + F32 getPitchKey() const { return mPitchKey; } + + void setAtKey(S32 mag) { mAtKey = mag; } + void setWalkKey(S32 mag) { mWalkKey = mag; } + void setLeftKey(S32 mag) { mLeftKey = mag; } + void setUpKey(S32 mag) { mUpKey = mag; } + void setYawKey(F32 mag) { mYawKey = mag; } + void setPitchKey(F32 mag) { mPitchKey = mag; } + + void clearGeneralKeys(); + static S32 directionToKey(S32 direction); // Changes direction to -1/0/1 + +private: + S32 mAtKey; // Either 1, 0, or -1. Indicates that movement key is pressed + S32 mWalkKey; // Like AtKey, but causes less forward thrust + S32 mLeftKey; + S32 mUpKey; + F32 mYawKey; + F32 mPitchKey; + + + //-------------------------------------------------------------------- + // Orbit + //-------------------------------------------------------------------- +public: + F32 getOrbitLeftKey() const { return mOrbitLeftKey; } + F32 getOrbitRightKey() const { return mOrbitRightKey; } + F32 getOrbitUpKey() const { return mOrbitUpKey; } + F32 getOrbitDownKey() const { return mOrbitDownKey; } + F32 getOrbitInKey() const { return mOrbitInKey; } + F32 getOrbitOutKey() const { return mOrbitOutKey; } + + 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; } + + void clearOrbitKeys(); +private: + F32 mOrbitLeftKey; + F32 mOrbitRightKey; + F32 mOrbitUpKey; + F32 mOrbitDownKey; + F32 mOrbitInKey; + F32 mOrbitOutKey; + + //-------------------------------------------------------------------- + // Pan + //-------------------------------------------------------------------- +public: + F32 getPanLeftKey() const { return mPanLeftKey; } + F32 getPanRightKey() const { return mPanRightKey; } + F32 getPanUpKey() const { return mPanUpKey; } + F32 getPanDownKey() const { return mPanDownKey; } + F32 getPanInKey() const { return mPanInKey; } + F32 getPanOutKey() const { return mPanOutKey; } + + 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; } + + void clearPanKeys(); +private: + F32 mPanUpKey; + F32 mPanDownKey; + F32 mPanLeftKey; + F32 mPanRightKey; + F32 mPanInKey; + F32 mPanOutKey; + +/** Keys + ** ** + *******************************************************************************/ + +}; + +extern LLAgentCamera gAgentCamera; + +#endif + diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp new file mode 100644 index 000000000..1ebc2d72b --- /dev/null +++ b/indra/newview/llagentwearables.cpp @@ -0,0 +1,1794 @@ +/** + * @file llagentwearables.cpp + * @brief LLAgentWearables class implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "llagentwearables.h" + +#include "llagent.h" +#include "llagentcamera.h" +#include "llcallbacklist.h" +#include "llfolderview.h" +#include "llgesturemgr.h" +#include "llinventorybridge.h" +#include "llmd5.h" +#include "llnotifications.h" +#include "lltexlayer.h" +#include "llviewerregion.h" +#include "llvoavatar.h" +#include "llwearable.h" +#include "llwearablelist.h" + +#include "cofmgr.h" +#include "llfloatercustomize.h" + +// [RLVa:KB] - Checked: 2010-09-27 (RLVa-1.1.3b) +#include "rlvhandler.h" +#include "rlvinventory.h" +#include "llattachmentsmgr.h" +// [/RLVa:KB] + +#include "hippogridmanager.h" + +#include + +LLAgentWearables gAgentWearables; + +using namespace LLVOAvatarDefines; +LLAgentWearables::LLAgentWearables() : + mWearablesLoaded(FALSE) +{ +} + +LLAgentWearables::~LLAgentWearables() +{ + cleanup(); +} + +void LLAgentWearables::cleanup() +{ +} + +// static +void LLAgentWearables::initClass() +{ +} + +void LLAgentWearables::setAvatarObject(LLVOAvatar *avatar) +{ + if (avatar) + { + sendAgentWearablesRequest(); + } +} +// wearables +LLAgentWearables::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback() +{ + llinfos << "destructor - all done?" << llendl; + gAgentWearables.createStandardWearablesAllDone(); +} + +LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback() +{ + gAgentWearables.sendAgentWearablesUpdate(); +} + +LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback( + LLPointer cb, S32 index, LLWearable* wearable, U32 todo) : + mIndex(index), + mWearable(wearable), + mTodo(todo), + mCB(cb) +{ + llinfos << "constructor" << llendl; +} + +void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item) +{ + if (inv_item.isNull()) + return; + + gAgentWearables.addWearabletoAgentInventoryDone(mIndex, inv_item, mWearable); + + if (mTodo & CALL_UPDATE) + { + gAgentWearables.sendAgentWearablesUpdate(); + } + if (mTodo & CALL_RECOVERDONE) + { + gAgentWearables.recoverMissingWearableDone(); + } + /* + * Do this for every one in the loop + */ + if (mTodo & CALL_CREATESTANDARDDONE) + { + gAgentWearables.createStandardWearablesDone(mIndex); + } + if (mTodo & CALL_MAKENEWOUTFITDONE) + { + gAgentWearables.makeNewOutfitDone(mIndex); + } +} + +void LLAgentWearables::addWearabletoAgentInventoryDone( + S32 index, + const LLUUID& item_id, + LLWearable* wearable) +{ + if (item_id.isNull()) + return; + + LLUUID old_item_id = mWearableEntry[index].mItemID; + mWearableEntry[index].mItemID = item_id; + mWearableEntry[index].mWearable = wearable; + if (old_item_id.notNull()) + gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + LLViewerInventoryItem* item = gInventory.getItem(item_id); + if(item && wearable) + { + // We're changing the asset id, so we both need to set it + // locally via setAssetUUID() and via setTransactionID() which + // will be decoded on the server. JC + item->setAssetUUID(wearable->getID()); + item->setTransactionID(wearable->getTransactionID()); + gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id); + item->updateServer(FALSE); + } + gInventory.notifyObservers(); +} + +void LLAgentWearables::sendAgentWearablesUpdate() +{ + // First make sure that we have inventory items for each wearable + S32 i; + for(i=0; i < WT_COUNT; ++i) + { + LLWearable* wearable = mWearableEntry[ i ].mWearable; + if (wearable) + { + if( mWearableEntry[ i ].mItemID.isNull() ) + { + LLPointer cb = + new addWearableToAgentInventoryCallback( + LLPointer(NULL), + i, + wearable, + addWearableToAgentInventoryCallback::CALL_NONE); + addWearableToAgentInventory(cb, wearable); + } + else + { + gInventory.addChangedMask( LLInventoryObserver::LABEL, + mWearableEntry[i].mItemID ); + } + } + } + + // Then make sure the inventory is in sync with the avatar. + gInventory.notifyObservers(); + + // This isn't the proper place to be doing this, but it's a good "catch-all" + LLCOFMgr::instance().synchWearables(); + + // Send the AgentIsNowWearing + gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing); + + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + LL_DEBUGS("Wearables") << "sendAgentWearablesUpdate()" << LL_ENDL; + for(i=0; i < WT_COUNT; ++i) + { + gMessageSystem->nextBlockFast(_PREHASH_WearableData); + + U8 type_u8 = (U8)i; + gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 ); + + LLWearable* wearable = mWearableEntry[ i ].mWearable; + if( wearable ) + { + LL_DEBUGS("Wearables") << "Sending wearable " << wearable->getName() << " mItemID = " << mWearableEntry[ i ].mItemID << LL_ENDL; + LLUUID item_id = mWearableEntry[i].mItemID; + const LLViewerInventoryItem *item = gInventory.getItem(item_id); + if (item && item->getIsLinkType()) + { + // Get the itemID that this item points to. i.e. make sure + // we are storing baseitems, not their links, in the database. + item_id = item->getLinkedUUID(); + } + gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id); + } + else + { + LL_DEBUGS("Wearables") << "Not wearing wearable type " << LLWearable::typeToTypeName((EWearableType)i) << LL_ENDL; + gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null ); + } + + LL_DEBUGS("Wearables") << " " << LLWearable::typeToTypeLabel((EWearableType)i) << " : " << (wearable ? wearable->getID() : LLUUID::null) << LL_ENDL; + } + gAgent.sendReliableMessage(); +} + +void LLAgentWearables::saveWearable( EWearableType type, BOOL send_update ) +{ + LLWearable* old_wearable = mWearableEntry[(S32)type].mWearable; + if( old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()) ) + { + LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); + mWearableEntry[(S32)type].mWearable = new_wearable; + + LLInventoryItem* item = gInventory.getItem(mWearableEntry[(S32)type].mItemID); + if( item ) + { + // Update existing inventory item + LLPointer template_item = + new LLViewerInventoryItem(item->getUUID(), + item->getParentUUID(), + item->getPermissions(), + new_wearable->getID(), + new_wearable->getAssetType(), + item->getInventoryType(), + item->getName(), + item->getDescription(), + item->getSaleInfo(), + item->getFlags(), + item->getCreationDate()); + template_item->setTransactionID(new_wearable->getTransactionID()); + template_item->updateServer(FALSE); + gInventory.updateItem(template_item); + } + else + { + // Add a new inventory item (shouldn't ever happen here) + U32 todo = addWearableToAgentInventoryCallback::CALL_NONE; + if (send_update) + { + todo |= addWearableToAgentInventoryCallback::CALL_UPDATE; + } + LLPointer cb = + new addWearableToAgentInventoryCallback( + LLPointer(NULL), + (S32)type, + new_wearable, + todo); + addWearableToAgentInventory(cb, new_wearable); + return; + } + + gAgent.getAvatarObject()->wearableUpdated( type ); + + if( send_update ) + { + sendAgentWearablesUpdate(); + } + } +} + +void LLAgentWearables::saveWearableAs( + EWearableType type, + const std::string& new_name, + BOOL save_in_lost_and_found) +{ + if(!isWearableCopyable(type)) + { + llwarns << "LLAgent::saveWearableAs() not copyable." << llendl; + return; + } + LLWearable* old_wearable = getWearable(type); + if(!old_wearable) + { + llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl; + return; + } + LLInventoryItem* item = gInventory.getItem(mWearableEntry[type].mItemID); + if(!item) + { + llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl; + return; + } + std::string trunc_name(new_name); + LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); + LLWearable* new_wearable = gWearableList.createCopyFromAvatar( + old_wearable, + trunc_name); + LLPointer cb = + new addWearableToAgentInventoryCallback( + LLPointer(NULL), + type, + new_wearable, + addWearableToAgentInventoryCallback::CALL_UPDATE); + LLUUID category_id; + if (save_in_lost_and_found) + { + category_id = gInventory.findCategoryUUIDForType( + LLAssetType::AT_LOST_AND_FOUND); + } + else + { + // put in same folder as original + category_id = item->getParentUUID(); + } + + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + category_id, + new_name, + cb); + +/* + LLWearable* old_wearable = getWearable( type ); + if( old_wearable ) + { + std::string old_name = old_wearable->getName(); + old_wearable->setName( new_name ); + LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable ); + old_wearable->setName( old_name ); + + LLUUID category_id; + LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID ); + if( item ) + { + new_wearable->setPermissions(item->getPermissions()); + if (save_in_lost_and_found) + { + category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); + } + else + { + // put in same folder as original + category_id = item->getParentUUID(); + } + LLInventoryView* view = LLInventoryView::getActiveInventory(); + if(view) + { + view->getPanel()->setSelection(item->getUUID(), TAKE_FOCUS_NO); + } + } + + mWearableEntry[ type ].mWearable = new_wearable; + LLPointer cb = + new addWearableToAgentInventoryCallback( + LLPointer(NULL), + type, + addWearableToAgentInventoryCallback::CALL_UPDATE); + addWearableToAgentInventory(cb, new_wearable, category_id); + } +*/ +} + +void LLAgentWearables::revertWearable( EWearableType type ) +{ + LLWearable* wearable = mWearableEntry[(S32)type].mWearable; + if( wearable ) + { + wearable->writeToAvatar( TRUE ); + } + gAgent.sendAgentSetAppearance(); +} + +void LLAgentWearables::revertAllWearables() +{ + for( S32 i=0; i < WT_COUNT; i++ ) + { + revertWearable( (EWearableType)i ); + } +} + +void LLAgentWearables::saveAllWearables() +{ + //if(!gInventory.isLoaded()) + //{ + // return; + //} + + for( S32 i=0; i < WT_COUNT; i++ ) + { + saveWearable( (EWearableType)i, FALSE ); + } + sendAgentWearablesUpdate(); +} + +// Called when the user changes the name of a wearable inventory item that is currenlty being worn. +void LLAgentWearables::setWearableName( const LLUUID& item_id, const std::string& new_name ) +{ + for( S32 i=0; i < WT_COUNT; i++ ) + { + if( mWearableEntry[i].mItemID == item_id ) + { + LLWearable* old_wearable = mWearableEntry[i].mWearable; + llassert( old_wearable ); + + std::string old_name = old_wearable->getName(); + old_wearable->setName( new_name ); + LLWearable* new_wearable = gWearableList.createCopy( old_wearable ); + LLInventoryItem* item = gInventory.getItem(item_id); + if(item) + { + new_wearable->setPermissions(item->getPermissions()); + } + old_wearable->setName( old_name ); + + mWearableEntry[i].mWearable = new_wearable; + sendAgentWearablesUpdate(); + break; + } + } +} + + +BOOL LLAgentWearables::isWearableModifiable(EWearableType type) const +{ + LLUUID item_id = getWearableItemID(type); + return item_id.notNull() ? isWearableModifiable(item_id) : FALSE; +} + +BOOL LLAgentWearables::isWearableModifiable(const LLUUID& item_id) const +{ + if(!item_id.isNull()) + { + LLInventoryItem* item = gInventory.getItem(item_id); + if(item && item->getPermissions().allowModifyBy(gAgent.getID(), + gAgent.getGroupID())) + { + return TRUE; + } + } + return FALSE; +} + +BOOL LLAgentWearables::isWearableCopyable(EWearableType type) const +{ + LLUUID item_id = getWearableItemID(type); + if(!item_id.isNull()) + { + LLInventoryItem* item = gInventory.getItem(item_id); + if(item && item->getPermissions().allowCopyBy(gAgent.getID(), + gAgent.getGroupID())) + { + return TRUE; + } + } + return FALSE; +} + +U32 LLAgentWearables::getWearablePermMask(EWearableType type) const +{ + LLUUID item_id = getWearableItemID(type); + if(!item_id.isNull()) + { + LLInventoryItem* item = gInventory.getItem(item_id); + if(item) + { + return item->getPermissions().getMaskOwner(); + } + } + return PERM_NONE; +} + +LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type) +{ + LLUUID item_id = getWearableItemID(type); + LLInventoryItem* item = NULL; + if(item_id.notNull()) + { + item = gInventory.getItem(item_id); + } + return item; +} + +const LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) const +{ + for( S32 i=0; i < WT_COUNT; i++ ) + { + if( mWearableEntry[i].mItemID == item_id ) + { + return mWearableEntry[i].mWearable; + } + } + return NULL; +} + +LLWearable* LLAgentWearables::getWearableFromItemID( const LLUUID& item_id ) +{ + for( S32 i=0; i < WT_COUNT; i++ ) + { + if( mWearableEntry[i].mItemID == item_id ) + { + return mWearableEntry[i].mWearable; + } + } + return NULL; +} + + +void LLAgentWearables::sendAgentWearablesRequest() +{ + gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + gAgent.sendReliableMessage(); +} + +// Used to enable/disable menu items. +// static +BOOL LLAgentWearables::selfHasWearable( void* userdata ) +{ + EWearableType type = (EWearableType)(intptr_t)userdata; + return gAgentWearables.getWearable( type ) != NULL; +} +LLWearable* LLAgentWearables::getWearable(const EWearableType type) +{ + return (type < WT_COUNT) ? mWearableEntry[ type ].mWearable : NULL; +} +const LLWearable* LLAgentWearables::getWearable(const EWearableType type) const +{ + return (type < WT_COUNT) ? mWearableEntry[ type ].mWearable : NULL; +} + +const LLUUID &LLAgentWearables::getWearableItemID(EWearableType type) const +{ + return (type < WT_COUNT) ? mWearableEntry[ type ].mItemID : LLUUID::null; +} + +BOOL LLAgentWearables::isWearingItem( const LLUUID& item_id ) const +{ + const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id); + return (getWearableFromItemID(base_item_id) != NULL); +} + +// static +void LLAgentWearables::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void** user_data ) +{ + // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates + // that may result from AgentWearablesRequest having been sent more than once. + static bool first = true; + if (!first) return; + first = false; + + LLUUID agent_id; + gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); + + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( avatar && (agent_id == avatar->getID()) ) + { + gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgentQueryManager.mUpdateSerialNum ); + + S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData); + if( num_wearables < 4 ) + { + // Transitional state. Avatars should always have at least their body parts (hair, eyes, shape and skin). + // The fact that they don't have any here (only a dummy is sent) implies that this account existed + // before we had wearables, or that the database has gotten messed up. + return; + } + + //lldebugs << "processAgentInitialWearablesUpdate()" << llendl; + // Add wearables + LLUUID asset_id_array[ WT_COUNT ]; + S32 i; + for( i=0; i < num_wearables; i++ ) + { + U8 type_u8 = 0; + gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i ); + if( type_u8 >= WT_COUNT ) + { + continue; + } + EWearableType type = (EWearableType) type_u8; + + LLUUID item_id; + gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i ); + + LLUUID asset_id; + gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i ); + if( asset_id.isNull() ) + { + LLWearable::removeFromAvatar( type, FALSE ); + } + else + { + LLAssetType::EType asset_type = LLWearable::typeToAssetType( type ); + if( asset_type == LLAssetType::AT_NONE ) + { + continue; + } + + gAgentWearables.mWearableEntry[type].mItemID = item_id; + asset_id_array[type] = asset_id; + } + + LL_DEBUGS("Wearables") << " " << LLWearable::typeToTypeLabel(type) << " " << asset_id << " item id " << gAgentWearables.mWearableEntry[type].mItemID.asString() << LL_ENDL; + } + + LLCOFMgr::instance().fetchCOF(); + + // now that we have the asset ids...request the wearable assets + for( i = 0; i < WT_COUNT; i++ ) + { + LL_DEBUGS("Wearables") << " fetching " << asset_id_array[i] << LL_ENDL; + if( !gAgentWearables.mWearableEntry[i].mItemID.isNull() ) + { + gWearableList.getAsset( + asset_id_array[i], + LLStringUtil::null, + LLWearable::typeToAssetType( (EWearableType) i ), + LLAgentWearables::onInitialWearableAssetArrived, (void*)(intptr_t)i ); + } + } + + // Not really sure where else to put this + gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle, NULL); + } +} + +// A single wearable that the avatar was wearing on start-up has arrived from the database. +// static +void LLAgentWearables::onInitialWearableAssetArrived( LLWearable* wearable, void* userdata ) +{ + EWearableType type = (EWearableType)(intptr_t)userdata; + + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( !avatar ) + { + return; + } + + if( wearable ) + { + llassert( type == wearable->getType() ); + gAgentWearables.mWearableEntry[ type ].mWearable = wearable; + + // disable composites if initial textures are baked + avatar->setupComposites(); + gAgentWearables.queryWearableCache(); + + wearable->writeToAvatar( FALSE ); + avatar->setCompositeUpdatesEnabled(TRUE); + gInventory.addChangedMask( LLInventoryObserver::LABEL, gAgentWearables.mWearableEntry[type].mItemID ); + } + else + { + // Somehow the asset doesn't exist in the database. + gAgentWearables.recoverMissingWearable( type ); + } + + gInventory.notifyObservers(); + + // Have all the wearables that the avatar was wearing at log-in arrived? + if( !gAgentWearables.mWearablesLoaded ) + { + gAgentWearables.mWearablesLoaded = TRUE; + for( S32 i = 0; i < WT_COUNT; i++ ) + { + if( !gAgentWearables.mWearableEntry[i].mItemID.isNull() && !gAgentWearables.mWearableEntry[i].mWearable ) + { + gAgentWearables.mWearablesLoaded = FALSE; + break; + } + } + } + + if( gAgentWearables.mWearablesLoaded ) + { + // Make sure that the server's idea of the avatar's wearables actually match the wearables. + gAgent.sendAgentSetAppearance(); + + // 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( !gAgentCamera.cameraCustomizeAvatar() ) + { + avatar->requestLayerSetUploads(); + } + } +} + +// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the +// database. If for some reason, we can't load one of those assets, we can try to reconstruct it so that +// the user isn't left without a shape, for example. (We can do that only after the inventory has loaded.) +void LLAgentWearables::recoverMissingWearable( EWearableType type ) +{ + // Try to recover by replacing missing wearable with a new one. + LLNotifications::instance().add("ReplacedMissingWearable"); + lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; + LLWearable* new_wearable = gWearableList.createNewWearable(type); + + S32 type_s32 = (S32) type; + mWearableEntry[type_s32].mWearable = new_wearable; + new_wearable->writeToAvatar( TRUE ); + + // Add a new one in the lost and found folder. + // (We used to overwrite the "not found" one, but that could potentially + // destory content.) JC + LLUUID lost_and_found_id = + gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); + LLPointer cb = + new addWearableToAgentInventoryCallback( + LLPointer(NULL), + type_s32, + new_wearable, + addWearableToAgentInventoryCallback::CALL_RECOVERDONE); + addWearableToAgentInventory( cb, new_wearable, lost_and_found_id, TRUE); +} + +void LLAgentWearables::recoverMissingWearableDone() +{ + // Have all the wearables that the avatar was wearing at log-in arrived or been fabricated? + mWearablesLoaded = TRUE; + for( S32 i = 0; i < WT_COUNT; i++ ) + { + if( !mWearableEntry[i].mItemID.isNull() && !mWearableEntry[i].mWearable ) + { + mWearablesLoaded = FALSE; + break; + } + } + + if( mWearablesLoaded ) + { + // Make sure that the server's idea of the avatar's wearables actually match the wearables. + gAgent.sendAgentSetAppearance(); + } + else + { + gInventory.addChangedMask( LLInventoryObserver::LABEL, LLUUID::null ); + gInventory.notifyObservers(); + } +} + +void LLAgentWearables::createStandardWearables(BOOL female) +{ + llwarns << "Creating Standard " << (female ? "female" : "male" ) + << " Wearables" << llendl; + + if (!isAgentAvatarValid()) return; + + gAgent.getAvatarObject()->setSex(female ? SEX_FEMALE : SEX_MALE); + + const BOOL create[WT_COUNT] = + { + TRUE, //WT_SHAPE + TRUE, //WT_SKIN + TRUE, //WT_HAIR + TRUE, //WT_EYES + TRUE, //WT_SHIRT + TRUE, //WT_PANTS + TRUE, //WT_SHOES + TRUE, //WT_SOCKS + FALSE, //WT_JACKET + FALSE, //WT_GLOVES + TRUE, //WT_UNDERSHIRT + TRUE, //WT_UNDERPANTS + FALSE, //WT_SKIRT + FALSE, //WT_ALPHA + FALSE, //WT_TATTOO + FALSE, //WT_PHYSICS + }; + + for( S32 i=0; i < WT_COUNT; i++ ) + { + bool once = false; + LLPointer donecb = NULL; + if( create[i] ) + { + if (!once) + { + once = true; + donecb = new createStandardWearablesAllDoneCallback; + } + llassert( mWearableEntry[i].mWearable == NULL ); + LLWearable* wearable = gWearableList.createNewWearable((EWearableType)i); + mWearableEntry[i].mWearable = wearable; + // no need to update here... + LLPointer cb = + new addWearableToAgentInventoryCallback( + donecb, + i, + wearable, + addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE); + addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE); + } + } +} +void LLAgentWearables::createStandardWearablesDone(S32 index) +{ + LLWearable* wearable = mWearableEntry[index].mWearable; + + if (wearable) + { + wearable->writeToAvatar(TRUE); + } +} + +void LLAgentWearables::createStandardWearablesAllDone() +{ + // ... because sendAgentWearablesUpdate will notify inventory + // observers. + mWearablesLoaded = TRUE; + sendAgentWearablesUpdate(); + gAgent.sendAgentSetAppearance(); + + // Treat this as the first texture entry message, if none received yet + gAgent.getAvatarObject()->onFirstTEMessageReceived(); +} + +void LLAgentWearables::makeNewOutfit( + const std::string& new_folder_name, + const LLDynamicArray& wearables_to_include, + const LLDynamicArray& attachments_to_include, + BOOL rename_clothing) +{ + if (!gAgent.getAvatarObject()) + { + return; + } + + BOOL fUseLinks = !gSavedSettings.getBOOL("UseInventoryLinks") || + !gHippoGridManager->getConnectedGrid()->supportsInvLinks(); + BOOL fUseOutfits = gSavedSettings.getBOOL("UseOutfitFolders") && + gHippoGridManager->getConnectedGrid()->supportsInvLinks(); + + LLAssetType::EType typeDest = (fUseOutfits) ? LLAssetType::AT_MY_OUTFITS : LLAssetType::AT_CLOTHING; + LLAssetType::EType typeFolder = (fUseOutfits) ? LLAssetType::AT_OUTFIT : LLAssetType::AT_NONE; + + // First, make a folder for the outfit. + LLUUID folder_id = gInventory.createNewCategory(gInventory.findCategoryUUIDForType(typeDest), typeFolder, new_folder_name); + + bool found_first_item = false; + + /////////////////// + // Wearables + + if( wearables_to_include.count() ) + { + // Then, iterate though each of the wearables and save copies of them in the folder. + S32 i; + S32 count = wearables_to_include.count(); + LLPointer cbdone = NULL; + for( i = 0; i < count; ++i ) + { + S32 index = wearables_to_include[i]; + LLWearable* old_wearable = mWearableEntry[ index ].mWearable; + if( old_wearable ) + { + LLViewerInventoryItem* item = gInventory.getItem(mWearableEntry[index].mItemID); + if (fUseOutfits) + { + std::string strOrdering = llformat("@%d", item->getWearableType() * 100); + + link_inventory_item( + gAgent.getID(), + item->getLinkedUUID(), + folder_id, + item->getName(), + strOrdering, + LLAssetType::AT_LINK, + LLPointer(NULL)); + } + else + { + std::string new_name = item->getName(); + if (rename_clothing) + { + new_name = new_folder_name; + new_name.append(" "); + new_name.append(old_wearable->getTypeLabel()); + LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN); + } + + if (fUseLinks || isWearableCopyable((EWearableType)index)) + { + LLWearable* new_wearable = gWearableList.createCopy(old_wearable); + if (rename_clothing) + { + new_wearable->setName(new_name); + } + + S32 todo = addWearableToAgentInventoryCallback::CALL_NONE; + if (!found_first_item) + { + found_first_item = true; + /* set the focus to the first item */ + todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE; + /* send the agent wearables update when done */ + cbdone = new sendAgentWearablesUpdateCallback; + } + LLPointer cb = + new addWearableToAgentInventoryCallback( + cbdone, + index, + new_wearable, + todo); + if (isWearableCopyable((EWearableType)index)) + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getLinkedUUID(), + folder_id, + new_name, + cb); + } + else + { + move_inventory_item( + gAgent.getID(), + gAgent.getSessionID(), + item->getLinkedUUID(), + folder_id, + new_name, + cb); + } + } + else + { + link_inventory_item( + gAgent.getID(), + item->getLinkedUUID(), + folder_id, + item->getName(), // Apparently, links cannot have arbitrary names... + item->getDescription(), + LLAssetType::AT_LINK, + LLPointer(NULL)); + } + } + } + } + gInventory.notifyObservers(); + } + + + /////////////////// + // Attachments + + if( attachments_to_include.count() ) + { + for( S32 i = 0; i < attachments_to_include.count(); i++ ) + { + S32 attachment_pt = attachments_to_include[i]; + LLViewerJointAttachment* attachment = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL ); + if(!attachment) continue; + 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) continue; + const LLUUID& item_id = attached_object->getAttachmentItemID(); + if (item_id.isNull()) continue; + LLInventoryItem* item = gInventory.getItem(item_id); + if (!item) continue; + if (fUseOutfits) + { + link_inventory_item( + gAgent.getID(), + item->getLinkedUUID(), + folder_id, + item->getName(), + item->getDescription(), + LLAssetType::AT_LINK, + LLPointer(NULL)); + } + else + { + if (fUseLinks || item->getPermissions().allowCopyBy(gAgent.getID())) + { + const LLUUID& old_folder_id = item->getParentUUID(); + + move_inventory_item( + gAgent.getID(), + gAgent.getSessionID(), + item->getLinkedUUID(), + folder_id, + item->getName(), + LLPointer(NULL)); + + if (item->getPermissions().allowCopyBy(gAgent.getID())) + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getLinkedUUID(), + old_folder_id, + item->getName(), + LLPointer(NULL)); + } + } + else + { + link_inventory_item( + gAgent.getID(), + item->getLinkedUUID(), + folder_id, + item->getName(), + item->getDescription(), + LLAssetType::AT_LINK, + LLPointer(NULL)); + } + } + } + } + } +} + +void LLAgentWearables::makeNewOutfitDone(S32 index) +{ + LLUUID first_item_id = mWearableEntry[index].mItemID; + // Open the inventory and select the first item we added. + if( first_item_id.notNull() ) + { + LLInventoryView* view = LLInventoryView::getActiveInventory(); + if(view) + { + view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO); + } + } +} + + +void LLAgentWearables::addWearableToAgentInventory(LLPointer cb, + LLWearable* wearable, + const LLUUID& category_id, + BOOL notify) +{ + create_inventory_item(gAgent.getID(), + gAgent.getSessionID(), + category_id, + wearable->getTransactionID(), + wearable->getName(), + wearable->getDescription(), + wearable->getAssetType(), + LLInventoryType::IT_WEARABLE, + wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + cb); +} + +void LLAgentWearables::removeWearable( EWearableType type ) +{ + LLWearable* old_wearable = mWearableEntry[ type ].mWearable; + + if ( (gAgent.isTeen()) + && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS)) + { + // Can't take off underclothing in simple UI mode or on PG accounts + return; + } + +// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.1.3b) + if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(type)) ) + { + return; + } +// [/RLVa:KB] + + if( old_wearable ) + { + if( old_wearable->isDirty() ) + { + LLSD payload; + payload["wearable_type"] = (S32)type; + // Bring up view-modal dialog: Save changes? Yes, No, Cancel + LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgentWearables::onRemoveWearableDialog); + return; + } + else + { + removeWearableFinal( type ); + } + } +} + +// static +bool LLAgentWearables::onRemoveWearableDialog(const LLSD& notification, const LLSD& response ) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger(); + switch( option ) + { + case 0: // "Save" + gAgentWearables.saveWearable( type ); + gAgentWearables.removeWearableFinal( type ); + break; + + case 1: // "Don't Save" + gAgentWearables.removeWearableFinal( type ); + break; + + case 2: // "Cancel" + break; + + default: + llassert(0); + break; + } + return false; +} + +// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal. +void LLAgentWearables::removeWearableFinal( EWearableType type ) +{ + LLWearable* old_wearable = mWearableEntry[ type ].mWearable; + + gInventory.addChangedMask( LLInventoryObserver::LABEL, mWearableEntry[type].mItemID ); + + mWearableEntry[ type ].mWearable = NULL; + mWearableEntry[ type ].mItemID.setNull(); + + queryWearableCache(); + + if( old_wearable ) + { + old_wearable->removeFromAvatar( TRUE ); + } + + // Update the server + sendAgentWearablesUpdate(); + gAgent.sendAgentSetAppearance(); + gInventory.notifyObservers(); +} + +void LLAgentWearables::copyWearableToInventory( EWearableType type ) +{ + LLWearable* wearable = mWearableEntry[ type ].mWearable; + if( wearable ) + { + // Save the old wearable if it has changed. + if( wearable->isDirty() ) + { + wearable = gWearableList.createCopyFromAvatar( wearable ); + mWearableEntry[ type ].mWearable = wearable; + } + + // Make a new entry in the inventory. (Put it in the same folder as the original item if possible.) + LLUUID category_id; + LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID ); + if( item ) + { + category_id = item->getParentUUID(); + wearable->setPermissions(item->getPermissions()); + } + LLPointer cb = + new addWearableToAgentInventoryCallback( + LLPointer(NULL), + type, + wearable); + addWearableToAgentInventory(cb, wearable, category_id); + } +} + + +// A little struct to let setWearable() communicate more than one value with onSetWearableDialog(). +struct LLSetWearableData +{ + LLSetWearableData( const LLUUID& new_item_id, LLWearable* new_wearable ) : + mNewItemID( new_item_id ), mNewWearable( new_wearable ) {} + LLUUID mNewItemID; + LLWearable* mNewWearable; +}; + +static bool isFirstPhysicsWearable(EWearableType type, LLInventoryItem *new_item, LLWearable *new_wearable) +{ + if (type == WT_PHYSICS && gSavedSettings.getWarning("FirstPhysicsWearable")) + { + class WearableDelayedCallback + { + public: + static void setDelayedWearable( const LLSD& notification, const LLSD& response, LLUUID item_id, LLWearable *wearable ) + { + if(LLNotification::getSelectedOption(notification, response) == 0) //User selected wear + { + gSavedSettings.setWarning("FirstPhysicsWearable",FALSE); + LLInventoryItem *item = gInventory.getItem(item_id); + if(item) + gAgentWearables.setWearableItem(item,wearable); //re-enter. + } + } + }; + LLNotifications::instance().add("FirstPhysicsWearable",LLSD(),LLSD(),boost::bind(WearableDelayedCallback::setDelayedWearable, _1, _2, new_item->getUUID(),new_wearable)); + return true; + } + return false; +} + +BOOL LLAgentWearables::needsReplacement(EWearableType wearableType, S32 remove) +{ + return TRUE; + /*if (remove) return TRUE; + + return getWearable(wearableType) ? TRUE : FALSE;*/ +} + +// Assumes existing wearables are not dirty. +void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items, + const LLDynamicArray< LLWearable* >& wearables, + BOOL remove ) +{ + lldebugs << "setWearableOutfit() start" << llendl; + + BOOL wearables_to_remove[WT_COUNT]; + wearables_to_remove[WT_SHAPE] = FALSE; + wearables_to_remove[WT_SKIN] = FALSE; + wearables_to_remove[WT_HAIR] = FALSE; + wearables_to_remove[WT_EYES] = FALSE; +// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.1.3b) | Added: RLVa-0.2.2a + wearables_to_remove[WT_SHIRT] = remove && gRlvWearableLocks.canRemove(WT_SHIRT); + wearables_to_remove[WT_PANTS] = remove && gRlvWearableLocks.canRemove(WT_PANTS); + wearables_to_remove[WT_SHOES] = remove && gRlvWearableLocks.canRemove(WT_SHOES); + wearables_to_remove[WT_SOCKS] = remove && gRlvWearableLocks.canRemove(WT_SOCKS); + wearables_to_remove[WT_JACKET] = remove && gRlvWearableLocks.canRemove(WT_JACKET); + wearables_to_remove[WT_GLOVES] = remove && gRlvWearableLocks.canRemove(WT_GLOVES); + wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) && remove && gRlvWearableLocks.canRemove(WT_UNDERSHIRT); + wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) && remove && gRlvWearableLocks.canRemove(WT_UNDERPANTS); + wearables_to_remove[WT_SKIRT] = remove && gRlvWearableLocks.canRemove(WT_SKIRT); + wearables_to_remove[WT_ALPHA] = remove && gRlvWearableLocks.canRemove(WT_ALPHA); + wearables_to_remove[WT_TATTOO] = remove && gRlvWearableLocks.canRemove(WT_TATTOO); + wearables_to_remove[WT_PHYSICS] = remove && gRlvWearableLocks.canRemove(WT_PHYSICS); +// [/RLVa:KB] + + S32 count = wearables.count(); + llassert( items.count() == count ); + + S32 i; + for( i = 0; i < count; i++ ) + { + LLWearable* new_wearable = wearables[i]; + LLPointer new_item = items[i]; + + llassert(new_wearable); + EWearableType type = new_wearable->getType(); + wearables_to_remove[type] = FALSE; + + LLWearable* old_wearable = mWearableEntry[ type ].mWearable; + if( old_wearable ) + { + const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; + if( (old_wearable->getID() == new_wearable->getID()) && + (old_item_id == new_item->getUUID()) ) + { + lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl; + continue; + } + + gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); + + // Assumes existing wearables are not dirty. + if( old_wearable->isDirty() ) + { + llassert(0); + continue; + } + } + + if (isFirstPhysicsWearable(type, new_item, new_wearable)) + { + return; + } + + mWearableEntry[ type ].mItemID = new_item->getUUID(); + mWearableEntry[ type ].mWearable = new_wearable; + } + + std::vector wearables_being_removed; + + for( i = 0; i < WT_COUNT; i++ ) + { + if( wearables_to_remove[i] ) + { + wearables_being_removed.push_back(mWearableEntry[ i ].mWearable); + mWearableEntry[ i ].mWearable = NULL; + + gInventory.addChangedMask(LLInventoryObserver::LABEL, mWearableEntry[ i ].mItemID); + mWearableEntry[ i ].mItemID.setNull(); + } + } + + gInventory.notifyObservers(); + + queryWearableCache(); + + std::vector::iterator wearable_iter; + + for( wearable_iter = wearables_being_removed.begin(); + wearable_iter != wearables_being_removed.end(); + ++wearable_iter) + { + LLWearable* wearablep = *wearable_iter; + if (wearablep) + { + wearablep->removeFromAvatar( TRUE ); + } + } + + for( i = 0; i < count; i++ ) + { + wearables[i]->writeToAvatar( TRUE ); + } + + // Start rendering & update the server + mWearablesLoaded = TRUE; + sendAgentWearablesUpdate(); + gAgent.sendAgentSetAppearance(); + + lldebugs << "setWearableOutfit() end" << llendl; +} + + +// User has picked "wear on avatar" from a menu. +void LLAgentWearables::setWearableItem( LLInventoryItem* new_item, LLWearable* new_wearable ) +{ + EWearableType type = new_wearable->getType(); + + LLWearable* old_wearable = mWearableEntry[ type ].mWearable; + +// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d) + // Block if: we can't wear on that layer; or we're already wearing something there we can't take off + if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canWear(type)) ) + { + return; + } +// [/RLVa:KB] + + if (isFirstPhysicsWearable(type, new_item, new_wearable)) + { + return; + } + + if( old_wearable ) + { + const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; + if( (old_wearable->getID() == new_wearable->getID()) && + (old_item_id == new_item->getUUID()) ) + { + lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl; + return; + } + + if( old_wearable->isDirty() ) + { + // Bring up modal dialog: Save changes? Yes, No, Cancel + LLSD payload; + payload["item_id"] = new_item->getUUID(); + LLNotifications::instance().add( "WearableSave", LLSD(), payload, boost::bind(LLAgentWearables::onSetWearableDialog, _1, _2, new_wearable)); + return; + } + } + + setWearableFinal( new_item, new_wearable ); +} + +// static +bool LLAgentWearables::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable ) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID()); + if( !new_item ) + { + delete wearable; + return false; + } + + switch( option ) + { + case 0: // "Save" + gAgentWearables.saveWearable( wearable->getType() ); + gAgentWearables.setWearableFinal( new_item, wearable ); + break; + + case 1: // "Don't Save" + gAgentWearables.setWearableFinal( new_item, wearable ); + break; + + case 2: // "Cancel" + break; + + default: + llassert(0); + break; + } + + delete wearable; + return false; +} + +// Called from setWearable() and onSetWearableDialog() to actually set the wearable. +void LLAgentWearables::setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable ) +{ + const EWearableType type = new_wearable->getType(); + + // Replace the old wearable with a new one. + llassert( new_item->getAssetUUID() == new_wearable->getID() ); + LLUUID old_item_id = mWearableEntry[ type ].mItemID; + mWearableEntry[ type ].mItemID = new_item->getUUID(); + mWearableEntry[ type ].mWearable = new_wearable; + + if (old_item_id.notNull()) + { + gInventory.addChangedMask( LLInventoryObserver::LABEL, old_item_id ); + gInventory.notifyObservers(); + } + + //llinfos << "LLVOAvatar::setWearable()" << llendl; + queryWearableCache(); + new_wearable->writeToAvatar( TRUE ); + + // Update the server + sendAgentWearablesUpdate(); + gAgent.sendAgentSetAppearance(); +} + +void LLAgentWearables::queryWearableCache() +{ + if (!mWearablesLoaded) + { + return; + } + + // Look up affected baked textures. + // If they exist: + // disallow updates for affected layersets (until dataserver responds with cache request.) + // If cache miss, turn updates back on and invalidate composite. + // If cache hit, modify baked texture entries. + // + // Cache requests contain list of hashes for each baked texture entry. + // Response is list of valid baked texture assets. (same message) + + gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addS32Fast(_PREHASH_SerialNum, gAgentQueryManager.mWearablesCacheQueryID); + + S32 num_queries = 0; + for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ ) + { + const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index); + LLUUID hash; + for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++) + { + // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num]; + const EWearableType wearable_type = wearable_dict->mWearablesVec[i]; + const LLWearable* wearable = getWearable(wearable_type); + if (wearable) + { + hash ^= wearable->getID(); + } + } + if (hash.notNull()) + { + hash ^= wearable_dict->mHashID; + num_queries++; + // *NOTE: make sure at least one request gets packed + + //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl; + gMessageSystem->nextBlockFast(_PREHASH_WearableData); + gMessageSystem->addUUIDFast(_PREHASH_ID, hash); + gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index); + } + + gAgentQueryManager.mActiveCacheQueries[ baked_index ] = gAgentQueryManager.mWearablesCacheQueryID; + } + //VWR-22113: gAgent.getRegion() can return null if invalid, seen here on logout + if(gAgent.getRegion()) + { + llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; + gMessageSystem->sendReliable(gAgent.getRegion()->getHost()); + gAgentQueryManager.mNumPendingQueries++; + gAgentQueryManager.mWearablesCacheQueryID++; + } +} + +// User has picked "remove from avatar" from a menu. +// static +void LLAgentWearables::userRemoveWearable( void* userdata ) +{ + EWearableType type = (EWearableType)(intptr_t)userdata; + + if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES) ) //&& + //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) + { + gAgentWearables.removeWearable( type ); + } +} + +void LLAgentWearables::userRemoveAllClothes( void* userdata ) +{ + // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty. + if (gAgentCamera.cameraCustomizeAvatar()) + { + gFloaterCustomize->askToSaveIfDirty( LLAgentWearables::userRemoveAllClothesStep2, NULL ); + } + else + { + userRemoveAllClothesStep2( TRUE, NULL ); + } +} + +void LLAgentWearables::userRemoveAllClothesStep2( BOOL proceed, void* userdata ) +{ + if( proceed ) + { + gAgentWearables.removeWearable( WT_SHIRT ); + gAgentWearables.removeWearable( WT_PANTS ); + gAgentWearables.removeWearable( WT_SHOES ); + gAgentWearables.removeWearable( WT_SOCKS ); + gAgentWearables.removeWearable( WT_JACKET ); + gAgentWearables.removeWearable( WT_GLOVES ); + gAgentWearables.removeWearable( WT_UNDERSHIRT ); + gAgentWearables.removeWearable( WT_UNDERPANTS ); + gAgentWearables.removeWearable( WT_SKIRT ); + gAgentWearables.removeWearable( WT_ALPHA ); + gAgentWearables.removeWearable( WT_TATTOO ); + gAgentWearables.removeWearable( WT_PHYSICS ); + } +} + +// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to +// get attachments into desired state with minimal number of adds/removes. +//void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array) +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a +void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly) +// [/SL:KB] +{ + // Possible cases: + // already wearing but not in request set -> take off. + // already wearing and in request set -> leave alone. + // not wearing and in request set -> put on. + + LLVOAvatar* pAvatar = gAgent.getAvatarObject(); + if (!pAvatar) return; + + std::set requested_item_ids; + std::set current_item_ids; + for (S32 i=0; igetLinkedUUID()); + + // Build up list of objects to be removed and items currently attached. + llvo_vec_t objects_to_remove; + for (LLVOAvatar::attachment_map_t::iterator iter = pAvatar->mAttachmentPoints.begin(); + iter != pAvatar->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 *objectp = (*attachment_iter); + if (objectp) + { + LLUUID object_item_id = objectp->getAttachmentItemID(); + if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) + { + // Object currently worn, was requested. + // Flag as currently worn so we won't have to add it again. + current_item_ids.insert(object_item_id); + } + else + { + // object currently worn, not requested. + objects_to_remove.push_back(objectp); + } + } + } + } + + LLInventoryModel::item_array_t items_to_add; + for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin(); + it != obj_item_array.end(); + ++it) + { + LLUUID linked_id = (*it).get()->getLinkedUUID(); + if (current_item_ids.find(linked_id) != current_item_ids.end()) + { + // Requested attachment is already worn. + } + else + { + // Requested attachment is not worn yet. + items_to_add.push_back(*it); + } + } + // S32 remove_count = objects_to_remove.size(); + // S32 add_count = items_to_add.size(); + // llinfos << "remove " << remove_count << " add " << add_count << llendl; + + // Remove everything in objects_to_remove +// userRemoveMultipleAttachments(objects_to_remove); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a + if (!fAttachOnly) + { + userRemoveMultipleAttachments(objects_to_remove); + } +// [/SL:KB] + + // Add everything in items_to_add + userAttachMultipleAttachments(items_to_add); +} + +void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove) +{ + if (!gAgent.getAvatarObject()) return; + +// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.1.3b) | Modified: RLVa-1.2.0a + // RELEASE-RLVa: [SL-2.0.0] Check our callers and verify that erasing elements from the passed vector won't break random things + if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) ) + { + llvo_vec_t::iterator itObj = objects_to_remove.begin(); + while (itObj != objects_to_remove.end()) + { + const LLViewerObject* pAttachObj = *itObj; + if (gRlvAttachmentLocks.isLockedAttachment(pAttachObj)) + { + itObj = objects_to_remove.erase(itObj); + + // Fall-back code: re-add the attachment if it got removed from COF somehow (compensates for possible bugs elsewhere) + LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items; + LLLinkedItemIDMatches f(pAttachObj->getAttachmentItemID()); + gInventory.collectDescendentsIf(LLCOFMgr::instance().getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH, f); + RLV_ASSERT( 0 != items.count() ); + if (0 == items.count()) + LLCOFMgr::instance().addAttachment(pAttachObj->getAttachmentItemID()); + } + else + { + ++itObj; + } + } + } +// [/RLVa:KB] + + if (objects_to_remove.empty()) + return; + + gMessageSystem->newMessage("ObjectDetach"); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + for (llvo_vec_t::iterator it = objects_to_remove.begin(); + it != objects_to_remove.end(); + ++it) + { + LLViewerObject *objectp = *it; + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); + } + gMessageSystem->sendReliable(gAgent.getRegionHost()); +} + +void LLAgentWearables::userRemoveAllAttachments( void* userdata ) +{ + LLVOAvatar* avatarp = gAgent.getAvatarObject(); + if(!avatarp) + { + llwarns << "No avatar found." << llendl; + return; + } + + llvo_vec_t objects_to_remove; + + for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); + iter != avatarp->mAttachmentPoints.end();) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + 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) +// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b + if ( (attached_object) && ((!rlv_handler_t::isEnabled()) || (!gRlvAttachmentLocks.isLockedAttachment(attached_object))) ) +// [/RLVa:KB] + { + objects_to_remove.push_back(attached_object); + } + } + } + userRemoveMultipleAttachments(objects_to_remove); +} + +void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array) +{ +// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a + // RELEASE-RLVa: [SL-2.0.0] Check our callers and verify that erasing elements from the passed vector won't break random things + if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) ) + { + // Fall-back code: everything should really already have been pruned before we get this far + for (S32 idxItem = obj_item_array.count() - 1; idxItem >= 0; idxItem--) + { + const LLInventoryItem* pItem = obj_item_array.get(idxItem).get(); + if (!gRlvAttachmentLocks.canAttach(pItem)) + { + obj_item_array.remove(idxItem); + RLV_ASSERT(false); + } + } + } +// [/RLVa:KB] + + // Build a compound message to send all the objects that need to be rezzed. + S32 obj_count = obj_item_array.count(); + + // Limit number of packets to send + const S32 MAX_PACKETS_TO_SEND = 10; + const S32 OBJECTS_PER_PACKET = 4; + const S32 MAX_OBJECTS_TO_SEND = MAX_PACKETS_TO_SEND * OBJECTS_PER_PACKET; + if( obj_count > MAX_OBJECTS_TO_SEND ) + { + obj_count = MAX_OBJECTS_TO_SEND; + } + + // Create an id to keep the parts of the compound message together + LLUUID compound_msg_id; + compound_msg_id.generate(); + LLMessageSystem* msg = gMessageSystem; + + for(S32 i = 0; i < obj_count; ++i) + { + if( 0 == (i % OBJECTS_PER_PACKET) ) + { + // Start a new message chunk + msg->newMessageFast(_PREHASH_RezMultipleAttachmentsFromInv); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_HeaderData); + msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); + msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); + msg->addBOOLFast(_PREHASH_FirstDetachAll, false ); + } + + const LLInventoryItem* item = obj_item_array.get(i).get(); + bool replace = !gHippoGridManager->getConnectedGrid()->supportsInvLinks(); + msg->nextBlockFast(_PREHASH_ObjectData ); + msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID()); + msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); + msg->addU8Fast(_PREHASH_AttachmentPt, replace? 0 : ATTACHMENT_ADD); // Wear at the previous or default attachment point + pack_permissions_slam(msg, item->getFlags(), item->getPermissions()); + msg->addStringFast(_PREHASH_Name, item->getName()); + msg->addStringFast(_PREHASH_Description, item->getDescription()); + + if( (i+1 == obj_count) || ((OBJECTS_PER_PACKET-1) == (i % OBJECTS_PER_PACKET)) ) + { + // End of message chunk + msg->sendReliable( gAgent.getRegion()->getHost() ); + } + } +} diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h new file mode 100644 index 000000000..f9ae285db --- /dev/null +++ b/indra/newview/llagentwearables.h @@ -0,0 +1,351 @@ +/** + * @file llagentwearables.h + * @brief LLAgentWearables class header file + * + * $LicenseInfo:firstyear=2000&license=viewergpl$ + * + * Copyright (c) 2000-2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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_LLAGENTWEARABLES_H +#define LL_LLAGENTWEARABLES_H + +// libraries +#include "llmemory.h" +#include "llui.h" +#include "lluuid.h" +#include "llinventory.h" + +// newview +#include "llinventorymodel.h" +#include "llviewerinventory.h" +#include "llvoavatardefines.h" + +class LLInventoryItem; +class LLVOAvatar; +class LLWearable; +class LLInitialWearablesFetch; +class LLViewerObject; +class LLTexLayerTemplate; + +typedef std::vector llvo_vec_t; + +class LLAgentWearables : public LLInitClass +{ + //-------------------------------------------------------------------- + // Constructors / destructors / Initializers + //-------------------------------------------------------------------- +public: + friend class LLInitialWearablesFetch; + + LLAgentWearables(); + virtual ~LLAgentWearables(); + void setAvatarObject(LLVOAvatar *avatar); + void createStandardWearables(BOOL female); + void cleanup(); + //void dump(); + + // LLInitClass interface + static void initClass(); +protected: + void createStandardWearablesDone(S32 index); + void createStandardWearablesAllDone(); + + //-------------------------------------------------------------------- + // Queries + //-------------------------------------------------------------------- +public: + BOOL isWearingItem(const LLUUID& item_id) const; + BOOL isWearableModifiable(EWearableType type) const; + BOOL isWearableModifiable(const LLUUID& item_id) const; + + BOOL isWearableCopyable(EWearableType type) const; + BOOL areWearablesLoaded() const { return mWearablesLoaded; }; + //void updateWearablesLoaded(); + //void checkWearablesLoaded() const; + //bool canMoveWearable(const LLUUID& item_id, bool closer_to_body); + + // Note: False for shape, skin, eyes, and hair, unless you have MORE than 1. + //bool canWearableBeRemoved(const LLWearable* wearable) const; + + //void animateAllWearableParams(F32 delta, BOOL upload_bake); + + BOOL needsReplacement(EWearableType wearableType, S32 remove); + U32 getWearablePermMask(EWearableType type) const; + + //-------------------------------------------------------------------- + // Accessors + //-------------------------------------------------------------------- +public: + const LLUUID& getWearableItemID(EWearableType type ) const; + //const LLUUID getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const; + const LLWearable* getWearableFromItemID(const LLUUID& item_id) const; + LLWearable* getWearableFromItemID(const LLUUID& item_id); + //LLWearable* getWearableFromAssetID(const LLUUID& asset_id); + LLInventoryItem* getWearableInventoryItem(EWearableType type); + static BOOL selfHasWearable( void* userdata ); // userdata is EWearableType + LLWearable* getWearable( const EWearableType type ); + const LLWearable* getWearable( const EWearableType type ) const; + //const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const; + //LLWearable* getTopWearable(const LLWearableType::EType type); + //LLWearable* getBottomWearable(const LLWearableType::EType type); + //U32 getWearableCount(const LLWearableType::EType type) const; + //U32 getWearableCount(const U32 tex_index) const; + + + static EWearableType getTEWearableType( S32 te ); + static LLUUID getDefaultTEImageID( S32 te ); + + void copyWearableToInventory( EWearableType type ); + + static const U32 MAX_CLOTHING_PER_TYPE = 5; + + + //-------------------------------------------------------------------- + // Setters + //-------------------------------------------------------------------- + +private: + // Low-level data structure setter - public access is via setWearableItem, etc. + //void setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable); + //U32 pushWearable(const LLWearableType::EType type, LLWearable *wearable); + //void wearableUpdated(LLWearable *wearable); + //void popWearable(LLWearable *wearable); + //void popWearable(const LLWearableType::EType type, U32 index); + +public: + void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable); + void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove); + void setWearableName(const LLUUID& item_id, const std::string& new_name); + //void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index); + //U32 getWearableIndex(LLWearable *wearable); + +protected: + void setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable ); + static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable); + + void addWearableToAgentInventory(LLPointer cb, + LLWearable* wearable, + const LLUUID& category_id = LLUUID::null, + BOOL notify = TRUE); + + /** + * @brief Only public because of addWearableToAgentInventoryCallback. + * + * NOTE: Do not call this method unless you are the inventory callback. + * NOTE: This can suffer from race conditions when working on the + * same values for index. + * @param index The index in mWearableEntry. + * @param item_id The inventory item id of the new wearable to wear. + * @param wearable The actual wearable data. + */ + void addWearabletoAgentInventoryDone( + S32 index, + const LLUUID& item_id, + LLWearable* wearable); + + void recoverMissingWearable(EWearableType type); + void recoverMissingWearableDone(); + + //-------------------------------------------------------------------- + // Editing/moving wearables + //-------------------------------------------------------------------- + +public: + //static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null); + //static void editWearable(const LLUUID& item_id); + //bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body); + + //void requestEditingWearable(const LLUUID& item_id); + //void editWearableIfRequested(const LLUUID& item_id); + +private: + //LLUUID mItemToEdit; + + //-------------------------------------------------------------------- + // Removing wearables + //-------------------------------------------------------------------- +public: + void removeWearable( EWearableType type ); +private: + void removeWearableFinal( EWearableType type ); +protected: + static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response); + static void userRemoveAllClothesStep2(BOOL proceed, void* userdata ); // userdata is NULL + + //-------------------------------------------------------------------- + // Server Communication + //-------------------------------------------------------------------- +public: + // Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant) + static void processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data); + //LLUUID computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index, + // BOOL generate_valid_hash = TRUE); + +protected: + void sendAgentWearablesUpdate(); + void sendAgentWearablesRequest(); + void queryWearableCache(); + //void updateServer(); + static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata); + + //-------------------------------------------------------------------- + // Outfits + //-------------------------------------------------------------------- +public: + + // Should only be called if we *know* we've never done so before, since users may + // not want the Library outfits to stay in their quick outfit selector and can delete them. + //void populateMyOutfitsFolder(); + void makeNewOutfit( + const std::string& new_folder_name, + const LLDynamicArray& wearables_to_include, + const LLDynamicArray& attachments_to_include, + BOOL rename_clothing); +private: + + void makeNewOutfitDone(S32 index); + + //-------------------------------------------------------------------- + // Save Wearables + //-------------------------------------------------------------------- +public: + void saveWearableAs( EWearableType type, const std::string& new_name, BOOL save_in_lost_and_found ); + void saveWearable( EWearableType type, BOOL send_update = TRUE ); + + void saveAllWearables(); + void revertWearable( EWearableType type ); + void revertAllWearables(); + + //-------------------------------------------------------------------- + // Static UI hooks + //-------------------------------------------------------------------- +public: + static void userRemoveWearable( void* userdata ); // userdata is EWearableType + static void userRemoveAllClothes( void* userdata ); // userdata is NULL +// static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array); +// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a + // Not the best way to go about this but other attempts changed far too much LL code to be a viable solution + static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false); +// [/SL:KB] + static void userRemoveAllAttachments( void* userdata); // userdata is NULLy); + static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array); + static void userRemoveAllAttachments(); + static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array); + + BOOL itemUpdatePending(const LLUUID& item_id) const; + U32 itemUpdatePendingCount() const; + + //-------------------------------------------------------------------- + // Signals + //-------------------------------------------------------------------- +public: + /*typedef boost::function loading_started_callback_t; + typedef boost::signals2::signal loading_started_signal_t; + boost::signals2::connection addLoadingStartedCallback(loading_started_callback_t cb); + + typedef boost::function loaded_callback_t; + typedef boost::signals2::signal loaded_signal_t; + boost::signals2::connection addLoadedCallback(loaded_callback_t cb); + + void notifyLoadingStarted(); + void notifyLoadingFinished();*/ + +private: + + //-------------------------------------------------------------------- + // Member variables + //-------------------------------------------------------------------- + struct LLWearableEntry + { + LLWearableEntry() : mItemID( LLUUID::null ), mWearable( NULL ) {} + + LLUUID mItemID; // ID of the inventory item in the agent's inventory. + LLWearable* mWearable; + }; + LLWearableEntry mWearableEntry[ WT_COUNT ]; + BOOL mWearablesLoaded; + + //-------------------------------------------------------------------------------- + // Support classes + //-------------------------------------------------------------------------------- +private: + class createStandardWearablesAllDoneCallback : public LLRefCount + { + protected: + ~createStandardWearablesAllDoneCallback(); + }; + class sendAgentWearablesUpdateCallback : public LLRefCount + { + protected: + ~sendAgentWearablesUpdateCallback(); + }; + + class addWearableToAgentInventoryCallback : public LLInventoryCallback + { + public: + enum { + CALL_NONE = 0, + CALL_UPDATE = 1, + CALL_RECOVERDONE = 2, + CALL_CREATESTANDARDDONE = 4, + CALL_MAKENEWOUTFITDONE = 8 + } EType; + + /** + * @brief Construct a callback for dealing with the wearables. + * + * Would like to pass the agent in here, but we can't safely + * count on it being around later. Just use gAgent directly. + * @param cb callback to execute on completion (??? unused ???) + * @param index Index for the wearable in the agent + * @param wearable The wearable data. + * @param todo Bitmask of actions to take on completion. + */ + addWearableToAgentInventoryCallback( + LLPointer cb, + S32 index, + LLWearable* wearable, + U32 todo = CALL_NONE); + virtual void fire(const LLUUID& inv_item); + + private: + S32 mIndex; + LLWearable* mWearable; + U32 mTodo; + LLPointer mCB; + }; + +}; // LLAgentWearables + +extern LLAgentWearables gAgentWearables; + +//-------------------------------------------------------------------- +// Types +//-------------------------------------------------------------------- + +#endif // LL_AGENTWEARABLES_H diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 28debb275..891b08ecb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -48,6 +48,8 @@ #include "llviewertexturelist.h" #include "llgroupmgr.h" #include "llagent.h" +#include "llagentcamera.h" +#include "llagentwearables.h" #include "llwindow.h" #include "llviewerstats.h" #include "llmd5.h" @@ -441,7 +443,7 @@ static void settings_to_globals() gFrameStats.setTrackStats(gSavedSettings.getBOOL("StatsSessionTrackFrameStats")); gAgentPilot.mNumRuns = gSavedSettings.getS32("StatsNumRuns"); gAgentPilot.mQuitAfterRuns = gSavedSettings.getBOOL("StatsQuitAfterRuns"); - gAgent.mHideGroupTitle = gSavedSettings.getBOOL("RenderHideGroupTitle"); + gAgent.setHideGroupTitle(gSavedSettings.getBOOL("RenderHideGroupTitle")); gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK"); @@ -2454,9 +2456,9 @@ void LLAppViewer::cleanupSavedSettings() gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips); // Some things are cached in LLAgent. - if (gAgent.mInitialized) + if (gAgentCamera.isInitialized()) { - gSavedSettings.setF32("RenderFarClip", gAgent.mDrawDistance); + gSavedSettings.setF32("RenderFarClip", gAgentCamera.mDrawDistance); } } @@ -3387,10 +3389,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(); @@ -3831,7 +3833,7 @@ void LLAppViewer::idle() LLViewerJoystick::getInstance()->moveObjects(); } - gAgent.updateCamera(); + gAgentCamera.updateCamera(); } // update media focus @@ -4234,6 +4236,8 @@ void LLAppViewer::disconnectViewer() // close inventory interface, close all windows LLInventoryView::cleanup(); + gAgentWearables.cleanup(); + gAgentCamera.cleanup(); // Also writes cached agent settings to gSavedSettings gAgent.cleanup(); diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp index 9f43f3e3f..996e9b8f5 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" @@ -166,7 +166,7 @@ void LLAudioSourceVO::update() if (mObjectp->isHUDAttachment()) { - mPositionGlobal = gAgent.getCameraPositionGlobal(); + mPositionGlobal = gAgentCamera.getCameraPositionGlobal(); } else { diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index aea63301e..2febd9769 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -42,6 +42,7 @@ #include "llstring.h" #include "llagent.h" +#include "llanimationstates.h" #include "llbbox.h" #include "llbutton.h" #include "llcheckboxctrl.h" diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 91fe00c54..ac058cb2b 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -32,6 +32,7 @@ #include "llregionflags.h" #include "llfloaterreporter.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewerregion.h" #include "lltracker.h" #include "llviewerstats.h" @@ -1060,7 +1061,7 @@ void LLFloaterAvatarList::focusOnCurrent() { removeFocusFromAll(); entry->setFocus(TRUE); - gAgent.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT); + gAgentCamera.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT); return; } } @@ -1100,7 +1101,7 @@ void LLFloaterAvatarList::focusOnPrev(BOOL marked_only) removeFocusFromAll(); prev->setFocus(TRUE); mFocusedAvatar = prev->getID(); - gAgent.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT); + gAgentCamera.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT); } } @@ -1145,7 +1146,7 @@ void LLFloaterAvatarList::focusOnNext(BOOL marked_only) removeFocusFromAll(); next->setFocus(TRUE); mFocusedAvatar = next->getID(); - gAgent.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT); + gAgentCamera.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT); } } @@ -1155,10 +1156,10 @@ void LLFloaterAvatarList::lookAtAvatar(LLUUID &uuid) LLViewerObject* voavatar = gObjectList.findObject(uuid); if(voavatar && voavatar->isAvatar()) { - gAgent.setFocusOnAvatar(FALSE, FALSE); - gAgent.changeCameraToThirdPerson(); - gAgent.setFocusGlobal(voavatar->getPositionGlobal(),uuid); - gAgent.setCameraPosAndFocusGlobal(voavatar->getPositionGlobal() + gAgentCamera.setFocusOnAvatar(FALSE, FALSE); + gAgentCamera.changeCameraToThirdPerson(); + gAgentCamera.setFocusGlobal(voavatar->getPositionGlobal(),uuid); + gAgentCamera.setCameraPosAndFocusGlobal(voavatar->getPositionGlobal() + LLVector3d(3.5,1.35,0.75) * voavatar->getRotation(), voavatar->getPositionGlobal(), uuid ); diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 8288c581c..2c74ca209 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -1158,7 +1158,7 @@ void LLFloaterBuyLandUI::refreshUI() if (mIsForGroup) { LLStringUtil::format_map_t string_args; - string_args["[GROUP]"] = std::string(gAgent.mGroupName); + string_args["[GROUP]"] = std::string(gAgent.getGroupName()); message += getString("insufficient_land_credits", string_args); diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 7a4e5147f..18826f961 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -38,6 +38,7 @@ #include "lluictrlfactory.h" // Viewer includes +#include "llagentcamera.h" #include "lljoystickbutton.h" #include "llviewercontrol.h" diff --git a/indra/newview/llfloatercustomize.cpp b/indra/newview/llfloatercustomize.cpp index a7b31fa44..5d75a0cd0 100644 --- a/indra/newview/llfloatercustomize.cpp +++ b/indra/newview/llfloatercustomize.cpp @@ -41,6 +41,7 @@ #include "llmorphview.h" #include "llfloatertools.h" #include "llagent.h" +#include "llagentwearables.h" #include "lltoolmorph.h" #include "llvoavatar.h" #include "llradiogroup.h" @@ -587,7 +588,7 @@ void LLPanelEditWearable::setSubpart( ESubpart subpart ) LLVOAvatar* avatar = gAgent.getAvatarObject(); ESex avatar_sex = avatar->getSex(); LLViewerInventoryItem* item; - item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem(mType); + item = (LLViewerInventoryItem*)gAgentWearables.getWearableInventoryItem(mType); U32 perm_mask = 0x0; BOOL is_complete = FALSE; bool can_export = false; @@ -653,27 +654,27 @@ void LLPanelEditWearable::onBtnTakeOff( void* userdata ) { LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - LLWearable* wearable = gAgent.getWearable( self->mType ); + LLWearable* wearable = gAgentWearables.getWearable( self->mType ); if( !wearable ) { return; } - gAgent.removeWearable( self->mType ); + gAgentWearables.removeWearable( self->mType ); } // static void LLPanelEditWearable::onBtnSave( void* userdata ) { LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - gAgent.saveWearable( self->mType ); + gAgentWearables.saveWearable( self->mType ); } // static void LLPanelEditWearable::onBtnSaveAs( void* userdata ) { LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - LLWearable* wearable = gAgent.getWearable( self->getType() ); + LLWearable* wearable = gAgentWearables.getWearable( self->getType() ); if( wearable ) { LLWearableSaveAsDialog* save_as_dialog = new LLWearableSaveAsDialog( wearable->getName(), onSaveAsCommit, self ); @@ -689,7 +690,7 @@ void LLPanelEditWearable::onSaveAsCommit( LLWearableSaveAsDialog* save_as_dialog LLVOAvatar* avatar = gAgent.getAvatarObject(); if( avatar ) { - gAgent.saveWearableAs( self->getType(), save_as_dialog->getItemName(), FALSE ); + gAgentWearables.saveWearableAs( self->getType(), save_as_dialog->getItemName(), FALSE ); } } @@ -698,7 +699,7 @@ void LLPanelEditWearable::onSaveAsCommit( LLWearableSaveAsDialog* save_as_dialog void LLPanelEditWearable::onBtnRevert( void* userdata ) { LLPanelEditWearable* self = (LLPanelEditWearable*) userdata; - gAgent.revertWearable( self->mType ); + gAgentWearables.revertWearable( self->mType ); } // static @@ -737,7 +738,7 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const bool LLPanelEditWearable::textureIsInvisible(ETextureIndex te) { - if (gAgent.getWearable(mType)) + if (gAgentWearables.getWearable(mType)) { LLVOAvatar *avatar = gAgent.getAvatarObject(); if (avatar) @@ -873,7 +874,7 @@ void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::str LLVOAvatar* avatar = gAgent.getAvatarObject(); if (avatar) { - LLWearable* wearable = gAgent.getWearable(mType); + LLWearable* wearable = gAgentWearables.getWearable(mType); if (wearable && mType == WT_ALPHA) { const LLTextureEntry* current_te = avatar->getTE(te); @@ -903,7 +904,7 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata ) image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR); } self->mTextureList[ctrl->getName()] = te; - if (gAgent.getWearable(self->mType)) + if (gAgentWearables.getWearable(self->mType)) { avatar->setLocTexTE(te, image, TRUE); avatar->wearableUpdated(self->mType, FALSE); @@ -955,14 +956,14 @@ void LLPanelEditWearable::draw() return; } - LLWearable* wearable = gAgent.getWearable( mType ); + LLWearable* wearable = gAgentWearables.getWearable( mType ); BOOL has_wearable = (wearable != NULL ); BOOL is_dirty = isDirty(); BOOL is_modifiable = FALSE; BOOL is_copyable = FALSE; BOOL is_complete = FALSE; LLViewerInventoryItem* item; - item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem(mType); + item = (LLViewerInventoryItem*)gAgentWearables.getWearableInventoryItem(mType); if(item) { const LLPermissions& perm = item->getPermissions(); @@ -1038,7 +1039,7 @@ void LLPanelEditWearable::draw() childSetTextArg("title_loading", "[DESC]", std::string(LLWearable::typeToTypeLabel( mType ))); std::string path; - const LLUUID& item_id = gAgent.getWearableItem( wearable->getType() ); + const LLUUID& item_id = gAgentWearables.getWearableItemID( wearable->getType() ); gInventory.appendPath(item_id, path); childSetVisible("path", TRUE); childSetTextArg("path", "[PATH]", path); @@ -1051,7 +1052,7 @@ void LLPanelEditWearable::draw() childSetTextArg("title", "[DESC]", wearable->getName() ); std::string path; - const LLUUID& item_id = gAgent.getWearableItem( wearable->getType() ); + const LLUUID& item_id = gAgentWearables.getWearableItemID( wearable->getType() ); gInventory.appendPath(item_id, path); childSetVisible("path", TRUE); childSetTextArg("path", "[PATH]", path); @@ -1198,7 +1199,7 @@ void LLPanelEditWearable::setVisible(BOOL visible) BOOL LLPanelEditWearable::isDirty() const { - LLWearable* wearable = gAgent.getWearable( mType ); + LLWearable* wearable = gAgentWearables.getWearable( mType ); if( !wearable ) { return FALSE; @@ -1223,7 +1224,7 @@ void LLPanelEditWearable::onCommitSexChange( LLUICtrl*, void* userdata ) return; } - if( !gAgent.isWearableModifiable(self->mType)) + if( !gAgentWearables.isWearableModifiable(self->mType)) { return; } @@ -1933,10 +1934,10 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) for( S32 i=0; i < WT_COUNT; i++ ) { is_modifiable = FALSE; - LLWearable* old_wearable = gAgent.getWearable((EWearableType)i); + LLWearable* old_wearable = gAgentWearables.getWearable((EWearableType)i); if( old_wearable ) { - item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem((EWearableType)i); + item = (LLViewerInventoryItem*)gAgentWearables.getWearableInventoryItem((EWearableType)i); if(item) { const LLPermissions& perm = item->getPermissions(); @@ -1957,10 +1958,10 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) for( S32 i=0; i < WT_COUNT; i++ ) { is_modifiable = FALSE; - LLWearable* old_wearable = gAgent.getWearable((EWearableType)i); + LLWearable* old_wearable = gAgentWearables.getWearable((EWearableType)i); if( old_wearable ) { - item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem((EWearableType)i); + item = (LLViewerInventoryItem*)gAgentWearables.getWearableInventoryItem((EWearableType)i); if(item) { const LLPermissions& perm = item->getPermissions(); @@ -1985,7 +1986,7 @@ void LLFloaterCustomize::onBtnExport_continued(AIFilePicker* filepicker) void LLFloaterCustomize::onBtnOk( void* userdata ) { LLFloaterCustomize* floater = (LLFloaterCustomize*) userdata; - gAgent.saveAllWearables(); + gAgentWearables.saveAllWearables(); LLVOAvatar* avatar = gAgent.getAvatarObject(); if ( avatar ) @@ -2012,7 +2013,7 @@ void LLFloaterCustomize::onBtnMakeOutfit( void* userdata ) for( S32 i = 0; i < WT_COUNT; i++ ) { - BOOL enabled = (gAgent.getWearable( (EWearableType) i ) != NULL); + BOOL enabled = (gAgentWearables.getWearable( (EWearableType) i ) != NULL); BOOL selected = (enabled && (WT_SHIRT <= i) && (i < WT_COUNT)); // only select clothing by default if (gAgent.isTeen() && !edit_wearable_for_teens((EWearableType)i)) @@ -2039,7 +2040,7 @@ void LLFloaterCustomize::onMakeOutfitCommit( LLMakeOutfitDialog* dialog, void* u dialog->getIncludedItems( wearables_to_include, attachments_to_include ); - gAgent.makeNewOutfit( dialog->getFolderName(), wearables_to_include, attachments_to_include, dialog->getRenameClothing() ); + gAgentWearables.makeNewOutfit( dialog->getFolderName(), wearables_to_include, attachments_to_include, dialog->getRenameClothing() ); } } @@ -2745,13 +2746,13 @@ bool LLFloaterCustomize::onSaveDialog(const LLSD& notification, const LLSD& resp switch( option ) { case 0: // "Save" - gAgent.saveWearable( cur ); + gAgentWearables.saveWearable( cur ); proceed = TRUE; break; case 1: // "Don't Save" { - gAgent.revertWearable( cur ); + gAgentWearables.revertWearable( cur ); proceed = TRUE; } break; @@ -2787,7 +2788,7 @@ void LLFloaterCustomize::fetchInventory() LLUUID item_id; for(S32 type = (S32)WT_SHAPE; type < (S32)WT_COUNT; ++type) { - item_id = gAgent.getWearableItem((EWearableType)type); + item_id = gAgentWearables.getWearableItemID((EWearableType)type); if(item_id.notNull()) { ids.push_back(item_id); @@ -2813,7 +2814,7 @@ void LLFloaterCustomize::updateInventoryUI() panel = mWearablePanelList[i]; if(panel) { - item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem(panel->getType()); + item = (LLViewerInventoryItem*)gAgentWearables.getWearableInventoryItem(panel->getType()); } if(item) { @@ -2848,7 +2849,7 @@ void LLFloaterCustomize::updateScrollingPanelUI() LLPanelEditWearable* panel = mWearablePanelList[sCurrentWearableType]; if(panel) { - LLViewerInventoryItem* item = (LLViewerInventoryItem*)gAgent.getWearableInventoryItem(panel->getType()); + LLViewerInventoryItem* item = (LLViewerInventoryItem*)gAgentWearables.getWearableInventoryItem(panel->getType()); if(item) { U32 perm_mask = item->getPermissions().getMaskOwner(); diff --git a/indra/newview/llfloaterexploresounds.cpp b/indra/newview/llfloaterexploresounds.cpp index 7fdcfda10..6ada9c155 100644 --- a/indra/newview/llfloaterexploresounds.cpp +++ b/indra/newview/llfloaterexploresounds.cpp @@ -6,6 +6,7 @@ #include "lluictrlfactory.h" #include "llscrolllistctrl.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewerwindow.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -335,9 +336,9 @@ void LLFloaterExploreSounds::handle_look_at(void* user_data) cam += pos_global; cam += LLVector3d(0.f, 0.f, 3.0f); - gAgent.setFocusOnAvatar(FALSE, FALSE); - gAgent.setCameraPosAndFocusGlobal(cam, pos_global, item.mSourceID); - gAgent.setCameraAnimating(FALSE); + gAgentCamera.setFocusOnAvatar(FALSE, FALSE); + gAgentCamera.setCameraPosAndFocusGlobal(cam, pos_global, item.mSourceID); + gAgentCamera.setCameraAnimating(FALSE); } // static diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 2e5a4a7f5..23da0629b 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -96,6 +96,7 @@ void LLFloaterHardwareSettings::refreshEnabledState() childSetMinValue("GrapicsCardTextureMemory", min_tex_mem); childSetMaxValue("GrapicsCardTextureMemory", max_tex_mem); + mLastVBOState = LLVertexBuffer::sEnableVBOs; if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || !gGLManager.mHasVertexBufferObject) { @@ -158,6 +159,13 @@ void LLFloaterHardwareSettings::onClose(bool app_quitting) } } +// virtual +void LLFloaterHardwareSettings::draw() +{ + if(mLastVBOState == !LLVertexBuffer::sEnableVBOs) + refreshEnabledState(); + LLFloater::draw(); +} //============================================================================ diff --git a/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h index bdf3fb13b..0d78d67a2 100644 --- a/indra/newview/llfloaterhardwaresettings.h +++ b/indra/newview/llfloaterhardwaresettings.h @@ -75,6 +75,9 @@ public: /// sync up menu with parameters void refresh(); + /// Draw the panel... + void draw(); + /// Apply the changed values. void apply(); @@ -87,6 +90,7 @@ public: protected: LLSliderCtrl* mCtrlVideoCardMem; + //Retained values for cancel/reset BOOL mUseVBO; BOOL mUseFBO; BOOL mUseAniso; @@ -96,6 +100,7 @@ protected: F32 mFogRatio; BOOL mProbeHardwareOnStartup; + bool mLastVBOState; //track changes to LLVertexBuffer::sEnableVBOs every frame. Bleh. private: // one instance on the inside static LLFloaterHardwareSettings* sHardwareSettings; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index efb6057bb..84715f192 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -44,6 +44,7 @@ #include "lluserauth.h" #include "llagent.h" +#include "llagentaccess.h" #include "llavatarconstants.h" //For new Online check - HgB #include "llfloateravatarpicker.h" #include "llbutton.h" diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index f4ad40f52..6c81d6e4a 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -34,7 +34,8 @@ #include "llfloatermap.h" -#include "llagent.h" + +#include "llagentcamera.h" #include "llcolorscheme.h" #include "llviewercontrol.h" #include "lldraghandle.h" @@ -111,7 +112,7 @@ BOOL LLFloaterMap::canClose() void LLFloaterMap::draw() { // 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 2f9539fd1..e5c8a18a6 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -44,6 +44,7 @@ #include "llsdserialize.h" #include "llagent.h" +#include "llagentcamera.h" #include "llcallbacklist.h" #include "llcriticaldamp.h" #include "llfloaterperms.h" @@ -893,7 +894,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->setThumbnailImageSize(); } - previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal(); + previewp->mPosTakenGlobal = gAgentCamera.getCameraPositionGlobal(); previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame } } diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index c0e91f3c5..d0e41a96a 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -39,6 +39,7 @@ #include "llgl.h" #include "llagent.h" +#include "llagentcamera.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" @@ -596,7 +597,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) (mask == (MASK_PAN | MASK_ALT)) ); // 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()); @@ -830,7 +831,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(); @@ -843,7 +844,7 @@ void LLFloaterTools::onClose(bool app_quitting) mParcelSelection = NULL; mObjectSelection = NULL; - if (!gAgent.cameraMouselook()) + if (!gAgentCamera.cameraMouselook()) { // Switch back to basic toolset LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); @@ -923,7 +924,7 @@ void commit_slider_zoom(LLUICtrl *ctrl, void*) { // 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 5cc4ef529..716573d12 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 "llviewerwindow.h" #include "llbutton.h" #include "llcallingcard.h" @@ -602,14 +603,14 @@ void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id ) void LLFloaterWorldMap::trackEvent(const LLItemInfo &event_info) { mTrackedStatus = LLTracker::TRACKING_LOCATION; - LLTracker::trackLocation(event_info.mPosGlobal, event_info.mName, event_info.mToolTip, LLTracker::LOCATION_EVENT); + LLTracker::trackLocation(event_info.getGlobalPosition(), event_info.getName(), event_info.getToolTip(), LLTracker::LOCATION_EVENT); setDefaultBtn("Teleport"); } void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item) { mTrackedStatus = LLTracker::TRACKING_LOCATION; - LLTracker::trackLocation(item.mPosGlobal, item.mName, item.mToolTip, LLTracker::LOCATION_ITEM); + LLTracker::trackLocation(item.getGlobalPosition(), item.getName(), item.getToolTip(), LLTracker::LOCATION_ITEM); setDefaultBtn("Teleport"); } @@ -628,7 +629,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) setDefaultBtn(""); return; } - if (sim_info->mAccess == SIM_ACCESS_DOWN) + if (sim_info->isDown()) { // Down sim. Show the blue circle of death! LLWorldMap::getInstance()->mIsTrackingUnknownLocation = TRUE; @@ -839,8 +840,11 @@ void LLFloaterWorldMap::friendsChanged() if(avatar_id.notNull()) { LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo"); - if(!iface || !iface->setCurrentByID(avatar_id) || - !t.getBuddyInfo(avatar_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) || gAgent.isGodlike()) + const LLRelationship* buddy_info = t.getBuddyInfo(avatar_id); + if(!iface || + !iface->setCurrentByID(avatar_id) || + (buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) || + gAgent.isGodlike()) { LLTracker::stopTracking(NULL); } @@ -855,11 +859,10 @@ void LLFloaterWorldMap::buildAvatarIDList() // Delete all but the "None" entry S32 list_size = list->getItemCount(); - while (list_size > 1) + if (list_size > 1) { - list->selectNthItem(1); + list->selectItemRange(1, -1); list->operateOnSelection(LLCtrlListInterface::OP_DELETE); - --list_size; } LLSD default_column; @@ -1357,12 +1360,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()->mIsTrackingUnknownLocation) { - pos_global = LLWorldMap::getInstance()->mUnknownLocation - gAgent.getCameraPositionGlobal();; + pos_global = LLWorldMap::getInstance()->mUnknownLocation - gAgentCamera.getCameraPositionGlobal();; } else { @@ -1564,10 +1567,10 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) BOOL match_found = FALSE; S32 num_results = 0; std::map::const_iterator it; - for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) + for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) { LLSimInfo* info = (*it).second; - std::string sim_name = info->mName; + std::string sim_name = info->getName(); std::string sim_name_lower = sim_name; LLStringUtil::toLower(sim_name_lower); @@ -1652,15 +1655,13 @@ void LLFloaterWorldMap::onCommitSearchResult(LLUICtrl*, void* userdata) LLStringUtil::toLower(sim_name); std::map::const_iterator it; - for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) + for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) { - LLSimInfo* info = (*it).second; - std::string info_sim_name = info->mName; - LLStringUtil::toLower(info_sim_name); - - if (sim_name == info_sim_name) + LLSimInfo* info = it->second; + + if (info->isName(sim_name)) { - LLVector3d pos_global = from_region_handle( info->mHandle ); + LLVector3d pos_global = info->getGlobalOrigin(); F64 local_x = self->childGetValue("spin x"); F64 local_y = self->childGetValue("spin y"); F64 local_z = self->childGetValue("spin z"); diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index e9593ffde..496e321db 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -67,6 +67,7 @@ // We need these because some of the code below relies on things like // gAgent root folder. Remove them once the abstraction leak is fixed. #include "llagent.h" +#include "llagentwearables.h" #include "llappviewer.h" ///---------------------------------------------------------------------------- @@ -4688,7 +4689,7 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item) mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos; BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE) && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) - && (mFilterWorn == false || gAgent.isWearingItem(item_id) || + && (mFilterWorn == false || gAgentWearables.isWearingItem(item_id) || (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isWearingAttachment(item_id))) && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate); diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 89b4be753..092fdc6b5 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -73,106 +73,6 @@ #include "rlvhandler.h" // [/RLVa:KB] -BOOL LLAgent::setLookAt(ELookAtType target_type, LLViewerObject *object, LLVector3 position) -{ - if(gSavedSettings.getBOOL("PrivateLookAt")) - { - if(!mLookAt || mLookAt->isDead()) - return FALSE; - position.clearVec(); - return mLookAt->setLookAt(LOOKAT_TARGET_NONE, mAvatarObject, 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()) || gSavedSettings.getBOOL("DisablePointAtAndBeam")) - { - 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(); - } -} extern BOOL gDebugSelect; @@ -1156,3 +1056,4 @@ void LLViewerObjectList::renderObjectBeacons() } + \ No newline at end of file diff --git a/indra/newview/llhoverview.cpp b/indra/newview/llhoverview.cpp index b51a2c589..1821b7da7 100644 --- a/indra/newview/llhoverview.cpp +++ b/indra/newview/llhoverview.cpp @@ -47,6 +47,7 @@ // Viewer includes #include "llagent.h" +#include "llagentcamera.h" #include "llavatarnamecache.h" #include "llcachename.h" #include "llviewercontrol.h" @@ -120,7 +121,7 @@ void LLHoverView::updateHover(LLTool* current_tool) BOOL picking_tool = ( current_tool == LLToolPie::getInstance() || current_tool == LLToolSelectLand::getInstance() ); - mUseHover = !gAgent.cameraMouselook() + mUseHover = !gAgentCamera.cameraMouselook() && picking_tool && !mTyping; if (mUseHover) @@ -735,11 +736,11 @@ void LLHoverView::draw() LLViewerObject *hover_object = getLastHoverObject(); if (hover_object->isAvatar()) { - gAgent.setLookAt(LOOKAT_TARGET_HOVER, getLastHoverObject(), LLVector3::zero); + gAgentCamera.setLookAt(LOOKAT_TARGET_HOVER, getLastHoverObject(), LLVector3::zero); } else { - gAgent.setLookAt(LOOKAT_TARGET_HOVER, getLastHoverObject(), mHoverOffset); + gAgentCamera.setLookAt(LOOKAT_TARGET_HOVER, getLastHoverObject(), mHoverOffset); } } } diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index 5c7d1a7f9..e25efdf42 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" @@ -320,7 +321,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; } @@ -535,7 +536,7 @@ void LLHUDEffectLookAt::render() gGL.popMatrix(); // const std::string text = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->getFullname(); - LLVector3 offset = gAgent.getCameraPositionAgent() - target; + LLVector3 offset = gAgentCamera.getCameraPositionAgent() - target; offset.normalize(); LLVector3 shadow_offset = offset * 0.49f; offset *= 0.5f; @@ -679,7 +680,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 c566bd768..9c9508c74 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/llhudobject.cpp b/indra/newview/llhudobject.cpp index 4c0827239..b2ba698bc 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -43,7 +43,7 @@ #include "llhudeffectbeam.h" #include "llhudeffecttrail.h" #include "llhudeffectlookat.h" - +#include "llhudeffectpointat.h" #include "llvoicevisualizer.h" #include "llagent.h" diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 31743deb3..ff542ee0e 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -44,6 +44,7 @@ #include "lluictrlfactory.h" #include "llagent.h" +#include "llagentcamera.h" #include "llcallingcard.h" #include "llchat.h" #include "llresmgr.h" @@ -489,10 +490,10 @@ void LLIMMgr::toggle(void*) BOOL old_state = gIMMgr->getFloaterOpen(); // If we're in mouselook and we triggered the Talk View, we want to talk. - if( gAgent.cameraMouselook() && old_state ) + if( gAgentCamera.cameraMouselook() && old_state ) { return_to_mouselook = TRUE; - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); return; } @@ -501,18 +502,18 @@ void LLIMMgr::toggle(void*) if (new_state) { // ...making visible - if ( gAgent.cameraMouselook() ) + if ( gAgentCamera.cameraMouselook() ) { return_to_mouselook = TRUE; - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); } } else { // ...hiding - if ( gAgent.cameraThirdPerson() && return_to_mouselook ) + if ( gAgentCamera.cameraThirdPerson() && return_to_mouselook ) { - gAgent.changeCameraToMouselook(); + gAgentCamera.changeCameraToMouselook(); } return_to_mouselook = FALSE; } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index d728d4274..aa9038fa6 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -41,6 +41,8 @@ #include "cofmgr.h" #include "llagent.h" +#include "llagentwearables.h" +#include "llagentcamera.h" #include "llcallingcard.h" #include "llcheckboxctrl.h" // for radio buttons #include "llradiogroup.h" @@ -1505,7 +1507,7 @@ BOOL LLFolderBridge::isItemRemovable() if ((item->getType() == LLAssetType::AT_CLOTHING || item->getType() == LLAssetType::AT_BODYPART) && !item->getIsLinkType()) { - if( gAgent.isWearingItem( item->getUUID() ) ) + if( gAgentWearables.isWearingItem( item->getUUID() ) ) { return FALSE; } @@ -1659,7 +1661,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if( (item->getType() == LLAssetType::AT_CLOTHING) || (item->getType() == LLAssetType::AT_BODYPART) ) { - if( gAgent.isWearingItem( item->getUUID() ) ) + if( gAgentWearables.isWearingItem( item->getUUID() ) ) { is_movable = FALSE; // It's generally movable, but not into the trash! break; @@ -2844,7 +2846,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item, { case LLAssetType::AT_CLOTHING: case LLAssetType::AT_BODYPART: - is_movable = !gAgent.isWearingItem(inv_item->getUUID()); + is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID()); break; case LLAssetType::AT_OBJECT: @@ -3931,23 +3933,23 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model LLViewerParcelMgr::getInstance()->deselectLand(); LLSelectMgr::getInstance()->deselectAll(); - if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit()) + if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit()) { if (objectp->isHUDAttachment() || !gSavedSettings.getBOOL("EditCameraMovement")) { // 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); // zoom in on object center instead of where we clicked, as we need to see the manipulator handles - gAgent.setFocusGlobal(objectp->getPositionGlobal(), objectp->getID()); - gAgent.cameraZoomIn(0.666f); - gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD ); + gAgentCamera.setFocusGlobal(objectp->getPositionGlobal(), objectp->getID()); + gAgentCamera.cameraZoomIn(0.666f); + gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD ); gViewerWindow->moveCursorToCenter(); } } @@ -4817,7 +4819,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata ) obj_items.insert(obj_items.end(), obj_items_new.begin(), obj_items_new.end()); // [/RLVa:KB] - LLAgent::userUpdateAttachments(obj_items); + LLAgentWearables::userUpdateAttachments(obj_items); } else { @@ -4925,7 +4927,7 @@ void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, B if(wearables.count() > 0) { - gAgent.setWearableOutfit(items, wearables, !append); + gAgentWearables.setWearableOutfit(items, wearables, !append); gInventory.notifyObservers(); } @@ -5011,9 +5013,9 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) { for(i = 0; i < wearable_count; ++i) { -// if( gAgent.isWearingItem (item_array.get(i)->getUUID()) ) +// if( gAgentWearables.isWearingItem (item_array.get(i)->getUUID()) ) // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.1.3b) | Modified: RLVa-0.2.2a - LLWearable* pWearable = gAgent.getWearableFromWearableItem(item_array.get(i)->getLinkedUUID()); + LLWearable* pWearable = gAgentWearables.getWearableFromItemID(item_array.get(i)->getLinkedUUID()); if ( (pWearable) && ( (!rlv_handler_t::isEnabled()) || (gRlvWearableLocks.canRemove(pWearable->getType())) ) ) // [/RLVa:KB] { @@ -5058,9 +5060,9 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) BOOL LLWearableBridge::renameItem(const std::string& new_name) { - if( gAgent.isWearingItem( mUUID ) ) + if( gAgentWearables.isWearingItem( mUUID ) ) { - gAgent.setWearableName( mUUID, new_name ); + gAgentWearables.setWearableName( mUUID, new_name ); } return LLItemBridge::renameItem(new_name); } @@ -5078,7 +5080,7 @@ BOOL LLWearableBridge::isItemRemovable() return TRUE; } // - //if(gAgent.isWearingItem(mUUID)) return FALSE; + //if(gAgentWearables.isWearingItem(mUUID)) return FALSE; // return LLInvFVBridge::isItemRemovable(); } @@ -5087,7 +5089,7 @@ LLFontGL::StyleFlags LLWearableBridge::getLabelStyle() const { U8 font = LLFontGL::NORMAL; - if (gAgent.isWearingItem(mUUID)) + if (gAgentWearables.isWearingItem(mUUID)) { font |= LLFontGL::BOLD; } @@ -5103,7 +5105,7 @@ LLFontGL::StyleFlags LLWearableBridge::getLabelStyle() const std::string LLWearableBridge::getLabelSuffix() const { - if( gAgent.isWearingItem( mUUID ) ) + if( gAgentWearables.isWearingItem( mUUID ) ) { return LLItemBridge::getLabelSuffix() + " (worn)"; } @@ -5132,7 +5134,7 @@ void LLWearableBridge::performAction(LLFolderView* folder, LLInventoryModel* mod } else if ("take_off" == action) { - if(gAgent.isWearingItem(mUUID)) + if(gAgentWearables.isWearingItem(mUUID)) { LLViewerInventoryItem* item = getItem(); if (item) @@ -5156,7 +5158,7 @@ void LLWearableBridge::openItem() } else if(isAgentInventory()) { - if (gAgent.isWearingItem(mUUID)) + if (gAgentWearables.isWearingItem(mUUID)) { performAction(NULL, NULL, "take_off"); } @@ -5269,7 +5271,7 @@ BOOL LLWearableBridge::canWearOnAvatar(void* user_data) LLViewerInventoryItem* item = (LLViewerInventoryItem*)self->getItem(); if(!item || !item->isComplete()) return FALSE; } - return (!gAgent.isWearingItem(self->mUUID)); + return (!gAgentWearables.isWearingItem(self->mUUID)); } // Called from menus @@ -5285,7 +5287,7 @@ void LLWearableBridge::wearOnAvatar() { // Don't wear anything until initial wearables are loaded, can // destroy clothing items. - if (!gAgent.areWearablesLoaded()) + if (!gAgentWearables.areWearablesLoaded()) { LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded"); return; @@ -5339,7 +5341,7 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda // item->updateAssetOnServer(); // wearable = new_wearable; // } - gAgent.setWearable(item, wearable); + gAgentWearables.setWearableItem(item, wearable); gInventory.notifyObservers(); //self->getFolderItem()->refreshFromRoot(); } @@ -5358,7 +5360,7 @@ BOOL LLWearableBridge::canEditOnAvatar(void* user_data) LLWearableBridge* self = (LLWearableBridge*)user_data; if(!self) return FALSE; - return (gAgent.isWearingItem(self->mUUID)); + return (gAgentWearables.isWearingItem(self->mUUID)); } // static @@ -5374,16 +5376,16 @@ void LLWearableBridge::onEditOnAvatar(void* user_data) void LLWearableBridge::editOnAvatar() { LLUUID linked_id = gInventory.getLinkedItemID(mUUID); - LLWearable* wearable = gAgent.getWearableFromWearableItem(linked_id); + LLWearable* wearable = gAgentWearables.getWearableFromItemID(linked_id); if( wearable ) { // Set the tab to the right wearable. LLFloaterCustomize::setCurrentWearableType( wearable->getType() ); - if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() ) + if( CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() ) { // Start Avatar Customization - gAgent.changeCameraToCustomizeAvatar(); + gAgentCamera.changeCameraToCustomizeAvatar(); } } } @@ -5394,7 +5396,7 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data) LLWearableBridge* self = (LLWearableBridge*)user_data; if( self && (LLAssetType::AT_BODYPART != self->mAssetType) ) { - return gAgent.isWearingItem( self->mUUID ); + return gAgentWearables.isWearingItem( self->mUUID ); } return FALSE; } @@ -5404,7 +5406,7 @@ void LLWearableBridge::onRemoveFromAvatar(void* user_data) { LLWearableBridge* self = (LLWearableBridge*)user_data; if(!self) return; - if(gAgent.isWearingItem(self->mUUID)) + if(gAgentWearables.isWearingItem(self->mUUID)) { LLViewerInventoryItem* item = self->getItem(); if (item) @@ -5426,14 +5428,14 @@ void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable, const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID); if(wearable) { - if (gAgent.isWearingItem(item_id)) + if (gAgentWearables.isWearingItem(item_id)) { EWearableType type = wearable->getType(); if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES) ) //&& //!((!gAgent.isTeen()) && ( type==WT_UNDERPANTS || type==WT_UNDERSHIRT )) ) { - gAgent.removeWearable( type ); + gAgentWearables.removeWearable( type ); } } } diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index e65b75e01..bba3cf30d 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3577,7 +3577,7 @@ bool LLInventoryCollectFunctor::itemTransferCommonlyAllowed(LLInventoryItem* ite case LLAssetType::AT_BODYPART: case LLAssetType::AT_CLOTHING: - if(!gAgent.isWearingItem(item->getUUID())) + if(!gAgentWearables.isWearingItem(item->getUUID())) { allowed = true; } diff --git a/indra/newview/llinventoryview.cpp b/indra/newview/llinventoryview.cpp index 1d89872c9..a085c9b6a 100644 --- a/indra/newview/llinventoryview.cpp +++ b/indra/newview/llinventoryview.cpp @@ -40,6 +40,7 @@ #include "message.h" #include "llagent.h" +#include "llagentcamera.h" #include "llcallingcard.h" #include "llcheckboxctrl.h" // for radio buttons #include "llradiogroup.h" @@ -850,7 +851,7 @@ LLInventoryView* LLInventoryView::showAgentInventory(BOOL take_keyboard_focus) iv = NULL; } #endif - if(!iv && !gAgent.cameraMouselook()) + if(!iv && !gAgentCamera.cameraMouselook()) { // create one. iv = new LLInventoryView(std::string("Inventory"), @@ -1985,7 +1986,7 @@ public: virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) { - return !gAgent.isWearingItem(item->getUUID()); + return !gAgentWearables.isWearingItem(item->getUUID()); } }; diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 6eab2343a..4cfc2eaac 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 "llviewertexturelist.h" #include "llviewerwindow.h" #include "llmoveview.h" @@ -570,25 +571,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()); } } @@ -700,25 +701,25 @@ void LLJoystickCameraTrack::onHeldDown() if (dx > mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanRightKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setPanRightKey(getOrbitRate()); } else if (dx < -mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanLeftKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setPanLeftKey(getOrbitRate()); } // over/under rotation if (dy > mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanUpKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setPanUpKey(getOrbitRate()); } else if (dy < -mVertSlopNear) { - gAgent.unlockView(); - gAgent.setPanDownKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setPanDownKey(getOrbitRate()); } } @@ -769,26 +770,26 @@ void LLJoystickCameraZoom::onHeldDown() if (dy > mVertSlopFar) { // Zoom in fast - gAgent.unlockView(); - gAgent.setOrbitInKey(FAST_RATE); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey(FAST_RATE); } else if (dy > mVertSlopNear) { // Zoom in slow - gAgent.unlockView(); - gAgent.setOrbitInKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey(getOrbitRate()); } else if (dy < -mVertSlopFar) { // Zoom out fast - gAgent.unlockView(); - gAgent.setOrbitOutKey(FAST_RATE); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitOutKey(FAST_RATE); } else if (dy < -mVertSlopNear) { // Zoom out slow - gAgent.unlockView(); - gAgent.setOrbitOutKey(getOrbitRate()); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitOutKey(getOrbitRate()); } } diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 775c916c3..f1ef63b67 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" @@ -231,7 +232,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 { @@ -316,8 +317,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->getWindowWidth() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom; - F32 mouse_y = ((F32)y / gViewerWindow->getWindowHeight() - 0.5f) / gAgent.mHUDCurZoom; + F32 mouse_x = ((F32)x / gViewerWindow->getWindowWidth() - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; + F32 mouse_y = ((F32)y / gViewerWindow->getWindowHeight() - 0.5f) / gAgentCamera.mHUDCurZoom; LLVector3 origin_agent = gAgent.getPosAgentFromGlobal(origin); LLVector3 mouse_pos = LLVector3(0.f, -mouse_x, mouse_y); @@ -355,15 +356,15 @@ BOOL LLManip::nearestPointOnLineFromMouse( S32 x, S32 y, const LLVector3& b1, co if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { - F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgent.mHUDCurZoom; - F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.mHUDCurZoom; + F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) * LLViewerCamera::getInstance()->getAspect() / gAgentCamera.mHUDCurZoom; + F32 mouse_y = (((F32)y / gViewerWindow->getWindowHeight()) - 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; @@ -575,7 +576,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; @@ -633,7 +634,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 6a89fd0fd..8db7d7cb6 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" @@ -137,7 +138,7 @@ void LLManipRotate::render() glPushMatrix(); if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { - F32 zoom = gAgent.mHUDCurZoom; + F32 zoom = gAgentCamera.mHUDCurZoom; glScalef(zoom, zoom, zoom); } @@ -689,7 +690,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(); } @@ -729,7 +730,7 @@ void LLManipRotate::renderSnapGuides() } else { - cam_at_axis = center - gAgent.getCameraPositionAgent(); + cam_at_axis = center - gAgentCamera.getCameraPositionAgent(); cam_at_axis.normVec(); } @@ -1097,18 +1098,18 @@ 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; - mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgent.mHUDCurZoom * gViewerWindow->getWindowWidth()), - (S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgent.mHUDCurZoom * gViewerWindow->getWindowHeight())); + mCenterScreen.set((S32)((0.5f - mRotationCenter.mdV[VY]) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWindowWidth()), + (S32)((mRotationCenter.mdV[VZ] + 0.5f) / gAgentCamera.mHUDCurZoom * gViewerWindow->getWindowHeight())); visible = TRUE; } else @@ -1116,7 +1117,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(); @@ -1162,7 +1163,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); @@ -1330,7 +1331,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(); } @@ -1380,7 +1381,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(); } @@ -1427,7 +1428,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(); } @@ -1624,15 +1625,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->getWindowWidth()) - 0.5f) / gAgent.mHUDCurZoom; - F32 mouse_y = ((((F32)y) / gViewerWindow->getWindowHeight()) - 0.5f) / gAgent.mHUDCurZoom; + F32 mouse_x = (((F32)x / gViewerWindow->getWindowWidth()) - 0.5f) / gAgentCamera.mHUDCurZoom; + F32 mouse_y = ((((F32)y) / gViewerWindow->getWindowHeight()) - 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 5da5ba0aa..bec6a49f4 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); } @@ -225,11 +226,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 { - F32 range_squared = dist_vec_squared(gAgent.getCameraPositionAgent(), center_agent); + F32 range_squared = dist_vec_squared(gAgentCamera.getCameraPositionAgent(), center_agent); F32 range_from_agent_squared = dist_vec_squared(gAgent.getPositionAgent(), center_agent); // Don't draw manip if object too far away @@ -436,7 +437,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); @@ -632,7 +633,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) + @@ -822,7 +823,7 @@ void LLManipScale::drag( S32 x, S32 y ) } LLSelectMgr::getInstance()->updateSelectionCenter(); - gAgent.clearFocusObject(); + gAgentCamera.clearFocusObject(); } // Scale around the @@ -1361,7 +1362,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 @@ -1374,7 +1375,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 fdf8c2166..ed88881f8 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" @@ -427,12 +428,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 > gViewerWindow->getWindowWidth() - ROTATE_H_MARGIN) { - gAgent.cameraOrbitAround(-rotate_angle); + gAgentCamera.cameraOrbitAround(-rotate_angle); rotated = TRUE; } } @@ -786,7 +787,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; @@ -827,7 +828,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); @@ -1065,7 +1066,7 @@ void LLManipTranslate::render() gGL.pushMatrix(); if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { - F32 zoom = gAgent.mHUDCurZoom; + F32 zoom = gAgentCamera.mHUDCurZoom; glScalef(zoom, zoom, zoom); } { @@ -1230,7 +1231,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 @@ -1813,11 +1814,11 @@ void LLManipTranslate::renderTranslationHandles() if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD) { mArrowLengthMeters = mAxisArrowLength / gViewerWindow->getWindowHeight(); - 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); @@ -2099,7 +2100,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; @@ -2141,7 +2142,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/llmapresponders.cpp b/indra/newview/llmapresponders.cpp index 60758a396..ae0090e42 100644 --- a/indra/newview/llmapresponders.cpp +++ b/indra/newview/llmapresponders.cpp @@ -154,25 +154,17 @@ void LLMapLayerResponder::result(const LLSD& result) // llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl; - LLSimInfo* siminfo = new LLSimInfo(); - LLWorldMap::sim_info_map_t::iterator iter = LLWorldMap::getInstance()->mSimInfoMap.find(handle); - if (iter != LLWorldMap::getInstance()->mSimInfoMap.end()) + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if (siminfo == NULL) { - LLSimInfo* oldinfo = iter->second; - for (S32 image=0; imagemMapImageID[image] = oldinfo->mMapImageID[image]; - } - delete oldinfo; + siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); } - LLWorldMap::getInstance()->mSimInfoMap[handle] = siminfo; - siminfo->mHandle = handle; - siminfo->mName.assign( name ); - siminfo->mAccess = access; /*Flawfinder: ignore*/ - siminfo->mRegionFlags = region_flags; - siminfo->mWaterHeight = (F32) water_height; - siminfo->mMapImageID[agent_flags] = image_id; + siminfo->setName( name ); + siminfo->setAccess( access ); /*Flawfinder: ignore*/ + siminfo->setRegionFlags( region_flags ); + siminfo->setWaterHeight( (F32) water_height ); + siminfo->setMapImageID( image_id, agent_flags ); if (use_web_map_tiles) { siminfo->mCurrentImage = LLWorldMap::loadObjectsTile((U32)x_regions, (U32)y_regions); @@ -199,7 +191,7 @@ void LLMapLayerResponder::result(const LLSD& result) LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) { - if (siminfo->mAccess == SIM_ACCESS_DOWN) + if (siminfo->isDown()) { // We were tracking this location, but it doesn't exist LLWorldMap::getInstance()->mInvalidLocation = true; diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index d7b022219..87867ddfd 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -42,6 +42,7 @@ #include "message.h" #include "llagent.h" +#include "llagentcamera.h" #include "llcallingcard.h" #include "llchatbar.h" #include "llviewercontrol.h" @@ -84,7 +85,7 @@ void handle_pay_by_id(const LLUUID& agent_id) void handle_mouselook(void*) { - gAgent.changeCameraToMouselook(); + gAgentCamera.changeCameraToMouselook(); } diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index 18fd20d12..3f45eda67 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" @@ -93,7 +94,7 @@ void LLMorphView::initialize() LLVOAvatar *avatarp = gAgent.getAvatarObject(); if (!avatarp || avatarp->isDead()) { - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); return; } @@ -189,7 +190,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 a18004787..59996ca64 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -39,6 +39,7 @@ // Viewer includes #include "llagent.h" +#include "llagentcamera.h" #include "llviewercontrol.h" #include "llbutton.h" #include "llviewerwindow.h" diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index b266df2cb..164d3a950 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -44,6 +44,7 @@ #include "llfloateravatarlist.h" #include "llagent.h" +#include "llagentcamera.h" #include "llavatarnamecache.h" #include "llcallingcard.h" #include "llcolorscheme.h" @@ -104,7 +105,7 @@ LLNetMap::LLNetMap(const std::string& name) : mPixelsPerMeter = mScale / LLWorld::getInstance()->getRegionWidthInMeters(); mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); - mObjectImageCenterGlobal = gAgent.getCameraPositionGlobal(); + mObjectImageCenterGlobal = gAgentCamera.getCameraPositionGlobal(); // Register event listeners for popup menu (new LLScaleMap())->registerListener(this, "MiniMap.ZoomLevel"); @@ -251,7 +252,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; @@ -308,7 +309,7 @@ void LLNetMap::draw() mUpdateNow = FALSE; // Locate the centre of the object layer, accounting for panning - LLVector3 new_center = globalPosToView(gAgent.getCameraPositionGlobal(), rotate_map); + LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal(), rotate_map); new_center.mV[0] -= mCurPanX; new_center.mV[1] -= mCurPanY; new_center.mV[2] = 0.f; @@ -327,7 +328,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; @@ -535,7 +536,7 @@ void LLNetMap::reshape(S32 width, S32 height, BOOL called_from_parent) LLVector3 LLNetMap::globalPosToView(const LLVector3d& global_pos, BOOL rotated) { - 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 @@ -601,7 +602,7 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y, BOOL rotated ) LLVector3d pos_global; pos_global.setVec( pos_local ); - pos_global += gAgent.getCameraPositionGlobal(); + pos_global += gAgentCamera.getCameraPositionGlobal(); return pos_global; } diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index eeed29673..db981c415 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -42,6 +42,7 @@ #include "importtracker.h" #include "llrender.h" #include "llagent.h" +#include "llagentcamera.h" #include "llbutton.h" #include "llchatbar.h" #include "llfocusmgr.h" @@ -371,7 +372,7 @@ void LLOverlayBar::refresh() // turn off the whole bar in mouselook static BOOL last_mouselook = FALSE; - BOOL in_mouselook = gAgent.cameraMouselook(); + BOOL in_mouselook = gAgentCamera.cameraMouselook(); if(last_mouselook != in_mouselook) { @@ -442,7 +443,7 @@ void LLOverlayBar::onClickResetView(void* data) //static void LLOverlayBar::onClickMouselook(void*) { - gAgent.changeCameraToMouselook(); + gAgentCamera.changeCameraToMouselook(); } //static diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 9a3add526..c3c27fc9b 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -1717,14 +1717,7 @@ void LLPanelAvatar::resetGroupList() row["id"] = id ; row["columns"][0]["value"] = group_string; row["columns"][0]["font"] = "SANSSERIF_SMALL"; - if (group_data.mListInProfile) - { - row["columns"][0]["color"] = gColors.getColor("DefaultListText").getValue(); - } - else - { - row["columns"][0]["color"] = gColors.getColor("ScrollUnselectedColor").getValue(); - } + row["columns"][0]["font-style"] = group_data.mListInProfile ? "BOLD" : "NORMAL"; row["columns"][0]["width"] = 0; group_list->addElement(row); } diff --git a/indra/newview/llpaneldirplaces.cpp b/indra/newview/llpaneldirplaces.cpp index ccffc0259..305d2e2ac 100644 --- a/indra/newview/llpaneldirplaces.cpp +++ b/indra/newview/llpaneldirplaces.cpp @@ -44,6 +44,7 @@ // viewer project includes #include "llagent.h" +#include "llagentaccess.h" #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcombobox.h" diff --git a/indra/newview/llpanelmediahud.cpp b/indra/newview/llpanelmediahud.cpp index 39c4b637b..4b33ae6f2 100644 --- a/indra/newview/llpanelmediahud.cpp +++ b/indra/newview/llpanelmediahud.cpp @@ -34,6 +34,7 @@ //LLPanelMediaHUD #include "llagent.h" +#include "llagentcamera.h" #include "llparcel.h" #include "llpanel.h" #include "llselectmgr.h" @@ -467,7 +468,7 @@ void LLPanelMediaHUD::onClickClose(void* user_data) LLPanelMediaHUD* this_panel = static_cast (user_data); if(this_panel->mCurrentZoom != ZOOM_NONE) { - // gAgent.setFocusOnAvatar(TRUE, ANIMATE); + // gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE); this_panel->mCurrentZoom = ZOOM_NONE; } this_panel->setVisible(FALSE); @@ -587,7 +588,7 @@ void LLPanelMediaHUD::nextZoomLevel() { case ZOOM_NONE: { - gAgent.setFocusOnAvatar(TRUE, ANIMATE); + gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE); break; } case ZOOM_MEDIUM: @@ -597,7 +598,7 @@ void LLPanelMediaHUD::nextZoomLevel() } default: { - gAgent.setFocusOnAvatar(TRUE, ANIMATE); + gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE); break; } } diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 6d014a23d..2d4dc3246 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -73,9 +73,11 @@ #include "llvovolume.h" #include "llworld.h" #include "pipeline.h" +#include "llviewershadermgr.h" #include "lldrawpool.h" #include "lluictrlfactory.h" +#include "lltexturectrl.h" // "Features" Tab @@ -111,12 +113,28 @@ BOOL LLPanelVolume::postBuild() LightColorSwatch->setOnSelectCallback(onLightSelectColor); childSetCommitCallback("colorswatch",onCommitLight,this); } + + LLTextureCtrl* LightTexPicker = getChild("light texture control"); + if (LightTexPicker) + { + LightTexPicker->setOnCancelCallback(onLightCancelTexture); + LightTexPicker->setOnSelectCallback(onLightSelectTexture); + childSetCommitCallback("light texture control", onCommitLight, this); + } + childSetCommitCallback("Light Intensity",onCommitLight,this); childSetValidate("Light Intensity",precommitValidate); childSetCommitCallback("Light Radius",onCommitLight,this); childSetValidate("Light Radius",precommitValidate); childSetCommitCallback("Light Falloff",onCommitLight,this); childSetValidate("Light Falloff",precommitValidate); + + childSetCommitCallback("Light FOV", onCommitLight, this); + childSetValidate("Light FOV", precommitValidate); + childSetCommitCallback("Light Focus", onCommitLight, this); + childSetValidate("Light Focus", precommitValidate); + childSetCommitCallback("Light Ambiance", onCommitLight, this); + childSetValidate("Light Ambiance", precommitValidate); } // Start with everyone disabled @@ -221,14 +239,32 @@ void LLPanelVolume::getState( ) LightColorSwatch->setValid( TRUE ); LightColorSwatch->set(volobjp->getLightBaseColor()); } + + childSetEnabled("label texture",true); + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(TRUE); + LightTextureCtrl->setValid(TRUE); + LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); + } childSetEnabled("Light Intensity",true); childSetEnabled("Light Radius",true); childSetEnabled("Light Falloff",true); + childSetEnabled("Light FOV",true); + childSetEnabled("Light Focus",true); + childSetEnabled("Light Ambiance",true); + childSetValue("Light Intensity",volobjp->getLightIntensity()); childSetValue("Light Radius",volobjp->getLightRadius()); childSetValue("Light Falloff",volobjp->getLightFalloff()); + LLVector3 params = volobjp->getSpotLightParams(); + childSetValue("Light FOV",params.mV[0]); + childSetValue("Light Focus",params.mV[1]); + childSetValue("Light Ambiance",params.mV[2]); + mLightSavedColor = volobjp->getLightColor(); } else @@ -244,9 +280,20 @@ void LLPanelVolume::getState( ) LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } + childSetEnabled("label texture",false); + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(FALSE); + LightTextureCtrl->setValid(FALSE); + } childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); + + childSetEnabled("Light FOV",false); + childSetEnabled("Light Focus",false); + childSetEnabled("Light Ambiance",false); } // Flexible properties @@ -336,6 +383,14 @@ void LLPanelVolume::refresh() { mRootObject = NULL; } + + BOOL visible = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 0 ? TRUE : FALSE; + + childSetVisible("label texture", visible); + childSetVisible("Light FOV", visible); + childSetVisible("Light Focus", visible); + childSetVisible("Light Ambiance", visible); + childSetVisible("light texture control", visible); } @@ -355,13 +410,20 @@ void LLPanelVolume::clearCtrls() childSetVisible("edit_object",false); childSetEnabled("Light Checkbox Ctrl",false); childSetEnabled("label color",false); - childSetEnabled("label color",false); LLColorSwatchCtrl* LightColorSwatch = getChild("colorswatch"); if(LightColorSwatch) { LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } + childSetEnabled("label texture",false); + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if(LightTextureCtrl) + { + LightTextureCtrl->setEnabled( FALSE ); + LightTextureCtrl->setValid( FALSE ); + } + childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); @@ -438,6 +500,16 @@ void LLPanelVolume::onLightCancelColor(LLUICtrl* ctrl, void* userdata) onLightSelectColor(NULL, userdata); } +void LLPanelVolume::onLightCancelTexture(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setImageAssetID(self->mLightSavedTexture); + } +} + void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*) userdata; @@ -459,6 +531,25 @@ void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) } } +void LLPanelVolume::onLightSelectTexture(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLVOVolume *volobjp = (LLVOVolume*)self->mObject.get(); + if (!volobjp || (volobjp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + + + LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); + volobjp->setLightTextureID(id); + self->mLightSavedTexture = id; + } +} + // static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { @@ -474,12 +565,45 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) volobjp->setLightIntensity((F32)self->childGetValue("Light Intensity").asReal()); volobjp->setLightRadius((F32)self->childGetValue("Light Radius").asReal()); volobjp->setLightFalloff((F32)self->childGetValue("Light Falloff").asReal()); + LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); volobjp->setLightColor(LLColor3(clr)); } + + LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); + if (id.notNull()) + { + if (!volobjp->isLightSpotlight()) + { //this commit is making this a spot light, set UI to default params + volobjp->setLightTextureID(id); + LLVector3 spot_params = volobjp->getSpotLightParams(); + self->getChild("Light FOV")->setValue(spot_params.mV[0]); + self->getChild("Light Focus")->setValue(spot_params.mV[1]); + self->getChild("Light Ambiance")->setValue(spot_params.mV[2]); + } + else + { //modifying existing params + LLVector3 spot_params; + spot_params.mV[0] = (F32) self->getChild("Light FOV")->getValue().asReal(); + spot_params.mV[1] = (F32) self->getChild("Light Focus")->getValue().asReal(); + spot_params.mV[2] = (F32) self->getChild("Light Ambiance")->getValue().asReal(); + volobjp->setSpotLightParams(spot_params); + } + } + else if (volobjp->isLightSpotlight()) + { //no longer a spot light + volobjp->setLightTextureID(id); + //self->getChildView("Light FOV")->setEnabled(FALSE); + //self->getChildView("Light Focus")->setEnabled(FALSE); + //self->getChildView("Light Ambiance")->setEnabled(FALSE); + } + } } // static diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index 841880b14..bd9803b90 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -74,6 +74,8 @@ public: static void onLightCancelColor(LLUICtrl* ctrl, void* userdata); static void onLightSelectColor(LLUICtrl* ctrl, void* userdata); + static void onLightCancelTexture(LLUICtrl* ctrl, void* userdata); + static void onLightSelectTexture(LLUICtrl* ctrl, void* userdata); protected: void getState(); @@ -99,6 +101,7 @@ protected: */ LLColor4 mLightSavedColor; + LLUUID mLightSavedTexture; LLPointer mObject; LLPointer mRootObject; }; diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 1c7a57abc..9656f6e7a 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -46,6 +46,7 @@ // newview #include "llagent.h" // todo: remove +#include "llanimationstates.h" #include "llassetuploadresponders.h" #include "llbutton.h" #include "llcheckboxctrl.h" diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index cf67ca516..06d9a1ae4 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -37,6 +37,7 @@ #include "llinventory.h" #include "llagent.h" +#include "llagentcamera.h" #include "llassetuploadresponders.h" #include "llviewerwindow.h" #include "llbutton.h" @@ -152,7 +153,7 @@ LLPreviewNotecard::LLPreviewNotecard(const std::string& name, editor->setHandleEditKeysDirectly(TRUE); } - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); } LLPreviewNotecard::~LLPreviewNotecard() diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index afe43a353..e08cda791 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -53,6 +53,7 @@ // viewer includes #include "llagent.h" +#include "llagentcamera.h" #include "llviewerwindow.h" #include "lldrawable.h" #include "llfloaterinspect.h" @@ -2973,7 +2974,7 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, } } - 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); @@ -4750,8 +4751,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) { @@ -4772,7 +4773,7 @@ void LLSelectMgr::updateSilhouettes() } func; getSelection()->applyToObjects(&func); - mLastCameraPos = gAgent.getCameraPositionGlobal(); + mLastCameraPos = gAgentCamera.getCameraPositionGlobal(); } std::vector changed_objects; @@ -5039,7 +5040,7 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) LLVOAvatar* avatar = gAgent.getAvatarObject(); 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); @@ -5500,7 +5501,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) F32 silhouette_thickness; if (isAgentAvatarValid() && is_hud_object) { - silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgent.mHUDCurZoom; + silhouette_thickness = LLSelectMgr::sHighlightThickness / gAgentCamera.mHUDCurZoom; } else { @@ -5520,7 +5521,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); @@ -5713,8 +5714,8 @@ void LLSelectMgr::updateSelectionCenter() if (mSelectedObjects->mSelectType != SELECT_TYPE_HUD && isAgentAvatarValid()) { // reset hud ZOOM - gAgent.mHUDTargetZoom = 1.f; - gAgent.mHUDCurZoom = 1.f; + gAgentCamera.mHUDTargetZoom = 1.f; + gAgentCamera.mHUDCurZoom = 1.f; } mShowSelection = FALSE; @@ -5810,26 +5811,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); } } @@ -6021,20 +6022,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 ¤t_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/llstartup.cpp b/indra/newview/llstartup.cpp index 818e82c7f..f6f051fd1 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -86,6 +86,8 @@ #include "v3math.h" #include "llagent.h" +#include "llagentcamera.h" +#include "llagentwearables.h" #include "llagentpilot.h" #include "llfloateravatarlist.h" #include "llfloateravatarpicker.h" @@ -684,6 +686,8 @@ bool idle_startup() if(init) { gAudiop->setMuted(TRUE); + if(gSavedSettings.getBOOL("AllowLargeSounds")) + gAudiop->setAllowLargeSounds(true); } else { @@ -1698,7 +1702,7 @@ bool idle_startup() it = options[0].find("folder_id"); if(it != options[0].end()) { - gAgent.mInventoryRootID.set((*it).second); + gAgent.setInventoryRootID(LLUUID((*it).second)); //gInventory.mock(gAgent.getInventoryRootID()); } } @@ -1902,6 +1906,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 @@ -1933,7 +1938,7 @@ bool idle_startup() // World initialization must be done after above window init // User might have overridden far clip - LLWorld::getInstance()->setLandFarClip( gAgent.mDrawDistance ); + LLWorld::getInstance()->setLandFarClip( gAgentCamera.mDrawDistance ); // Before we create the first region, we need to set the agent's mOriginGlobal // This is necessary because creating objects before this is set will result in a @@ -2144,8 +2149,8 @@ bool idle_startup() gAgent.setPositionAgent(agent_start_position_region); gAgent.resetAxes(agent_start_look_at); - gAgent.stopCameraAnimation(); - gAgent.resetCamera(); + gAgentCamera.stopCameraAnimation(); + gAgentCamera.resetCamera(); // Initialize global class data needed for surfaces (i.e. textures) if (!gNoRender) @@ -2712,15 +2717,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(); } } } @@ -2834,7 +2839,7 @@ bool idle_startup() else { // OK to just get the wearables - if ( gAgent.areWearablesLoaded() ) + if ( gAgentWearables.areWearablesLoaded() ) { // We have our clothing, proceed. //llinfos << "wearables loaded" << llendl; @@ -3517,7 +3522,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) // LLFloaterRate::processReputationIndividualReply); msg->setHandlerFuncFast(_PREHASH_AgentWearablesUpdate, - LLAgent::processAgentInitialWearablesUpdate ); + LLAgentWearables::processAgentInitialWearablesUpdate ); msg->setHandlerFunc("ScriptControlChange", LLAgent::processScriptControlChange ); @@ -3664,7 +3669,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name, has_name); if (0 == cat_array.count()) { - gAgent.createStandardWearables(gender); + gAgentWearables.createStandardWearables(gender); } else { @@ -3789,6 +3794,11 @@ void LLStartUp::setStartupState( EStartupState state ) void reset_login() { + gAgentWearables.cleanup(); + gAgentCamera.cleanup(); + gAgent.cleanup(); + LLWorld::getInstance()->destroyClass(); + // OGPX : Save URL history file // This needs to be done on login failure because it gets read on *every* login attempt LLURLHistory::saveFile("url_history.xml"); diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 390d4ce50..9d718e88c 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/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index f204bc227..17a1a3ce9 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -34,6 +34,8 @@ #include "imageids.h" #include "llagent.h" +#include "llagentcamera.h" +#include "llagentwearables.h" #include "llcrc.h" #include "lldir.h" #include "llglheaders.h" @@ -81,7 +83,7 @@ LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar, mStartTime = LLFrameTimer::getTotalTime(); // Record starting time for( S32 i = 0; i < WT_COUNT; i++ ) { - LLWearable* wearable = gAgent.getWearable( (EWearableType)i); + LLWearable* wearable = gAgentWearables.getWearable( (EWearableType)i); if( wearable ) { mWearableAssets[i] = wearable->getID(); @@ -189,7 +191,7 @@ void LLTexLayerSetBuffer::cancelUpload() // do we need to upload, and do we have sufficient data to create an uploadable composite? BOOL LLTexLayerSetBuffer::needsUploadNow() const { - BOOL upload = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && (gAgent.mNumPendingQueries == 0); + BOOL upload = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && gAgentQueryManager.hasNoPendingQueries(); return (upload && (LLFrameTimer::getTotalTime() > mUploadAfter)); } @@ -2006,7 +2008,7 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL set_by_user) LLVOAvatar* avatar = mTexLayer->getTexLayerSet()->getAvatar(); if( avatar->getSex() & getSex() ) { - if ( gAgent.cameraCustomizeAvatar() ) + if ( gAgentCamera.cameraCustomizeAvatar() ) { set_by_user = FALSE; } diff --git a/indra/newview/lltexlayerparams.cpp b/indra/newview/lltexlayerparams.cpp new file mode 100644 index 000000000..40f151925 --- /dev/null +++ b/indra/newview/lltexlayerparams.cpp @@ -0,0 +1,575 @@ +/** + * @file lltexlayerparams.cpp + * @brief Texture layer parameters + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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 "lltexlayerparams.h" + +#include "llagentcamera.h" +#include "llimagetga.h" +#include "lltexlayer.h" +#include "llvoavatarself.h" +#include "llwearable.h" +#include "llui.h" + +//----------------------------------------------------------------------------- +// LLTexLayerParam +//----------------------------------------------------------------------------- +LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) : + mTexLayer(layer), + mAvatar(NULL) +{ + if (mTexLayer != NULL) + { + mAvatar = mTexLayer->getTexLayerSet()->getAvatar(); + } + else + { + llerrs << "LLTexLayerParam constructor passed with NULL reference for layer!" << llendl; + } +} + +LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) : + mTexLayer(NULL) +{ + mAvatar = avatar; +} + + +BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar ) +{ + LLViewerVisualParam::setInfo(info); + + if (add_to_avatar) + { + mAvatar->addVisualParam( this); + } + + return TRUE; +} + + +//----------------------------------------------------------------------------- +// LLTexLayerParamAlpha +//----------------------------------------------------------------------------- + +// static +LLTexLayerParamAlpha::param_alpha_ptr_list_t LLTexLayerParamAlpha::sInstances; + +// static +void LLTexLayerParamAlpha::dumpCacheByteCount() +{ + S32 gl_bytes = 0; + getCacheByteCount( &gl_bytes); + llinfos << "Processed Alpha Texture Cache GL:" << (gl_bytes/1024) << "KB" << llendl; +} + +// static +void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes) +{ + *gl_bytes = 0; + + for (param_alpha_ptr_list_t::iterator iter = sInstances.begin(); + iter != sInstances.end(); iter++) + { + LLTexLayerParamAlpha* instance = *iter; + LLViewerTexture* tex = instance->mCachedProcessedTexture; + if (tex) + { + S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents(); + + if (tex->hasGLTexture()) + { + *gl_bytes += bytes; + } + } + } +} + +LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) : + LLTexLayerParam(layer), + mCachedProcessedTexture(NULL), + mNeedsCreateTexture(FALSE), + mStaticImageInvalid(FALSE), + mAvgDistortionVec(1.f, 1.f, 1.f), + mCachedEffectiveWeight(0.f) +{ + sInstances.push_front(this); +} + +LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) : + LLTexLayerParam(avatar), + mCachedProcessedTexture(NULL), + mNeedsCreateTexture(FALSE), + mStaticImageInvalid(FALSE), + mAvgDistortionVec(1.f, 1.f, 1.f), + mCachedEffectiveWeight(0.f) +{ + sInstances.push_front(this); +} + + +LLTexLayerParamAlpha::~LLTexLayerParamAlpha() +{ + deleteCaches(); + sInstances.remove(this); +} + +/*virtual*/ LLViewerVisualParam* LLTexLayerParamAlpha::cloneParam(LLWearable* wearable) const +{ + LLTexLayerParamAlpha *new_param = new LLTexLayerParamAlpha(mTexLayer); + *new_param = *this; + return new_param; +} + +void LLTexLayerParamAlpha::deleteCaches() +{ + mStaticImageTGA = NULL; // deletes image + mCachedProcessedTexture = NULL; + mStaticImageRaw = NULL; + mNeedsCreateTexture = FALSE; +} + +BOOL LLTexLayerParamAlpha::getMultiplyBlend() const +{ + return ((LLTexLayerParamAlphaInfo *)getInfo())->mMultiplyBlend; +} + +void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake) +{ + if (mIsAnimating || mTexLayer == NULL) + { + return; + } + F32 min_weight = getMinWeight(); + F32 max_weight = getMaxWeight(); + F32 new_weight = llclamp(weight, min_weight, max_weight); + U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight); + U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight); + if (cur_u8 != new_u8) + { + mCurWeight = new_weight; + + if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. + { + if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) + { + upload_bake = FALSE; + } + mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); + mTexLayer->invalidateMorphMasks(); + } + } +} + +void LLTexLayerParamAlpha::setAnimationTarget(F32 target_value, BOOL upload_bake) +{ + // do not animate dummy parameters + if (mIsDummy) + { + setWeight(target_value, upload_bake); + return; + } + + mTargetWeight = target_value; + setWeight(target_value, upload_bake); + mIsAnimating = TRUE; + if (mNext) + { + mNext->setAnimationTarget(target_value, upload_bake); + } +} + +void LLTexLayerParamAlpha::animate(F32 delta, BOOL upload_bake) +{ + if (mNext) + { + mNext->animate(delta, upload_bake); + } +} + +BOOL LLTexLayerParamAlpha::getSkip() const +{ + if (!mTexLayer) + { + return TRUE; + } + + const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar(); + + if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight) + { + F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); + if (is_approx_zero(effective_weight)) + { + return TRUE; + } + } + + EWearableType type = (EWearableType)getWearableType(); + if ((type != WT_INVALID) && !avatar->isWearingWearableType(type)) + { + return TRUE; + } + + return FALSE; +} + + +BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height) +{ + BOOL success = TRUE; + + if (!mTexLayer) + { + return success; + } + + F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight(); + BOOL weight_changed = effective_weight != mCachedEffectiveWeight; + if (getSkip()) + { + return success; + } + + LLTexLayerParamAlphaInfo *info = (LLTexLayerParamAlphaInfo *)getInfo(); + gGL.flush(); + if (info->mMultiplyBlend) + { + gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO); // Multiplication: approximates a min() function + } + else + { + gGL.setSceneBlendType(LLRender::BT_ADD); // Addition: approximates a max() function + } + + if (!info->mStaticImageFileName.empty() && !mStaticImageInvalid) + { + if (mStaticImageTGA.isNull()) + { + // Don't load the image file until we actually need it the first time. Like now. + mStaticImageTGA = LLTexLayerStaticImageList::getInstance()->getImageTGA(info->mStaticImageFileName); + // We now have something in one of our caches + LLTexLayerSet::sHasCaches |= mStaticImageTGA.notNull() ? TRUE : FALSE; + + if (mStaticImageTGA.isNull()) + { + llwarns << "Unable to load static file: " << info->mStaticImageFileName << llendl; + mStaticImageInvalid = TRUE; // don't try again. + return FALSE; + } + } + + const S32 image_tga_width = mStaticImageTGA->getWidth(); + const S32 image_tga_height = mStaticImageTGA->getHeight(); + if (!mCachedProcessedTexture || + (mCachedProcessedTexture->getWidth() != image_tga_width) || + (mCachedProcessedTexture->getHeight() != image_tga_height) || + (weight_changed)) + { +// llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl; + mCachedEffectiveWeight = effective_weight; + + if (!mCachedProcessedTexture) + { + mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE); + + // We now have something in one of our caches + LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE; + + mCachedProcessedTexture->setExplicitFormat(GL_ALPHA8, GL_ALPHA); + } + + // Applies domain and effective weight to data as it is decoded. Also resizes the raw image if needed. + mStaticImageRaw = NULL; + mStaticImageRaw = new LLImageRaw; + mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight); + mNeedsCreateTexture = TRUE; + } + + if (mCachedProcessedTexture) + { + { + // Create the GL texture, and then hang onto it for future use. + if (mNeedsCreateTexture) + { + mCachedProcessedTexture->createGLTexture(0, mStaticImageRaw); + mNeedsCreateTexture = FALSE; + gGL.getTexUnit(0)->bind(mCachedProcessedTexture); + mCachedProcessedTexture->setAddressMode(LLTexUnit::TAM_CLAMP); + } + + LLGLSNoAlphaTest gls_no_alpha_test; + gGL.getTexUnit(0)->bind(mCachedProcessedTexture); + gl_rect_2d_simple_tex(width, height); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + stop_glerror(); + } + } + + // Don't keep the cache for other people's avatars + // (It's not really a "cache" in that case, but the logic is the same) + if (!mAvatar->isSelf()) + { + mCachedProcessedTexture = NULL; + } + } + else + { + LLGLDisable no_alpha(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.color4f(0.f, 0.f, 0.f, effective_weight); + gl_rect_2d_simple(width, height); + } + + return success; +} + +//----------------------------------------------------------------------------- +// LLTexLayerParamAlphaInfo +//----------------------------------------------------------------------------- +LLTexLayerParamAlphaInfo::LLTexLayerParamAlphaInfo() : + mMultiplyBlend(FALSE), + mSkipIfZeroWeight(FALSE), + mDomain(0.f) +{ +} + +BOOL LLTexLayerParamAlphaInfo::parseXml(LLXmlTreeNode* node) +{ + llassert(node->hasName("param") && node->getChildByName("param_alpha")); + + if (!LLViewerVisualParamInfo::parseXml(node)) + return FALSE; + + LLXmlTreeNode* param_alpha_node = node->getChildByName("param_alpha"); + if (!param_alpha_node) + { + return FALSE; + } + + static LLStdStringHandle tga_file_string = LLXmlTree::addAttributeString("tga_file"); + if (param_alpha_node->getFastAttributeString(tga_file_string, mStaticImageFileName)) + { + // Don't load the image file until it's actually needed. + } +// else +// { +// llwarns << " element is missing tga_file attribute." << llendl; +// } + + static LLStdStringHandle multiply_blend_string = LLXmlTree::addAttributeString("multiply_blend"); + param_alpha_node->getFastAttributeBOOL(multiply_blend_string, mMultiplyBlend); + + static LLStdStringHandle skip_if_zero_string = LLXmlTree::addAttributeString("skip_if_zero"); + param_alpha_node->getFastAttributeBOOL(skip_if_zero_string, mSkipIfZeroWeight); + + static LLStdStringHandle domain_string = LLXmlTree::addAttributeString("domain"); + param_alpha_node->getFastAttributeF32(domain_string, mDomain); + + return TRUE; +} + + + + +LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) : + LLTexLayerParam(layer), + mAvgDistortionVec(1.f, 1.f, 1.f) +{ +} + +LLTexLayerParamColor::LLTexLayerParamColor(LLVOAvatar *avatar) : + LLTexLayerParam(avatar), + mAvgDistortionVec(1.f, 1.f, 1.f) +{ +} + +LLTexLayerParamColor::~LLTexLayerParamColor() +{ +} + +/*virtual*/ LLViewerVisualParam* LLTexLayerParamColor::cloneParam(LLWearable* wearable) const +{ + LLTexLayerParamColor *new_param = new LLTexLayerParamColor(mTexLayer); + *new_param = *this; + return new_param; +} + +LLColor4 LLTexLayerParamColor::getNetColor() const +{ + const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo(); + + llassert(info->mNumColors >= 1); + + F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight(); + + S32 index_last = info->mNumColors - 1; + F32 scaled_weight = effective_weight * index_last; + S32 index_start = (S32) scaled_weight; + S32 index_end = index_start + 1; + if (index_start == index_last) + { + return info->mColors[index_last]; + } + else + { + F32 weight = scaled_weight - index_start; + const LLColor4 *start = &info->mColors[ index_start ]; + const LLColor4 *end = &info->mColors[ index_end ]; + return LLColor4((1.f - weight) * start->mV[VX] + weight * end->mV[VX], + (1.f - weight) * start->mV[VY] + weight * end->mV[VY], + (1.f - weight) * start->mV[VZ] + weight * end->mV[VZ], + (1.f - weight) * start->mV[VW] + weight * end->mV[VW]); + } +} + +void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake) +{ + if (mIsAnimating) + { + return; + } + + const LLTexLayerParamColorInfo *info = (LLTexLayerParamColorInfo *)getInfo(); + F32 min_weight = getMinWeight(); + F32 max_weight = getMaxWeight(); + F32 new_weight = llclamp(weight, min_weight, max_weight); + U8 cur_u8 = F32_to_U8(mCurWeight, min_weight, max_weight); + U8 new_u8 = F32_to_U8(new_weight, min_weight, max_weight); + if (cur_u8 != new_u8) + { + mCurWeight = new_weight; + + if (info->mNumColors <= 0) + { + // This will happen when we set the default weight the first time. + return; + } + + if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param. + { + onGlobalColorChanged(upload_bake); + if (mTexLayer) + { + mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake); + } + } + +// llinfos << "param " << mName << " = " << new_weight << llendl; + } +} + +void LLTexLayerParamColor::setAnimationTarget(F32 target_value, BOOL upload_bake) +{ + // set value first then set interpolating flag to ignore further updates + mTargetWeight = target_value; + setWeight(target_value, upload_bake); + mIsAnimating = TRUE; + if (mNext) + { + mNext->setAnimationTarget(target_value, upload_bake); + } +} + +void LLTexLayerParamColor::animate(F32 delta, BOOL upload_bake) +{ + if (mNext) + { + mNext->animate(delta, upload_bake); + } +} + +//----------------------------------------------------------------------------- +// LLTexLayerParamColorInfo +//----------------------------------------------------------------------------- +LLTexLayerParamColorInfo::LLTexLayerParamColorInfo() : + mOperation(LLTexLayerParamColor::OP_ADD), + mNumColors(0) +{ +} + +BOOL LLTexLayerParamColorInfo::parseXml(LLXmlTreeNode *node) +{ + llassert(node->hasName("param") && node->getChildByName("param_color")); + + if (!LLViewerVisualParamInfo::parseXml(node)) + return FALSE; + + LLXmlTreeNode* param_color_node = node->getChildByName("param_color"); + if (!param_color_node) + { + return FALSE; + } + + std::string op_string; + static LLStdStringHandle operation_string = LLXmlTree::addAttributeString("operation"); + if (param_color_node->getFastAttributeString(operation_string, op_string)) + { + LLStringUtil::toLower(op_string); + if (op_string == "add") mOperation = LLTexLayerParamColor::OP_ADD; + else if (op_string == "multiply") mOperation = LLTexLayerParamColor::OP_MULTIPLY; + else if (op_string == "blend") mOperation = LLTexLayerParamColor::OP_BLEND; + } + + mNumColors = 0; + + LLColor4U color4u; + for (LLXmlTreeNode* child = param_color_node->getChildByName("value"); + child; + child = param_color_node->getNextNamedChild()) + { + if ((mNumColors < MAX_COLOR_VALUES)) + { + static LLStdStringHandle color_string = LLXmlTree::addAttributeString("color"); + if (child->getFastAttributeColor4U(color_string, color4u)) + { + mColors[ mNumColors ].setVec(color4u); + mNumColors++; + } + } + } + if (!mNumColors) + { + llwarns << " is missing sub-elements" << llendl; + return FALSE; + } + + if ((mOperation == LLTexLayerParamColor::OP_BLEND) && (mNumColors != 1)) + { + llwarns << " with operation\"blend\" must have exactly one " << llendl; + return FALSE; + } + + return TRUE; +} diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 11fb9ada1..593a382cd 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -41,6 +41,7 @@ #include "llparcel.h" #include "llagent.h" +#include "llagentcamera.h" #include "llbutton.h" #include "llfocusmgr.h" #include "llviewercontrol.h" @@ -289,7 +290,7 @@ void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent) void LLToolBar::refresh() { BOOL show = gSavedSettings.getBOOL("ShowToolBar"); - BOOL mouselook = gAgent.cameraMouselook(); + BOOL mouselook = gAgentCamera.cameraMouselook(); setVisible(show && !mouselook); BOOL sitting = FALSE; @@ -467,9 +468,9 @@ void LLToolBar::onClickChat(void* user_data) // static void LLToolBar::onClickAppearance(void*) { - if (gAgent.areWearablesLoaded()) + if (gAgentWearables.areWearablesLoaded()) { - gAgent.changeCameraToCustomizeAvatar(); + gAgentCamera.changeCameraToCustomizeAvatar(); } } diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index d5883c8b1..c31717779 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -53,6 +53,7 @@ #include "llviewerobject.h" #include "llviewerwindow.h" #include "llagent.h" +#include "llagentcamera.h" #include "llfloatertools.h" #include "qtoolalign.h" #include "llviewercontrol.h" @@ -800,7 +801,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 ebedef626..137a07f6f 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -39,6 +39,7 @@ #include "lldir.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewercontrol.h" #include "llfirstuse.h" #include "llfloater.h" @@ -1060,7 +1061,7 @@ void LLToolDragAndDrop::pickCallback(const LLPickInfo& pick_info) gViewerWindow->getWindow()->setCursor( cursor ); LLToolDragAndDrop::getInstance()->mLastHitPos = pick_info.mPosGlobal; - LLToolDragAndDrop::getInstance()->mLastCameraPos = gAgent.getCameraPositionGlobal(); + LLToolDragAndDrop::getInstance()->mLastCameraPos = gAgentCamera.getCameraPositionGlobal(); } // static @@ -1937,7 +1938,7 @@ BOOL LLToolDragAndDrop::isInventoryGiveAcceptable(LLInventoryItem* item) case LLAssetType::AT_BODYPART: case LLAssetType::AT_CLOTHING: // - /*if(!copyable && gAgent.isWearingItem(item->getUUID())) + /*if(!copyable && gAgentWearables.isWearingItem(item->getUUID())) { acceptable = FALSE; }*/ @@ -2037,7 +2038,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL break; case LLAssetType::AT_BODYPART: case LLAssetType::AT_CLOTHING: - if(gAgent.isWearingItem(item->getUUID())) + if(gAgentWearables.isWearingItem(item->getUUID())) { worn = TRUE; } @@ -2558,7 +2559,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( { // Don't wear anything until initial wearables are loaded, can // destroy clothing items. - if (!gAgent.areWearablesLoaded()) + if (!gAgentWearables.areWearablesLoaded()) { LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded"); return ACCEPT_NO; @@ -2653,7 +2654,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory( { // Don't wear anything until initial wearables are loaded, can // destroy clothing items. - if (!gAgent.areWearablesLoaded()) + if (!gAgentWearables.areWearablesLoaded()) { LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded"); return ACCEPT_NO; diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index 375a84c9e..fa25c0c41 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" @@ -100,7 +101,7 @@ void LLToolCamera::handleSelect() // virtual void LLToolCamera::handleDeselect() { -// gAgent.setLookingAtAvatar(FALSE); +// gAgentCamera.setLookingAtAvatar(FALSE); } BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask) @@ -165,7 +166,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 ) @@ -205,20 +206,20 @@ 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); } static const LLCachedControl freeze_time("FreezeTime",0); if (!(pick_info.mKeyMask & MASK_ALT) && - gAgent.cameraThirdPerson() && + gAgentCamera.cameraThirdPerson() && gViewerWindow->getLeftMouseDown() && !freeze_time && (hit_obj == gAgent.getAvatarObject() || @@ -231,14 +232,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); } } @@ -275,10 +276,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) { @@ -364,12 +365,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(); @@ -383,8 +384,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 @@ -392,12 +393,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(); @@ -414,7 +415,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; @@ -423,11 +424,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 e31b6b542..3862df1c5 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -46,7 +46,7 @@ // newview headers #include "llagent.h" -//#include "llfloateravatarinfo.h" +#include "llagentcamera.h" #include "lldrawable.h" #include "llfloatertools.h" #include "llhudeffect.h" @@ -83,9 +83,15 @@ LLToolGrab::LLToolGrab( LLToolComposite* composite ) : LLTool( std::string("Grab"), composite ), mMode( GRAB_INACTIVE ), mVerticalDragging( FALSE ), + mHitLand(FALSE), + mLastMouseX(0), + mLastMouseY(0), + mAccumDeltaX(0), + mAccumDeltaY(0), mHasMoved( FALSE ), mOutsideSlop(FALSE), mDeselectedThisClick(FALSE), + mLastFace(0), mSpinGrabbing( FALSE ), mSpinRotation(), mHideBuildHighlight(FALSE) @@ -222,7 +228,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() && !script_touch) + if (gAgentCamera.cameraMouselook() && !script_touch) { mMode = GRAB_LOCKED; gViewerWindow->hideCursor(); @@ -281,8 +287,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 @@ -386,7 +392,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); @@ -514,7 +520,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) ) { @@ -522,7 +528,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; @@ -610,7 +616,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. @@ -644,7 +650,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 ); @@ -658,24 +664,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->getWindowWidth() - ROTATE_H_MARGIN) { - if (gAgent.getFocusOnAvatar()) + if (gAgentCamera.getFocusOnAvatar()) { gAgent.yaw(-rotate_angle); } else { - gAgent.cameraOrbitAround(-rotate_angle); + gAgentCamera.cameraOrbitAround(-rotate_angle); } } @@ -717,17 +723,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(); } } @@ -826,7 +832,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 ); } @@ -884,8 +890,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 ); } @@ -904,7 +910,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask) // Only works in fullscreen if (gSavedSettings.getBOOL("FullScreen")) { - if (gAgent.cameraThirdPerson() ) + if (gAgentCamera.cameraThirdPerson() ) { if (x == 0) { @@ -1006,7 +1012,7 @@ void LLToolGrab::onMouseCaptureLost() return; } // First, fix cursor placement - if( !gAgent.cameraMouselook() + if( !gAgentCamera.cameraMouselook() && (GRAB_ACTIVE_CENTER == mMode)) { if (objectp->isHUDAttachment()) @@ -1047,8 +1053,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(); } @@ -1140,7 +1146,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 0aa7ba311..fa65eafd9 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" @@ -80,7 +81,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 db47f023f..eaf6c5a68 100644 --- a/indra/newview/lltoolmgr.cpp +++ b/indra/newview/lltoolmgr.cpp @@ -52,6 +52,7 @@ #include "lltoolobjpicker.h" #include "lltoolpipette.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewercontrol.h" @@ -244,7 +245,7 @@ bool LLToolMgr::inBuildMode() static const LLCachedControl build_btn_state("BuildBtnState",false); bool b=(inEdit() && build_btn_state - && !gAgent.cameraMouselook() + && !gAgentCamera.cameraMouselook() && mCurrentToolset != gFaceEditToolset); return b; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 5fbb48258..e26e039e4 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" @@ -324,7 +325,7 @@ BOOL LLToolPie::pickAndShowMenu(BOOL always_show) LLToolCamera::getInstance()->pickCallback(mPick); if(gSavedSettings.getBOOL("ResetFocusOnSelfClick")) { - gAgent.setFocusOnAvatar(TRUE, TRUE); + gAgentCamera.setFocusOnAvatar(TRUE, TRUE); } return TRUE; @@ -755,7 +756,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 42766dfcc..b2a61a4ac 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -59,6 +59,7 @@ #include "llvolumemessage.h" #include "llhudmanager.h" #include "llagent.h" +#include "llagentcamera.h" #include "llaudioengine.h" #include "llhudeffecttrail.h" #include "llviewerobjectlist.h" @@ -127,7 +128,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 b68e19f19..f38928600 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" @@ -101,7 +102,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi if (gFloaterTools->getVisible()) { // Copy/paste from toggle_build_mode() - gAgent.resetView(false); + gAgentCamera.resetView(false); gFloaterTools->close(); gViewerWindow->showCursor(); } @@ -122,7 +123,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi else if (gFloaterTools->getVisible()) { // Copy/paste from toggle_build_mode() - gAgent.resetView(false); + gAgentCamera.resetView(false); gFloaterTools->close(); gViewerWindow->showCursor(); } @@ -214,7 +215,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/lltoolselectland.cpp b/indra/newview/lltoolselectland.cpp index 91223904b..f80b4e3ad 100644 --- a/indra/newview/lltoolselectland.cpp +++ b/indra/newview/lltoolselectland.cpp @@ -38,12 +38,10 @@ #include "llparcel.h" // Viewer includes -#include "llagent.h" #include "llviewercontrol.h" #include "llfloatertools.h" #include "llselectmgr.h" #include "llstatusbar.h" -#include "lltoolview.h" #include "llviewerparcelmgr.h" #include "llviewerwindow.h" diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp index d544bff99..890666f34 100644 --- a/indra/newview/lltoolselectrect.cpp +++ b/indra/newview/lltoolselectrect.cpp @@ -44,7 +44,6 @@ #include "llviewercontrol.h" #include "llui.h" #include "llselectmgr.h" -#include "lltoolview.h" #include "lltoolmgr.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index dbb0d999e..299db5c1a 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 "llcolorscheme.h" #include "llfloaterworldmap.h" @@ -491,14 +492,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 b53593467..3d81cdea7 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); @@ -197,7 +198,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); @@ -220,7 +221,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/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 022f7bc59..be3330bda 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -38,6 +38,7 @@ #include "llquaternion.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewercontrol.h" #include "lldrawable.h" #include "llface.h" @@ -340,7 +341,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection, } else { - z_far = gAgent.mDrawDistance; + z_far = gAgentCamera.mDrawDistance; } } else diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 410dcc004..3808cfa25 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -40,6 +40,7 @@ // For Listeners #include "llaudioengine.h" #include "llagent.h" +#include "llagentcamera.h" #include "llavatarnamecache.h" #include "llconsole.h" #include "lldrawpoolterrain.h" @@ -109,7 +110,7 @@ static bool handleRenderAvatarMouselookChanged(const LLSD& newvalue) static bool handleRenderFarClipChanged(const LLSD& newvalue) { F32 draw_distance = (F32) newvalue.asReal(); - gAgent.mDrawDistance = draw_distance; + gAgentCamera.mDrawDistance = draw_distance; //Force it to a sane value. I've had drawdistance get knocked down to 0.. and BAD things happen. LLWorld::getInstance()->setLandFarClip(draw_distance); return true; } @@ -582,6 +583,12 @@ static bool handlePhoenixNameSystemChanged(const LLSD& newvalue) } // [/Ansariel: Display name support] +static bool handleAllowLargeSounds(const LLSD& newvalue) +{ + if(gAudiop) + gAudiop->setAllowLargeSounds(newvalue.asBoolean()); + return true; +} //////////////////////////////////////////////////////////////////////////// void settings_setup_listeners() { @@ -753,6 +760,8 @@ void settings_setup_listeners() // [Ansariel: Display name support] gSavedSettings.getControl("PhoenixNameSystem")->getSignal()->connect(boost::bind(&handlePhoenixNameSystemChanged, _1)); // [/Ansariel: Display name support] + + gSavedSettings.getControl("AllowLargeSounds")->getSignal()->connect(boost::bind(&handleAllowLargeSounds, _1)); } template <> eControlType get_control_type(const U32& in, LLSD& out) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 8e62a5753..8414945a8 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" @@ -174,7 +175,7 @@ void display_update_camera(bool tiling=false) // Cut draw distance in half when customizing avatar, // but on the viewer only. - F32 final_far = gAgent.mDrawDistance; + F32 final_far = gAgentCamera.mDrawDistance; if(tiling) //Don't animate clouds and water if tiling! { LLViewerCamera::getInstance()->setFar(final_far); @@ -182,7 +183,7 @@ void display_update_camera(bool tiling=false) LLWorld::getInstance()->setLandFarClip(final_far); return; } - if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) + if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) { final_far *= 0.5f; } @@ -412,7 +413,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gTextureList.mForceResetTextureStats = TRUE; - if(!gSavedSettings.getBOOL("AscentDisableTeleportScreens"))gAgent.resetView(TRUE, TRUE); + if(!gSavedSettings.getBOOL("AscentDisableTeleportScreens"))gAgentCamera.resetView(TRUE, TRUE); break; case LLAgent::TELEPORT_ARRIVING: @@ -987,12 +988,12 @@ 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); // [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Modified: RLVa-1.0.0c - gAgent.mHUDTargetZoom = llclamp(gAgent.mHUDTargetZoom, (!gRlvAttachmentLocks.hasLockedHUD()) ? 0.1f : 0.85f, 1.f); + gAgentCamera.mHUDTargetZoom = llclamp(gAgentCamera.mHUDTargetZoom, (!gRlvAttachmentLocks.hasLockedHUD()) ? 0.1f : 0.85f, 1.f); // [/RLVa:KB] // 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()) { @@ -1105,7 +1106,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(); // set up transform to keep HUD objects in front of camera @@ -1381,14 +1382,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) { gGL.pushMatrix(); S32 half_width = (gViewerWindow->getWindowWidth() / 2); S32 half_height = (gViewerWindow->getWindowHeight() / 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 e154234b1..6bb8be13f 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -37,6 +37,7 @@ #include "indra_constants.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewercontrol.h" #include "llconsole.h" #include "llinventorymodel.h" diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index ccfa99dd3..67bd7786c 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -37,7 +37,6 @@ // Header Files //----------------------------------------------------------------------------- #include "lljoint.h" -#include "llapr.h" class LLFace; class LLViewerJointMesh; diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 926a9f9c7..36e9b71f6 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -39,7 +39,6 @@ #include "llfasttimer.h" #include "llrender.h" -#include "llagent.h" #include "llapr.h" #include "llbox.h" #include "lldrawable.h" diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index 3e4854e1a..3a5987468 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -37,7 +37,6 @@ #include "llviewertexture.h" #include "llpolymesh.h" #include "v4color.h" -#include "llapr.h" class LLDrawable; class LLFace; diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index 9058bdc13..f810de5ad 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(); } } @@ -949,7 +950,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 67df36631..ef0fa8447 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 "llchatbar.h" #include "llviewercontrol.h" #include "llfocusmgr.h" @@ -246,22 +247,22 @@ F32 get_orbit_rate() void camera_spin_around_ccw( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitLeftKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); } void camera_spin_around_cw( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitRightKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.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); @@ -269,7 +270,7 @@ void camera_spin_around_ccw_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitLeftKey( get_orbit_rate() ); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); } } @@ -277,7 +278,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); @@ -285,7 +286,7 @@ void camera_spin_around_cw_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitRightKey( get_orbit_rate() ); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); } } @@ -293,22 +294,22 @@ void camera_spin_around_cw_sitting( EKeystate s ) void camera_spin_over( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitUpKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); } void camera_spin_under( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitDownKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.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); @@ -316,7 +317,7 @@ void camera_spin_over_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitUpKey( get_orbit_rate() ); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); } } @@ -324,7 +325,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); @@ -332,35 +333,35 @@ void camera_spin_under_sitting( EKeystate s ) else { //change camera but do not send keystrokes - gAgent.setOrbitDownKey( get_orbit_rate() ); + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); } } void camera_move_forward( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitInKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); } void camera_move_backward( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitOutKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.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); } else { - gAgent.setOrbitInKey( get_orbit_rate() ); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); } } @@ -369,70 +370,70 @@ 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); } else { - gAgent.setOrbitOutKey( get_orbit_rate() ); + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); } } void camera_pan_up( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanUpKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanUpKey( get_orbit_rate() ); } void camera_pan_down( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanDownKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanDownKey( get_orbit_rate() ); } void camera_pan_left( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanLeftKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanLeftKey( get_orbit_rate() ); } void camera_pan_right( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanRightKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanRightKey( get_orbit_rate() ); } void camera_pan_in( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanInKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanInKey( get_orbit_rate() ); } void camera_pan_out( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setPanOutKey( get_orbit_rate() ); + gAgentCamera.unlockView(); + gAgentCamera.setPanOutKey( get_orbit_rate() ); } void camera_move_forward_fast( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitInKey(2.5f); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitInKey(2.5f); } void camera_move_backward_fast( EKeystate s ) { if( KEYSTATE_UP == s ) return; - gAgent.unlockView(); - gAgent.setOrbitOutKey(2.5f); + gAgentCamera.unlockView(); + gAgentCamera.setOrbitOutKey(2.5f); } @@ -440,7 +441,7 @@ void edit_avatar_spin_ccw( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitLeftKey( get_orbit_rate() ); + gAgentCamera.setOrbitLeftKey( get_orbit_rate() ); //gMorphView->orbitLeft( get_orbit_rate() ); } @@ -449,7 +450,7 @@ void edit_avatar_spin_cw( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitRightKey( get_orbit_rate() ); + gAgentCamera.setOrbitRightKey( get_orbit_rate() ); //gMorphView->orbitRight( get_orbit_rate() ); } @@ -457,7 +458,7 @@ void edit_avatar_spin_over( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitUpKey( get_orbit_rate() ); + gAgentCamera.setOrbitUpKey( get_orbit_rate() ); //gMorphView->orbitUp( get_orbit_rate() ); } @@ -466,7 +467,7 @@ void edit_avatar_spin_under( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitDownKey( get_orbit_rate() ); + gAgentCamera.setOrbitDownKey( get_orbit_rate() ); //gMorphView->orbitDown( get_orbit_rate() ); } @@ -474,7 +475,7 @@ void edit_avatar_move_forward( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitInKey( get_orbit_rate() ); + gAgentCamera.setOrbitInKey( get_orbit_rate() ); //gMorphView->orbitIn(); } @@ -483,7 +484,7 @@ void edit_avatar_move_backward( EKeystate s ) { if( KEYSTATE_UP == s ) return; gMorphView->setCameraDrivenByKeys( TRUE ); - gAgent.setOrbitOutKey( get_orbit_rate() ); + gAgentCamera.setOrbitOutKey( get_orbit_rate() ); //gMorphView->orbitOut(); } @@ -834,7 +835,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 2e372a1ca..9ad2c8f0b 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -39,6 +39,7 @@ #include "llpanelmediahud.h" #include "llpluginclassmedia.h" #include "llagent.h" +#include "llagentcamera.h" #include "lltoolpie.h" #include "llviewercamera.h" #include "llviewermedia.h" @@ -120,7 +121,7 @@ void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer objectp { if (!mFocus->isEmpty()) { - gAgent.setFocusOnAvatar(TRUE, ANIMATE); + gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE); } } mFocus = NULL; @@ -162,7 +163,7 @@ void LLViewerMediaFocus::setCameraZoom(F32 padding_factor) if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) { - gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); F32 height; @@ -200,7 +201,7 @@ void LLViewerMediaFocus::setCameraZoom(F32 padding_factor) distance += depth * 0.5; // Finally animate the camera to this new position and focal point - gAgent.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(pick.mNormal * distance), + gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(pick.mNormal * distance), LLSelectMgr::getInstance()->getSelectionCenterGlobal(), LLSelectMgr::getInstance()->getSelection()->getFirstObject()->mID ); } } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 6599123bb..45c64a4ef 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -73,7 +73,8 @@ // newview includes #include "llagent.h" - +#include "llagentcamera.h" +#include "llagentwearables.h" #include "jcfloaterareasearch.h" #include "llagentpilot.h" @@ -2021,7 +2022,7 @@ bool toggle_build_mode() else { // manually disable edit mode, but do not affect the camera - gAgent.resetView(false); + gAgentCamera.resetView(false); gFloaterTools->close(); gViewerWindow->showCursor(); } @@ -2030,7 +2031,7 @@ bool toggle_build_mode() } 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 @@ -2045,13 +2046,13 @@ bool toggle_build_mode() 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 ); } } @@ -2068,7 +2069,7 @@ bool toggle_build_mode() // Could be first use LLFirstUse::useBuild(); - gAgent.resetView(false); + gAgentCamera.resetView(false); // avoid spurious avatar movements LLViewerJoystick::getInstance()->setNeedsReset(); @@ -2131,18 +2132,18 @@ class LLObjectBuild : public view_listener_t { bool handleEvent(LLPointer event, 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(); } @@ -2178,7 +2179,7 @@ class LLObjectEdit : public view_listener_t } // [/RLVa:KB] - if (gAgent.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit()) + if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit()) { LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); @@ -2186,19 +2187,19 @@ class LLObjectEdit : public view_listener_t { // 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(); } } @@ -2271,19 +2272,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(); } @@ -2386,7 +2387,7 @@ class LLSelfRemoveAllAttachments : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - LLAgent::userRemoveAllAttachments(NULL); + LLAgentWearables::userRemoveAllAttachments(NULL); return true; } }; @@ -2796,12 +2797,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 @@ -3330,7 +3331,7 @@ bool callback_leave_group(const LLSD& notification, const LLSD& response) msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_GroupData); - msg->addUUIDFast(_PREHASH_GroupID, gAgent.mGroupID ); + msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() ); gAgent.sendReliableMessage(); } return false; @@ -3341,7 +3342,7 @@ void handle_leave_group(void *) if (gAgent.getGroupID() != LLUUID::null) { LLSD args; - args["GROUP"] = gAgent.mGroupName; + args["GROUP"] = gAgent.getGroupName(); LLNotifications::instance().add("GroupLeaveConfirmMember", args, LLSD(), callback_leave_group); } } @@ -3484,10 +3485,10 @@ void handle_show_notifications_console(void *) void handle_dump_group_info(void *) { - llinfos << "group " << gAgent.mGroupName << llendl; - llinfos << "ID " << gAgent.mGroupID << llendl; + llinfos << "group " << gAgent.getGroupName() << llendl; + llinfos << "ID " << gAgent.getGroupID() << llendl; llinfos << "powers " << gAgent.mGroupPowers << llendl; - llinfos << "title " << gAgent.mGroupTitle << llendl; + llinfos << "title " << gAgent.getGroupTitle() << llendl; //llinfos << "insig " << gAgent.mGroupInsigniaID << llendl; } @@ -3906,7 +3907,7 @@ class LLEditEnableCustomizeAvatar : public view_listener_t { bool new_value = (gAgent.getAvatarObject() && gAgent.getAvatarObject()->isFullyLoaded() && - gAgent.areWearablesLoaded()); + gAgentWearables.areWearablesLoaded()); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -4176,7 +4177,7 @@ void reset_view_final( BOOL proceed, void* ); 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, NULL ); @@ -4204,14 +4205,14 @@ void reset_view_final( BOOL proceed, void* ) return; } - gAgent.resetView(TRUE, TRUE); + gAgentCamera.resetView(TRUE, TRUE); } class LLViewLookAtLastChatter : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - gAgent.lookAtLastChat(); + gAgentCamera.lookAtLastChat(); return true; } }; @@ -4220,13 +4221,13 @@ class LLViewMouselook : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) { - if (!gAgent.cameraMouselook()) + if (!gAgentCamera.cameraMouselook()) { - gAgent.changeCameraToMouselook(); + gAgentCamera.changeCameraToMouselook(); } else { - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); } return true; } @@ -4513,9 +4514,9 @@ void handle_show_overlay_title(void*) void derez_objects(EDeRezDestination dest, const LLUUID& dest_id) { - if(gAgent.cameraMouselook()) + if(gAgentCamera.cameraMouselook()) { - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); } //gInventoryView->setPanelOpen(TRUE); @@ -5636,7 +5637,7 @@ class LLViewEnableLastChatter : public view_listener_t bool handleEvent(LLPointer event, 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()); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -5769,7 +5770,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() @@ -6054,7 +6055,7 @@ class LLToolsLookAtSelection : public view_listener_t BOOL zoom = (userdata.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()); @@ -6070,13 +6071,13 @@ class LLToolsLookAtSelection : public view_listener_t } if (zoom) { - 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 ); } } return true; @@ -6371,9 +6372,9 @@ class LLShowFloater : public view_listener_t } else if (floater_name == "appearance") { - if (gAgent.areWearablesLoaded()) + if (gAgentWearables.areWearablesLoaded()) { - gAgent.changeCameraToCustomizeAvatar(); + gAgentCamera.changeCameraToCustomizeAvatar(); } } // Phoenix: Wolfspirit: Enabled Show Floater out of viewer menu @@ -6739,16 +6740,16 @@ void handle_focus(void *) return; } - if (gAgent.getFocusOnAvatar()) + if (gAgentCamera.getFocusOnAvatar()) { // zoom in if we're looking at the avatar - gAgent.setFocusOnAvatar(FALSE, ANIMATE); - gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick()); - gAgent.cameraZoomIn(0.666f); + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gAgentCamera.cameraZoomIn(0.666f); } else { - gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); } gViewerWindow->moveCursorToCenter(); @@ -6769,18 +6770,18 @@ class LLLandEdit : public view_listener_t } // [/RLVa:KB] - 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(); } @@ -6818,17 +6819,17 @@ BOOL enable_buy_land(void*) void handle_move(void*) { - if (gAgent.getFocusOnAvatar()) + if (gAgentCamera.getFocusOnAvatar()) { // 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.cameraZoomIn(0.666f); + gAgentCamera.cameraZoomIn(0.666f); } else { - gAgent.setFocusGlobal(LLToolPie::getInstance()->getPick()); + gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick()); } gViewerWindow->moveCursorToCenter(); @@ -6932,7 +6933,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(); } } } @@ -8031,7 +8032,7 @@ class LLToolsEnableSaveToObjectInventory : public view_listener_t BOOL enable_not_thirdperson(void*) { - return !gAgent.cameraThirdPerson(); + return !gAgentCamera.cameraThirdPerson(); } @@ -8058,7 +8059,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")); gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); return true; } @@ -9185,51 +9186,51 @@ class LLEditEnableTakeOff : public view_listener_t bool new_value = false; if (clothing == "shirt") { - new_value = LLAgent::selfHasWearable((void *)WT_SHIRT); + new_value = LLAgentWearables::selfHasWearable((void *)WT_SHIRT); } if (clothing == "pants") { - new_value = LLAgent::selfHasWearable((void *)WT_PANTS); + new_value = LLAgentWearables::selfHasWearable((void *)WT_PANTS); } if (clothing == "shoes") { - new_value = LLAgent::selfHasWearable((void *)WT_SHOES); + new_value = LLAgentWearables::selfHasWearable((void *)WT_SHOES); } if (clothing == "socks") { - new_value = LLAgent::selfHasWearable((void *)WT_SOCKS); + new_value = LLAgentWearables::selfHasWearable((void *)WT_SOCKS); } if (clothing == "jacket") { - new_value = LLAgent::selfHasWearable((void *)WT_JACKET); + new_value = LLAgentWearables::selfHasWearable((void *)WT_JACKET); } if (clothing == "gloves") { - new_value = LLAgent::selfHasWearable((void *)WT_GLOVES); + new_value = LLAgentWearables::selfHasWearable((void *)WT_GLOVES); } if (clothing == "undershirt") { - new_value = LLAgent::selfHasWearable((void *)WT_UNDERSHIRT); + new_value = LLAgentWearables::selfHasWearable((void *)WT_UNDERSHIRT); } if (clothing == "underpants") { - new_value = LLAgent::selfHasWearable((void *)WT_UNDERPANTS); + new_value = LLAgentWearables::selfHasWearable((void *)WT_UNDERPANTS); } if (clothing == "skirt") { - new_value = LLAgent::selfHasWearable((void *)WT_SKIRT); + new_value = LLAgentWearables::selfHasWearable((void *)WT_SKIRT); } if (clothing == "alpha") { - new_value = LLAgent::selfHasWearable((void *)WT_ALPHA); + new_value = LLAgentWearables::selfHasWearable((void *)WT_ALPHA); } if (clothing == "tattoo") { - new_value = LLAgent::selfHasWearable((void *)WT_TATTOO); + new_value = LLAgentWearables::selfHasWearable((void *)WT_TATTOO); } if (clothing == "physics") { - new_value = LLAgent::selfHasWearable((void *)WT_PHYSICS); + new_value = LLAgentWearables::selfHasWearable((void *)WT_PHYSICS); } // [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b | OK @@ -9252,55 +9253,55 @@ class LLEditTakeOff : public view_listener_t std::string clothing = userdata.asString(); if (clothing == "shirt") { - LLAgent::userRemoveWearable((void*)WT_SHIRT); + LLAgentWearables::userRemoveWearable((void*)WT_SHIRT); } else if (clothing == "pants") { - LLAgent::userRemoveWearable((void*)WT_PANTS); + LLAgentWearables::userRemoveWearable((void*)WT_PANTS); } else if (clothing == "shoes") { - LLAgent::userRemoveWearable((void*)WT_SHOES); + LLAgentWearables::userRemoveWearable((void*)WT_SHOES); } else if (clothing == "socks") { - LLAgent::userRemoveWearable((void*)WT_SOCKS); + LLAgentWearables::userRemoveWearable((void*)WT_SOCKS); } else if (clothing == "jacket") { - LLAgent::userRemoveWearable((void*)WT_JACKET); + LLAgentWearables::userRemoveWearable((void*)WT_JACKET); } else if (clothing == "gloves") { - LLAgent::userRemoveWearable((void*)WT_GLOVES); + LLAgentWearables::userRemoveWearable((void*)WT_GLOVES); } else if (clothing == "undershirt") { - LLAgent::userRemoveWearable((void*)WT_UNDERSHIRT); + LLAgentWearables::userRemoveWearable((void*)WT_UNDERSHIRT); } else if (clothing == "underpants") { - LLAgent::userRemoveWearable((void*)WT_UNDERPANTS); + LLAgentWearables::userRemoveWearable((void*)WT_UNDERPANTS); } else if (clothing == "skirt") { - LLAgent::userRemoveWearable((void*)WT_SKIRT); + LLAgentWearables::userRemoveWearable((void*)WT_SKIRT); } else if (clothing == "alpha") { - LLAgent::userRemoveWearable((void*)WT_ALPHA); + LLAgentWearables::userRemoveWearable((void*)WT_ALPHA); } else if (clothing == "tattoo") { - LLAgent::userRemoveWearable((void*)WT_TATTOO); + LLAgentWearables::userRemoveWearable((void*)WT_TATTOO); } else if (clothing == "physics") { - LLAgent::userRemoveWearable((void*)WT_PHYSICS); + LLAgentWearables::userRemoveWearable((void*)WT_PHYSICS); } else if (clothing == "all") { - LLAgent::userRemoveAllClothes(NULL); + LLAgentWearables::userRemoveAllClothes(NULL); } return true; } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index d246ffe62..d0b6d61c6 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -36,6 +36,7 @@ // project includes #include "llagent.h" +#include "llagentcamera.h" #include "llimagejpeg.h" #include "llimagepng.h" @@ -171,9 +172,9 @@ class AIFileUpload { void AIFileUpload::start_filepicker(ELoadFilter filter, char const* context) { - if( gAgent.cameraMouselook() ) + if( gAgentCamera.cameraMouselook() ) { - gAgent.changeCameraToDefault(); + gAgentCamera.changeCameraToDefault(); // This doesn't seem necessary. JC // display(); } @@ -334,9 +335,9 @@ class LLFileUploadBulk : public view_listener_t { bool handleEvent(LLPointer event, 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 a670b229f..3c1a73cc0 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -67,6 +67,7 @@ #include "llmd5.h" #include "llagent.h" +#include "llagentcamera.h" #include "llcallingcard.h" #include "llconsole.h" #include "llvieweraudio.h" @@ -3742,7 +3743,7 @@ void process_teleport_finish(LLMessageSystem* msg, void**) gAgent.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); @@ -3750,7 +3751,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); @@ -3886,9 +3887,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) look_at = LLViewerCamera::getInstance()->getAtAxis(); } // 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 ); @@ -3949,7 +3950,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); } } @@ -4104,7 +4105,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(); @@ -4231,7 +4232,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis()); msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis()); msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis()); - msg->addF32Fast(_PREHASH_Far, gAgent.mDrawDistance); + msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); msg->addU32Fast(_PREHASH_ControlFlags, control_flags); @@ -4890,7 +4891,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) @@ -4927,10 +4928,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.mForceMouselook = force_mouselook; + gAgentCamera.setForceMouselook(force_mouselook); LLViewerObject* object = gObjectList.findObject(sitObjectID); if (object) @@ -5930,9 +5931,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(); } LLInventoryView* view = LLInventoryView::getActiveInventory(); @@ -6161,11 +6162,11 @@ void process_teleport_local(LLMessageSystem *msg,void**) } gAgent.setPositionAgent(pos); - gAgent.slamLookAt(look_at); + gAgentCamera.slamLookAt(look_at); if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstance()->getOverrideCamera()) && gSavedSettings.getBOOL("OptionRotateCamAfterLocalTP")) { - gAgent.resetView(TRUE, TRUE); + gAgentCamera.resetView(TRUE, TRUE); } // send camera update to new region diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3a68d6133..0708a587d 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -59,6 +59,7 @@ #include "llaudiosourcevo.h" #include "llagent.h" +#include "llagentcamera.h" #include "llbbox.h" #include "llbox.h" #include "llcylinder.h" @@ -2813,7 +2814,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 94e519604..36f451f04 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -46,6 +46,7 @@ #include "llviewerwindow.h" #include "llnetmap.h" #include "llagent.h" +#include "llagentcamera.h" #include "pipeline.h" #include "llspatialpartition.h" #include "llhoverview.h" @@ -292,7 +293,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { LLFastTimer t(LLFastTimer::FTM_PROCESS_OBJECTS); - LLVector3d camera_global = gAgent.getCameraPositionGlobal(); + LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); LLViewerObject *objectp; S32 num_objects; U32 local_id; @@ -621,7 +622,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) } // Focused - objectp = gAgent.getFocusObject(); + objectp = gAgentCamera.getFocusObject(); if (objectp) { objectp->boostTexturePriority(); @@ -930,21 +931,24 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp) void LLViewerObjectList::killObjects(LLViewerRegion *regionp) { + LLTimer kill_timer; LLViewerObject *objectp; - + S32 count = 0; for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { objectp = *iter; if (objectp->mRegionp == regionp) { + ++count; killObject(objectp); } } // Have to clean right away because the region is becoming invalid. cleanDeadObjects(FALSE); + llinfos << "Removed " << count << " objects for region " << regionp->getName() << ". (" << kill_timer.getElapsedTimeF64()*1000.0 << "ms)" << llendl; } void LLViewerObjectList::killAllObjects() @@ -1340,7 +1344,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/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 88f7e36bf..25edaa82a 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -45,6 +45,7 @@ // Viewer includes #include "llagent.h" +#include "llagentaccess.h" #include "llfloatergroupinfo.h" #include "llviewerwindow.h" #include "llviewercontrol.h" diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 4e8f30f70..46051f98e 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -42,6 +42,7 @@ #include "v2math.h" // newview includes +#include "llagentcamera.h" #include "llviewercontrol.h" #include "llsurface.h" #include "llviewerregion.h" @@ -757,7 +758,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; @@ -788,7 +789,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 3ab4390d7..fd1e82d1d 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -46,6 +46,7 @@ #include "v4math.h" #include "llagent.h" +#include "llagentcamera.h" #include "llcallingcard.h" #include "llcaphttpsender.h" #include "lldir.h" @@ -809,7 +810,7 @@ void LLViewerRegion::calculateCenterGlobal() void LLViewerRegion::calculateCameraDistance() { - mCameraDistanceSquared = (F32)(gAgent.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared(); + mCameraDistanceSquared = (F32)(gAgentCamera.getCameraPositionGlobal() - getCenterGlobal()).magVecSquared(); } U32 LLViewerRegion::getNetDetailsForLCD() diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 997a393ff..1f09298d3 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -48,6 +48,7 @@ #include "llsurface.h" #include "llvlmanager.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewercontrol.h" #include "llfloaterdirectory.h" #include "llfloatertools.h" @@ -517,11 +518,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 6b633b523..6f5a9dc0d 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -37,6 +37,8 @@ #include #include +#include "llagent.h" +#include "llagentcamera.h" #include "llpanellogin.h" #include "llviewerkeyboard.h" #include "llviewerwindow.h" @@ -364,7 +366,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])); @@ -970,7 +972,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 @@ -1296,7 +1298,10 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated) } // SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues - gAgent.changeCameraToDefault(); + if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) + { + gAgentCamera.changeCameraToDefault(); + } send_agent_pause(); @@ -1313,7 +1318,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; @@ -2363,7 +2368,7 @@ void LLViewerWindow::draw() // Draw tool specific overlay on world LLToolMgr::getInstance()->getCurrentTool()->draw(); - if( gAgent.cameraMouselook() ) + if( gAgentCamera.cameraMouselook() ) { drawMouselookInstructions(); stop_glerror(); @@ -2739,7 +2744,7 @@ void LLViewerWindow::handleScrollWheel(S32 clicks) } // Zoom the camera in and out behavior - gAgent.handleScrollWheel(clicks); + gAgentCamera.handleScrollWheel(clicks); return; } @@ -3308,7 +3313,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); } @@ -3437,7 +3442,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 @@ -3446,7 +3451,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; } @@ -3818,7 +3823,7 @@ LLVector3 LLViewerWindow::mousePointHUD(const S32 x, const S32 y) const F32 hud_x = -((F32)x - (F32)width/2.f) / height; F32 hud_y = ((F32)y - (F32)height/2.f) / 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 @@ -3861,7 +3866,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) @@ -3875,7 +3880,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; } @@ -3893,12 +3898,12 @@ 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; // walk forwards to find the point - for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < gAgent.mDrawDistance; mouse_dir_scale += FIRST_PASS_STEP) + for (mouse_dir_scale = FIRST_PASS_STEP; mouse_dir_scale < gAgentCamera.mDrawDistance; mouse_dir_scale += FIRST_PASS_STEP) { LLVector3d mouse_direction_global_d; mouse_direction_global_d.setVec(mouse_direction_global * mouse_dir_scale); @@ -5259,9 +5264,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; } @@ -5472,7 +5477,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/llvlmanager.cpp b/indra/newview/llvlmanager.cpp index 177093c4d..07ef26266 100644 --- a/indra/newview/llvlmanager.cpp +++ b/indra/newview/llvlmanager.cpp @@ -40,7 +40,6 @@ #include "patch_dct.h" #include "llviewerregion.h" #include "llframetimer.h" -#include "llagent.h" #include "llsurface.h" LLVLManager gVLManager; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ac4462875..6f3878c65 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -43,6 +43,9 @@ #include "cofmgr.h" #include "llagent.h" // Get state values from here +#include "llagentwearables.h" +#include "llanimationstates.h" +#include "llagentcamera.h" #include "llviewercontrol.h" #include "lldrawpoolavatar.h" #include "lldriverparam.h" @@ -778,6 +781,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, { mIsSelf = TRUE; gAgent.setAvatarObject(this); + gAgentWearables.setAvatarObject(this); lldebugs << "Marking avatar as self " << id << llendl; } else @@ -1185,7 +1189,7 @@ void LLVOAvatar::getMeshInfo (mesh_info_t* mesh_info) // static void LLVOAvatar::dumpBakedStatus() { - LLVector3d camera_pos_global = gAgent.getCameraPositionGlobal(); + LLVector3d camera_pos_global = gAgentCamera.getCameraPositionGlobal(); for (std::vector::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) @@ -2336,7 +2340,7 @@ void LLVOAvatar::restoreMeshData() if (isSelf()) { - updateAttachmentVisibility(gAgent.getCameraMode()); + updateAttachmentVisibility(gAgentCamera.getCameraMode()); } else { @@ -2762,7 +2766,7 @@ BOOL LLVOAvatar::detachAttachmentIntoInventory(const LLUUID &item_id) 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 ) { //---------------------------------------------------------------- @@ -3505,7 +3509,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) if (isSelf()) { render_name = render_name - && !gAgent.cameraMouselook() + && !gAgentCamera.cameraMouselook() && (visible_chat || !render_name_hide_self); } @@ -4159,10 +4163,10 @@ void LLVOAvatar::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() && @@ -4481,7 +4485,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()) @@ -4520,7 +4524,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); @@ -4782,7 +4786,7 @@ void LLVOAvatar::updateVisibility() if(isSelf()) { - if( !gAgent.areWearablesLoaded()) + if( !gAgentWearables.areWearablesLoaded()) { visible = FALSE; } @@ -6631,7 +6635,7 @@ BOOL LLVOAvatar::updateJointLODs() { if (isSelf()) { - if(gAgent.cameraCustomizeAvatar() || gAgent.cameraMouselook()) + if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook()) { mAdjustedPixelArea = MAX_PIXEL_AREA; } @@ -6776,7 +6780,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); } @@ -6809,7 +6813,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); } @@ -6904,7 +6908,7 @@ BOOL LLVOAvatar::setParent(LLViewerObject* parent) ret = LLViewerObject::setParent(parent); if (isSelf()) { - gAgent.resetCamera(); + gAgentCamera.resetCamera(); } } else @@ -7000,7 +7004,7 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) if (isSelf()) { - updateAttachmentVisibility(gAgent.getCameraMode()); + updateAttachmentVisibility(gAgentCamera.getCameraMode()); // Then make sure the inventory is in sync with the avatar. gInventory.addChangedMask( LLInventoryObserver::LABEL, item_id ); @@ -7024,7 +7028,7 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) if (isSelf()) { - updateAttachmentVisibility(gAgent.getCameraMode()); + updateAttachmentVisibility(gAgentCamera.getCameraMode()); // [RLVa:KB] - Checked: 2010-08-22 (RLVa-1.2.1a) | Modified: RLVa-1.2.1a // NOTE: RLVa event handlers should be invoked *after* LLVOAvatar::attachObject() calls LLViewerJointAttachment::addObject() @@ -7283,13 +7287,13 @@ 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.mForceMouselook) gAgent.changeCameraToMouselook(); + gAgentCamera.setupSitCamera(); + if (gAgentCamera.getForceMouselook()) gAgentCamera.changeCameraToMouselook(); } } @@ -7362,9 +7366,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); if (!sit_object->permYouOwner() && gSavedSettings.getBOOL("RevokePermsOnStandUp")) { @@ -7534,11 +7538,11 @@ void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerFetchedTexture *src discard_level < local_tex_data.mDiscard) { local_tex_data.mDiscard = discard_level; - if ( self->isSelf() && !gAgent.cameraCustomizeAvatar() ) + if ( self->isSelf() && !gAgentCamera.cameraCustomizeAvatar() ) { self->requestLayerSetUpdate( index ); } - else if( self->isSelf() && gAgent.cameraCustomizeAvatar() ) + else if( self->isSelf() && gAgentCamera.cameraCustomizeAvatar() ) { LLVisualParamHint::requestHintUpdates(); } @@ -8160,7 +8164,7 @@ void LLVOAvatar::setLocTexTE( U8 te, LLViewerTexture* image, BOOL set_by_user ) setTEImage( te, image ); updateMeshTextures(); - if( gAgent.cameraCustomizeAvatar() ) + if( gAgentCamera.cameraCustomizeAvatar() ) { LLVisualParamHint::requestHintUpdates(); } @@ -8197,7 +8201,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 is_layer_baked; @@ -8353,11 +8357,11 @@ void LLVOAvatar::setLocalTexture( ETextureIndex index, LLViewerFetchedTexture* t if (tex_discard >= 0 && tex_discard <= desired_discard) { local_tex_data.mDiscard = tex_discard; - if( isSelf() && !gAgent.cameraCustomizeAvatar() ) + if( isSelf() && !gAgentCamera.cameraCustomizeAvatar() ) { requestLayerSetUpdate( index ); } - 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 f13b973da..fa291580c 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 "llviewerwindow.h" #include "lldrawable.h" #include "llface.h" @@ -333,7 +333,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 978fbd509..d850ced0d 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(); } BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 00e48687d..b143b6bea 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" @@ -372,7 +373,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); @@ -2049,7 +2050,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 b16547398..548dab8b0 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -46,7 +46,7 @@ #include "material_codes.h" #include "object_flags.h" -#include "llagent.h" +#include "llagentcamera.h" #include "lldrawable.h" #include "llface.h" #include "llviewercamera.h" @@ -454,7 +454,7 @@ void LLVOTree::render(LLAgent &agent) void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) { LLVector3 center = getPositionAgent();//center of tree. - LLVector3 viewer_pos_agent = gAgent.getCameraPositionAgent(); + LLVector3 viewer_pos_agent = gAgentCamera.getCameraPositionAgent(); LLVector3 lookAt = center - viewer_pos_agent; F32 dist = lookAt.normVec() ; F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 8b7dc172e..71e4f0323 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -37,6 +37,8 @@ #include "llviewertexture.h" #include "llframetimer.h" #include "llapr.h" +#include "m3math.h" // LLMatrix3 +#include "m4math.h" // LLMatrix4 #include class LLViewerTextureAnim; diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 77ca7e54b..6028f4d80 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -56,6 +56,7 @@ #include "llviewerwindow.h" #include "lldrawpoolwater.h" #include "llagent.h" +#include "llagentcamera.h" #include "llviewerregion.h" #include "llwlparammanager.h" @@ -428,7 +429,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/llwearable.cpp b/indra/newview/llwearable.cpp index e85726166..72deff26d 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -39,6 +39,8 @@ #include "llquantize.h" #include "llagent.h" +#include "llagentcamera.h" +#include "llagentwearables.h" #include "llassetuploadresponders.h" #include "llviewerwindow.h" #include "llfloatercustomize.h" @@ -781,7 +783,7 @@ void LLWearable::writeToAvatar( BOOL set_by_user ) if( gFloaterCustomize ) { LLViewerInventoryItem* item; - item = (LLViewerInventoryItem*)gInventory.getItem(gAgent.getWearableItem(mType)); + item = (LLViewerInventoryItem*)gInventory.getItem(gAgentWearables.getWearableItemID(mType)); U32 perm_mask = PERM_NONE; BOOL is_complete = FALSE; if(item) diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index b56260403..c6ec2047a 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -49,6 +49,7 @@ #include "llregionflags.h" #include "hippogridmanager.h" bool LLWorldMap::sGotMapURL = false; +const F32 AGENTS_UPDATE_TIMER = 60.0; // Seconds between 2 agent requests for a region const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // 10 minutes // For DEV-17507, do lazy image loading in llworldmapview.cpp instead, @@ -73,8 +74,8 @@ LLItemInfo::LLItemInfo(F32 global_x, F32 global_y, mRegionHandle = to_region_handle(mPosGlobal); } -LLSimInfo::LLSimInfo() -: mHandle(0), +LLSimInfo::LLSimInfo(U64 handle) +: mHandle(handle), mName(), mAgentsUpdateTime(0), mShowAgentLocations(FALSE), @@ -86,12 +87,8 @@ LLSimInfo::LLSimInfo() } -LLVector3d LLSimInfo::getGlobalOrigin() const -{ - return from_region_handle(mHandle); -} -LLVector3d LLSimInfo::getGlobalPos(LLVector3 local_pos) const +LLVector3d LLSimInfo::getGlobalPos(const LLVector3& local_pos) const { LLVector3d pos = from_region_handle(mHandle); pos.mdV[VX] += local_pos.mV[VX]; @@ -100,6 +97,47 @@ LLVector3d LLSimInfo::getGlobalPos(LLVector3 local_pos) const return pos; } +LLVector3d LLSimInfo::getGlobalOrigin() const +{ + return from_region_handle(mHandle); +} +LLVector3 LLSimInfo::getLocalPos(LLVector3d global_pos) const +{ + LLVector3d sim_origin = from_region_handle(mHandle); + return LLVector3(global_pos - sim_origin); +} + +void LLSimInfo::clearImage() +{ + if (!mOverlayImage.isNull()) + { + mOverlayImage->setBoostLevel(0); + mOverlayImage = NULL; + } +} + +void LLSimInfo::dropImagePriority() +{ + if (!mOverlayImage.isNull()) + { + mOverlayImage->setBoostLevel(0); + } +} + +// Update the agent count for that region +void LLSimInfo::updateAgentCount(F64 time) +{ + if ((time - mAgentsUpdateTime > AGENTS_UPDATE_TIMER) || mFirstAgentRequest) + { + LLWorldMap::getInstance()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, mHandle); + mAgentsUpdateTime = time; + mFirstAgentRequest = false; + } +} +bool LLSimInfo::isName(const std::string& name) const +{ + return (LLStringUtil::compareInsensitive(name, mName) == 0); +} //--------------------------------------------------------------------------- // World Map @@ -203,20 +241,23 @@ void LLWorldMap::eraseItems() void LLWorldMap::clearImageRefs() { + // We clear the reference to the images we're holding. + // Images hold by the world mipmap first mWorldMipmap.reset(); + // Images hold by the region map + LLSimInfo* sim_info = NULL; for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) { - LLSimInfo* info = (*it).second; - if (info->mCurrentImage) + sim_info = it->second; + if(sim_info) { - info->mCurrentImage->setBoostLevel(0); - info->mCurrentImage = NULL; - } - if (info->mOverlayImage) - { - info->mOverlayImage->setBoostLevel(0); - info->mOverlayImage = NULL; + if (sim_info->mCurrentImage) + { + sim_info->mCurrentImage->setBoostLevel(0); + sim_info->mCurrentImage = NULL; + } + sim_info->clearImage(); } } } @@ -233,6 +274,13 @@ void LLWorldMap::clearSimFlags() } } +LLSimInfo* LLWorldMap::createSimInfoFromHandle(const U64 handle) +{ + LLSimInfo* sim_info = new LLSimInfo(handle); + mSimInfoMap[handle] = sim_info; + return sim_info; +} + void LLWorldMap::equalizeBoostLevels() { mWorldMipmap.equalizeBoostLevels(); @@ -250,11 +298,7 @@ LLSimInfo* LLWorldMap::simInfoFromHandle(const U64 handle) sim_info_map_t::iterator it = mSimInfoMap.find(handle); if (it != mSimInfoMap.end()) { - LLSimInfo* sim_info = (*it).second; - if (sim_info) - { - return sim_info; - } + return it->second; } return NULL; } @@ -265,39 +309,38 @@ LLSimInfo* LLWorldMap::simInfoFromName(const std::string& sim_name) LLSimInfo* sim_info = NULL; if (!sim_name.empty()) { - for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + // Iterate through the entire sim info map and compare the name + sim_info_map_t::iterator it; + for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) { - sim_info = (*it).second; - if (sim_info - && (0 == LLStringUtil::compareInsensitive(sim_name, sim_info->mName)) ) + sim_info = it->second; + if (sim_info && sim_info->isName(sim_name) ) { + // break out of loop if success break; } - sim_info = NULL; } + // If we got to the end, we haven't found the sim. Reset the ouput value to NULL. + if (it == mSimInfoMap.end()) + sim_info = NULL; } return sim_info; } bool LLWorldMap::simNameFromPosGlobal(const LLVector3d& pos_global, std::string & outSimName ) { - bool gotSimName = true; + LLSimInfo* sim_info = simInfoFromPosGlobal(pos_global); - U64 handle = to_region_handle(pos_global); - - sim_info_map_t::iterator it = mSimInfoMap.find(handle); - if (it != mSimInfoMap.end()) + if (sim_info) { - LLSimInfo* info = (*it).second; - outSimName = info->mName; + outSimName = sim_info->getName(); } else { - gotSimName = false; outSimName = "(unknown region)"; } - return gotSimName; + return (sim_info != NULL); } void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer) @@ -657,28 +700,20 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) y_meters, x_meters+REGION_WIDTH_UNITS, y_meters+REGION_WIDTH_UNITS) || adjust; - -// llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl; - - LLSimInfo* siminfo = new LLSimInfo(); - sim_info_map_t::iterator iter = LLWorldMap::getInstance()->mSimInfoMap.find(handle); - if (iter != LLWorldMap::getInstance()->mSimInfoMap.end()) + //LL_INFOS("World Map") << "Map sim : " << name << ", ID : " << image_id.getString() << LL_ENDL; + // Insert the region in the region map of the world map + // Loading the LLSimInfo object with what we got and insert it in the map + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); + if (siminfo == NULL) { - LLSimInfo* oldinfo = iter->second; - for (S32 image=0; imagemMapImageID[image] = oldinfo->mMapImageID[image]; - } - delete oldinfo; + siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); } - LLWorldMap::getInstance()->mSimInfoMap[handle] = siminfo; - siminfo->mHandle = handle; - siminfo->mName.assign( name ); - siminfo->mAccess = accesscode; - siminfo->mRegionFlags = region_flags; - siminfo->mWaterHeight = (F32) water_height; - siminfo->mMapImageID[agent_flags] = image_id; + siminfo->setName( name ); + siminfo->setAccess( accesscode ); + siminfo->setRegionFlags( region_flags ); + siminfo->setWaterHeight((F32) water_height); + siminfo->setMapImageID( image_id, agent_flags ); #ifdef IMMEDIATE_IMAGE_LOAD if (use_web_map_tiles) @@ -710,7 +745,7 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) { - if (siminfo->mAccess == SIM_ACCESS_DOWN) + if (siminfo->isDown()) { // We were tracking this location, but it doesn't exist LLWorldMap::getInstance()->mInvalidLocation = true; @@ -744,12 +779,11 @@ void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) callback(handle, LLWorldMap::getInstance()->mSLURL, image_id, LLWorldMap::getInstance()->mSLURLTeleport); } } - if(LLAgent::lure_show) + if( gAgent.mPendingLure && + (U16)(gAgent.mPendingLure->mPosGlobal.mdV[0] / REGION_WIDTH_UNITS) == x_regions && + (U16)(gAgent.mPendingLure->mPosGlobal.mdV[1] / REGION_WIDTH_UNITS) == y_regions ) { - if((x_regions == LLAgent::lure_global_x) && (y_regions == LLAgent::lure_global_y)) - { - gAgent.onFoundLureDestination(); - } + gAgent.onFoundLureDestination(); } } @@ -784,7 +818,7 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) Y /= REGION_WIDTH_UNITS; LLItemInfo new_item(world_x, world_y, name, uuid, extra, extra2); - LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(new_item.mRegionHandle); + LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(new_item.getRegionHandle()); switch (type) { @@ -827,13 +861,13 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) S32 display_hour = timep->tm_hour % 12; if (display_hour == 0) display_hour = 12; - new_item.mToolTip = llformat( "%d:%02d %s", + new_item.setTooltip( llformat( "%d:%02d %s", display_hour, timep->tm_min, - (timep->tm_hour < 12 ? "AM" : "PM") ); + (timep->tm_hour < 12 ? "AM" : "PM") ) ); // HACK: store Z in extra2 - new_item.mPosGlobal.mdV[VZ] = (F64)extra2; + new_item.setElevation((F64)extra2); if (type == MAP_ITEM_PG_EVENT) { LLWorldMap::getInstance()->mPGEvents.push_back(new_item); @@ -852,9 +886,9 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) case MAP_ITEM_LAND_FOR_SALE: // land for sale case MAP_ITEM_LAND_FOR_SALE_ADULT: // adult land for sale { - new_item.mToolTip = llformat("%d sq. m. %s%d", new_item.mExtra, + new_item.setTooltip(llformat("%d sq. m. %s%d", new_item.mExtra, gHippoGridManager->getConnectedGrid()->getCurrencySymbol().c_str(), - new_item.mExtra2); + new_item.mExtra2)); if (type == MAP_ITEM_LAND_FOR_SALE) { LLWorldMap::getInstance()->mLandForSale.push_back(new_item); @@ -874,19 +908,19 @@ void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) { if (!siminfo) { - llinfos << "siminfo missing for " << new_item.mPosGlobal.mdV[0] << ", " << new_item.mPosGlobal.mdV[1] << llendl; + llinfos << "siminfo missing for " << new_item.getGlobalPosition().mdV[0] << ", " << new_item.getGlobalPosition().mdV[1] << llendl; break; } // llinfos << "New Location " << new_item.mName << llendl; - item_info_list_t& agentcounts = LLWorldMap::getInstance()->mAgentLocationsMap[new_item.mRegionHandle]; + item_info_list_t& agentcounts = LLWorldMap::getInstance()->mAgentLocationsMap[new_item.getRegionHandle()]; // Find the last item in the list with a different name and erase them item_info_list_t::iterator lastiter; for (lastiter = agentcounts.begin(); lastiter!=agentcounts.end(); ++lastiter) { const LLItemInfo& info = *lastiter; - if (info.mName == new_item.mName) + if (info.isName(new_item.getName())) { break; } @@ -919,10 +953,10 @@ void LLWorldMap::dump() from_region_handle(handle, &x_pos, &y_pos); llinfos << x_pos << "," << y_pos - << " " << info->mName - << " " << (S32)info->mAccess - << " " << std::hex << info->mRegionFlags << std::dec - << " " << info->mWaterHeight + << " " << info->getName() + << " " << (S32)info->getAccess() + << " " << std::hex << info->getRegionFlags() << std::dec + << " " << info->getWaterHeight() //<< " " << info->mTelehubName //<< " " << info->mTelehubPosition << llendl; @@ -1089,9 +1123,6 @@ void LLWorldMap::dropImagePriorities() for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) { LLSimInfo* info = it->second; - if (!info->mOverlayImage.isNull()) - { - info->mOverlayImage->setBoostLevel(0); - } + info->dropImagePriority(); } } diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index a8d9c748e..c87b514ad 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -44,6 +44,7 @@ #include "llworldmipmap.h" #include "lluuid.h" #include "llmemory.h" +#include "llviewerregion.h" #include "llviewertexture.h" #include "lleventinfo.h" #include "v3color.h" @@ -56,14 +57,26 @@ class LLItemInfo public: LLItemInfo(F32 global_x, F32 global_y, const std::string& name, LLUUID id, S32 extra = 0, S32 extra2 = 0); + // Setters + void setTooltip(const std::string& tooltip) { mToolTip = tooltip; } + void setElevation(F64 z) { mPosGlobal.mdV[VZ] = z; } + // Accessors + const LLVector3d& getGlobalPosition() const { return mPosGlobal; } + const std::string& getName() const { return mName; } + const std::string& getToolTip() const { return mToolTip; } + const LLUUID& getUUID() const { return mID; } + U64 getRegionHandle() const { return mRegionHandle; } + bool isName(const std::string& name) const { return (mName == name); } // True if name same as item's name +private: std::string mName; std::string mToolTip; LLVector3d mPosGlobal; LLUUID mID; + U64 mRegionHandle; +public: //public for now.. non-standard. BOOL mSelected; S32 mExtra; S32 mExtra2; - U64 mRegionHandle; }; #define MAP_SIM_IMAGE_TYPES 3 @@ -74,25 +87,55 @@ public: class LLSimInfo { public: - LLSimInfo(); + LLSimInfo(U64 handle); - LLVector3d getGlobalPos(LLVector3 local_pos) const; + // Convert local region coordinates into world coordinates + LLVector3d getGlobalPos(const LLVector3& local_pos) const; // Get the world coordinates of the SW corner of that region LLVector3d getGlobalOrigin() const; + LLVector3 getLocalPos(LLVector3d global_pos) const; -public: + void clearImage(); // Clears the reference to the Land for sale image for that region + void dropImagePriority(); // Drops the boost level of the Land for sale image for that region + void updateAgentCount(F64 time); // Send an item request for agent count on that region if time's up + // Setters + void setName(std::string& name) { mName = name; } + void setAccess (U8 accesscode) { mAccess = accesscode; } + void setRegionFlags (U32 region_flags) { mRegionFlags = region_flags; } + void setWaterHeight (F32 water_height) { mWaterHeight = water_height; } + void setAlpha(F32 alpha) { mAlpha = alpha; } + + void setMapImageID (const LLUUID& id, const U8 &layer) { mMapImageID[layer] = id; } + + // Accessors + std::string getName() const { return mName; } + const std::string getFlagsString() const { return LLViewerRegion::regionFlagsToString(mRegionFlags); } + const U32 getRegionFlags() const { return mRegionFlags; } + const std::string getAccessString() const { return LLViewerRegion::accessToString((U8)mAccess); } + const U8 getAccess() const { return mAccess; } + + const F32 getWaterHeight() const { return mWaterHeight; } + const F32 getAlpha() const { return mAlpha; } + const U64 getHandle() const { return mHandle; } + bool isName(const std::string& name) const; + bool isDown() { return (mAccess == SIM_ACCESS_DOWN); } + bool isPG() { return (mAccess <= SIM_ACCESS_PG); } + bool isAdult() { return (mAccess == SIM_ACCESS_ADULT); } +private: U64 mHandle; std::string mName; - F64 mAgentsUpdateTime; - BOOL mShowAgentLocations; // are agents visible? - + F64 mAgentsUpdateTime; // Time stamp giving the last time the agents information was requested for that region + bool mFirstAgentRequest; // Init agent request flag U8 mAccess; U32 mRegionFlags; F32 mWaterHeight; F32 mAlpha; +public: + BOOL mShowAgentLocations; // are agents visible? + // Image ID for the current overlay mode. LLUUID mMapImageID[MAP_SIM_IMAGE_TYPES]; @@ -116,6 +159,7 @@ struct LLWorldMapLayer class LLWorldMap : public LLSingleton { + friend class LLMapLayerResponder; public: typedef void(*url_callback_t)(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport); @@ -138,6 +182,9 @@ public: // Drops the priority of the images being fetched void dropImagePriorities(); + // Region Map access + typedef std::map sim_info_map_t; + const LLWorldMap::sim_info_map_t& getRegionMap() const { return mSimInfoMap; } // Returns simulator information, or NULL if out of range LLSimInfo* simInfoFromHandle(const U64 handle); @@ -195,11 +242,14 @@ public: private: bool clearItems(bool force = false); // Clears the item lists -public: + // Create a region record corresponding to the handle, insert it in the region map and returns a pointer + LLSimInfo* createSimInfoFromHandle(const U64 handle); + // Map from region-handle to simulator info - typedef std::map sim_info_map_t; sim_info_map_t mSimInfoMap; +public: + BOOL mIsTrackingUnknownLocation, mInvalidLocation, mIsTrackingDoubleClick, mIsTrackingCommit; LLVector3d mUnknownLocation; diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 4a90e66f2..d4c9c7f66 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -42,6 +42,7 @@ #include "llrender.h" #include "llagent.h" +#include "llagentcamera.h" #include "llcallingcard.h" #include "llcolorscheme.h" #include "llviewercontrol.h" @@ -126,10 +127,6 @@ std::map LLWorldMapView::sStringsMap; #define SIM_MAP_AGENT_SCALE 8 // width in pixels, where we start drawing agents #define SIM_MAP_SCALE 4 // width in pixels, where we start drawing sim tiles -// Updates for agent locations. -#define AGENTS_UPDATE_TIME 60.0 // in seconds - - void LLWorldMapView::initClass() { @@ -260,7 +257,7 @@ void LLWorldMapView::setScale( F32 scale ) F32 old_scale = sMapScale; sMapScale = scale; - if (sMapScale == 0.f) + if (sMapScale <= 0.f) { sMapScale = 0.1f; } @@ -307,7 +304,7 @@ void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) BOOL is_agent_in_region(LLViewerRegion* region, LLSimInfo* info) { - return ((region && info) && (info->mName == region->getName())); + return ((region && info) && (info->isName(region->getName()))); } @@ -327,7 +324,9 @@ void LLWorldMapView::draw() const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); - LLVector3d camera_global = gAgent.getCameraPositionGlobal(); + const F32 half_width = F32(width) / 2.0f; + const F32 half_height = F32(height) / 2.0f; + LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); LLLocalClipRect clip(getLocalRect()); { @@ -345,6 +344,7 @@ void LLWorldMapView::draw() } gGL.flush(); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setColorMask(true, true); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -353,17 +353,15 @@ void LLWorldMapView::draw() drawMipmap(width, height); else drawTiles(width, height); - + gGL.flush(); LLFontGL* font = LLFontGL::getFontSansSerifSmall(); - const F32 half_width = F32(width) / 2.0f; - const F32 half_height = F32(height) / 2.0f; // Draw the region name in the lower left corner - for (LLWorldMap::sim_info_map_t::iterator it = LLWorldMap::getInstance()->mSimInfoMap.begin(); - it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) + for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); + it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) { U64 handle = it->first; - LLSimInfo* info = (*it).second; + LLSimInfo* info = it->second; LLVector3d origin_global = from_region_handle(handle); @@ -371,29 +369,26 @@ void LLWorldMapView::draw() LLVector3d rel_region_pos = origin_global - camera_global; F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; - - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; - F32 top = bottom + sMapScale ; - F32 right = left + sMapScale ; - - // disregard regions that are outside the rectangle - if (top < 0.f || - bottom > height || - right < 0.f || - left > width ) + + // Coordinates of the sim in pixels in the UI panel + // When the view isn't panned, 0,0 = center of rectangle + F32 bottom = sPanY + half_height + relative_y; + F32 left = sPanX + half_width + relative_x; + F32 top = bottom + sMapScale ; + F32 right = left + sMapScale ; + + // Discard if region is outside the screen rectangle (not visible on screen) + if ((top < 0.f) || (bottom > height) || + (right < 0.f) || (left > width) ) { + // Drop the "land for sale" fetching priority since it's outside the view rectangle + info->dropImagePriority(); continue; } info->mShowAgentLocations = (sMapScale >= SIM_MAP_AGENT_SCALE); mVisibleRegions.push_back(handle); - // See if the agents need updating - if (current_time - info->mAgentsUpdateTime > AGENTS_UPDATE_TIME) - { - LLWorldMap::getInstance()->sendItemRequest(MAP_ITEM_AGENT_LOCATIONS, info->mHandle); - info->mAgentsUpdateTime = current_time; - } + info->updateAgentCount(current_time); std::string mesg; if (sMapScale < sThresholdA) @@ -415,14 +410,14 @@ void LLWorldMapView::draw() mesg = RlvStrings::getString(RLV_STRING_HIDDEN); } // [/RLVa:KB] - else if (info->mAccess == SIM_ACCESS_DOWN) + else if (info->isDown()) { - mesg = llformat( "%s (%s)", info->mName.c_str(), sStringsMap["offline"].c_str()); + mesg = llformat( "%s (%s)", info->getName().c_str(), sStringsMap["offline"].c_str()); } else { - mesg = info->mName; - U8 access = info->mAccess; + mesg = info->getName(); + U8 access = info->getAccess(); switch(access) { case SIM_ACCESS_MIN: @@ -614,8 +609,8 @@ void LLWorldMapView::setVisible(BOOL visible) } } } - for (LLWorldMap::sim_info_map_t::iterator it = LLWorldMap::getInstance()->mSimInfoMap.begin(); - it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) + for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); + it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) { LLSimInfo* info = (*it).second; if (info->mCurrentImage.notNull()) @@ -634,7 +629,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { const F32 half_width = F32(width) / 2.0f; const F32 half_height = F32(height) / 2.0f; F32 layer_alpha = 1.f; - LLVector3d camera_global = gAgent.getCameraPositionGlobal(); + LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); // Draw one image per layer for (U32 layer_idx=0; layer_idxmMapLayers[LLWorldMap::getInstance()->mCurrentMap].size(); ++layer_idx) @@ -741,8 +736,8 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { bool use_web_map_tiles = LLWorldMap::useWebMapTiles(); - for (LLWorldMap::sim_info_map_t::iterator it = LLWorldMap::getInstance()->mSimInfoMap.begin(); - it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) + for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin(); + it != LLWorldMap::getInstance()->getRegionMap().end(); ++it) { U64 handle = (*it).first; LLSimInfo* info = (*it).second; @@ -758,7 +753,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { } LLVector3d origin_global = from_region_handle(handle); - LLVector3d camera_global = gAgent.getCameraPositionGlobal(); + LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); // Find x and y position relative to camera's center. LLVector3d rel_region_pos = origin_global - camera_global; @@ -775,7 +770,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { // 1. Tiles are zoomed out small enough, or // 2. Sim's texture has not been loaded yet F32 map_scale_cutoff = SIM_MAP_SCALE; - if ((info->mRegionFlags & REGION_FLAGS_NULL_LAYER) > 0) + if ((info->getRegionFlags() & REGION_FLAGS_NULL_LAYER) > 0) { map_scale_cutoff = SIM_NULL_MAP_SCALE; } @@ -788,18 +783,18 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { if (sim_visible) { // Fade in - if (info->mAlpha < 0.0f) - info->mAlpha = 1.f; // don't fade initially + if (info->getAlpha() < 0.0f) + info->setAlpha( 1.f ); // don't fade initially else - info->mAlpha = lerp(info->mAlpha, 1.f, LLCriticalDamp::getInterpolant(0.15f)); + info->setAlpha(lerp(info->getAlpha(), 1.f, LLCriticalDamp::getInterpolant(0.15f))); } else { // Fade out - if (info->mAlpha < 0.0f) - info->mAlpha = 0.f; // don't fade initially + if (info->getAlpha() < 0.0f) + info->setAlpha( 0.f ); // don't fade initially else - info->mAlpha = lerp(info->mAlpha, 0.f, LLCriticalDamp::getInterpolant(0.15f)); + info->setAlpha(lerp(info->getAlpha(), 0.f, LLCriticalDamp::getInterpolant(0.15f))); } // discard regions that are outside the rectangle @@ -869,7 +864,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { // LLTextureView::addDebugImage(simimage); - if (sim_visible && info->mAlpha > 0.001f) + if (sim_visible && info->getAlpha() > 0.001f) { // Draw using the texture. If we don't clamp we get artifact at // the edge. @@ -878,7 +873,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.getTexUnit(0)->bind(simimage); gGL.setSceneBlendType(LLRender::BT_ALPHA); - F32 alpha = sim_alpha * info->mAlpha; + F32 alpha = sim_alpha * info->getAlpha(); gGL.color4f(1.f, 1.0f, 1.0f, alpha); gGL.begin(LLRender::QUADS); @@ -908,7 +903,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { gGL.end(); } - if ((info->mRegionFlags & REGION_FLAGS_NULL_LAYER) == 0) + if ((info->getRegionFlags() & REGION_FLAGS_NULL_LAYER) == 0) { // draw an alpha of 1 where the sims are visible (except NULL sims) gGL.flush(); @@ -929,7 +924,7 @@ void LLWorldMapView::drawTiles(S32 width, S32 height) { } } - if (info->mAccess == SIM_ACCESS_DOWN) + if (info->isDown()) { // Draw a transparent red square over down sims gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA); @@ -979,7 +974,7 @@ void LLWorldMapView::drawGenericItems(const LLWorldMap::item_info_list_t& items, void LLWorldMapView::drawGenericItem(const LLItemInfo& item, LLUIImagePtr image) { - drawImage(item.mPosGlobal, image); + drawImage(item.getGlobalPosition(), image); } @@ -1017,7 +1012,7 @@ void LLWorldMapView::drawAgents() { U64 handle = *iter; LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); - if (siminfo && (siminfo->mAccess == SIM_ACCESS_DOWN)) + if (siminfo && (siminfo->isDown())) { continue; } @@ -1035,7 +1030,7 @@ void LLWorldMapView::drawAgents() sim_agent_count += info.mExtra; // Here's how we'd choose the color if info.mID were available but it's not being sent: //LLColor4 color = (agent_count == 1 && is_agent_friend(info.mID)) ? friend_color : avatar_color; - drawImageStack(info.mPosGlobal, sAvatarSmallImage, agent_count, 3.f, avatar_color); + drawImageStack(info.getGlobalPosition(), sAvatarSmallImage, agent_count, 3.f, avatar_color); } LLWorldMap::getInstance()->mNumAgents[handle] = sim_agent_count; // override mNumAgents for this sim } @@ -1304,7 +1299,7 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load 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 @@ -1400,7 +1395,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. @@ -1426,14 +1421,14 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic // std::string message = llformat("%s (%s)", info->getName().c_str(), info->getAccessString().c_str()); // [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Checked: 2009-07-04 (RLVa-1.0.0a) std::string message = llformat("%s (%s)", - (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? info->mName.c_str() : RlvStrings::getString(RLV_STRING_HIDDEN).c_str(), - LLViewerRegion::accessToString(info->mAccess).c_str()); + (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) ? info->getName().c_str() : RlvStrings::getString(RLV_STRING_HIDDEN).c_str(), + info->getAccessString().c_str()); // [/RLVa:KB] - if (info->mAccess != SIM_ACCESS_DOWN) + if (!info->isDown()) { - S32 agent_count = LLWorldMap::getInstance()->mNumAgents[info->mHandle]; - if (region && region->getHandle() == info->mHandle) + S32 agent_count = LLWorldMap::getInstance()->mNumAgents[info->getHandle()]; + if (region && region->getHandle() == info->getHandle()) { ++agent_count; // Bump by 1 if we're here } @@ -1457,7 +1452,7 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic msg.assign( message ); // Optionally show region flags - std::string region_flags = LLViewerRegion::regionFlagsToString(info->mRegionFlags); + std::string region_flags = info->getFlagsString(); if (!region_flags.empty()) { @@ -1807,7 +1802,7 @@ void LLWorldMapView::reshape( S32 width, S32 height, BOOL called_from_parent ) bool LLWorldMapView::checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track) { - LLVector3 pos_view = globalPosToView(item.mPosGlobal); + LLVector3 pos_view = globalPosToView(item.getGlobalPosition()); S32 item_x = llround(pos_view.mV[VX]); S32 item_y = llround(pos_view.mV[VY]); @@ -1816,12 +1811,12 @@ bool LLWorldMapView::checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bo if (y < item_y - BIG_DOT_RADIUS) return false; if (y > item_y + BIG_DOT_RADIUS) return false; - LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromHandle(item.mRegionHandle); + LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromHandle(item.getRegionHandle()); if (sim_info) { if (track) { - gFloaterWorldMap->trackLocation(item.mPosGlobal); + gFloaterWorldMap->trackLocation(item.getGlobalPosition()); } } @@ -1831,7 +1826,7 @@ bool LLWorldMapView::checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bo } item.mSelected = TRUE; - *id = item.mID; + *id = item.getUUID(); return true; } @@ -2038,7 +2033,7 @@ U32 LLWorldMapView::updateVisibleBlocks() return 0; } - LLVector3d camera_global = gAgent.getCameraPositionGlobal(); + LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); F32 pixels_per_region = sMapScale; const S32 width = getRect().getWidth(); @@ -2166,7 +2161,7 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) // Teleport if we got a valid location LLVector3d pos_global = viewPosToGlobal(x,y); LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); - if (sim_info && sim_info->mAccess != SIM_ACCESS_DOWN) + if (sim_info && !sim_info->isDown()) { gAgent.teleportViaLocation( pos_global ); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f67a72a7d..9ccc3f69f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -55,6 +55,7 @@ // newview includes #include "llagent.h" +#include "llagentcamera.h" #include "lldrawable.h" #include "lldrawpoolalpha.h" #include "lldrawpoolavatar.h" @@ -928,6 +929,8 @@ void LLPipeline::restoreGL() } } } + + resetLocalLights(); //Default all gl light parameters. Fixes light brightness problems on fullscren toggle } @@ -4678,6 +4681,29 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ return dist; } +//Default all gl light parameters. Used upon restoreGL. Fixes brightness problems on fullscren toggle +void LLPipeline::resetLocalLights() +{ + glEnable(GL_LIGHTING); + for (S32 i = 0; i < 8; ++i) + { + LLLightState *pLight = gGL.getLight(i); + pLight->enable(); + pLight->setAmbient(LLColor4::black); + pLight->setConstantAttenuation(0.f); + pLight->setDiffuse(LLColor4::black); + pLight->setLinearAttenuation(0.f); + pLight->setPosition(LLVector4(0.f,0.f,0.f,0.f)); + pLight->setQuadraticAttenuation(0.f); + pLight->setSpecular(LLColor4::black); + pLight->setSpotCutoff(0.f); + pLight->setSpotDirection(LLVector3(0.f,0.f,0.f)); + pLight->setSpotExponent(0.f); + pLight->disable(); + } + glDisable(GL_LIGHTING); +} + void LLPipeline::calcNearbyLights(LLCamera& camera) { assertInitialized(); @@ -4692,7 +4718,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(); @@ -4711,6 +4737,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) LLVOVolume* volight = drawable->getVOVolume(); if (!volight || !drawable->isState(LLDrawable::LIGHT)) { + setLight(drawable,false); //remove from mLight list drawable->clearState(LLDrawable::NEARBY_LIGHT); continue; } @@ -6172,7 +6199,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b { //focus on point under cursor focus_point = gDebugRaycastIntersection; } - else if (gAgent.cameraMouselook()) + else if (gAgentCamera.cameraMouselook()) { //focus on point under mouselook crosshairs gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, NULL, @@ -6180,10 +6207,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b } else { - LLViewerObject* obj = gAgent.getFocusObject(); + LLViewerObject* obj = gAgentCamera.getFocusObject(); if (obj) { //focus on alt-zoom target - focus_point = LLVector3(gAgent.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); } else { //focus on your avatar @@ -7711,7 +7738,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) { LLVOAvatar* agent = gAgent.getAvatarObject(); - if (!isAgentAvatarValid() || gAgent.getCameraAnimating() || gAgent.getCameraMode() != CAMERA_MODE_MOUSELOOK) + if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) { agent = NULL; } @@ -7946,7 +7973,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (agent) { - agent->updateAttachmentVisibility(gAgent.getCameraMode()); + agent->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; @@ -8545,7 +8572,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //put together a universal "near clip" plane for shadow frusta /*LLPlane shadow_near_clip; { - LLVector3 p = gAgent.getCameraPositionAgent();//gAgent.getPositionAgent(); + LLVector3 p = gAgentCamera.getCameraPositionAgent();//gAgent.getPositionAgent(); p += mSunDir * gSavedSettings.getF32("RenderFarClip")*2.f; shadow_near_clip.setVec(p, mSunDir); }*/ diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 56720d027..4145a9476 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -242,6 +242,7 @@ public: S32 getLightCount() const { return mLights.size(); } + void resetLocalLights(); //Default all gl light parameters. Used upon restoreGL. Fixes light brightness problems on fullscren toggle void calcNearbyLights(LLCamera& camera); void setupHWLights(LLDrawPool* pool); void setupAvatarLights(BOOL for_edit = FALSE); diff --git a/indra/newview/qtoolalign.cpp b/indra/newview/qtoolalign.cpp index b40faef40..2eae65ec5 100644 --- a/indra/newview/qtoolalign.cpp +++ b/indra/newview/qtoolalign.cpp @@ -14,6 +14,7 @@ // Viewer includes #include "llagent.h" +#include "llagentcamera.h" #include "llbox.h" #include "llcylinder.h" #include "llfloatertools.h" @@ -163,7 +164,7 @@ BOOL QToolAlign::findSelectedManipulator(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); @@ -322,11 +323,11 @@ void QToolAlign::computeManipulatorSize() if (LLSelectMgr::getInstance()->getSelection()->getSelectType() == SELECT_TYPE_HUD) { mManipulatorSize = MANIPULATOR_SIZE / (LLViewerCamera::getInstance()->getViewHeightInPixels() * - gAgent.mHUDCurZoom); + gAgentCamera.mHUDCurZoom); } else { - F32 distance = dist_vec(gAgent.getCameraPositionAgent(), mBBox.getCenterAgent()); + F32 distance = dist_vec(gAgentCamera.getCameraPositionAgent(), mBBox.getCenterAgent()); if (distance > 0.001f) { diff --git a/indra/newview/rlvextensions.cpp b/indra/newview/rlvextensions.cpp index 5d8fdb5e5..cc3fc6bc5 100644 --- a/indra/newview/rlvextensions.cpp +++ b/indra/newview/rlvextensions.cpp @@ -16,6 +16,7 @@ #include "llviewerprecompiledheaders.h" #include "llagent.h" +#include "llagentcamera.h" #include "llfloaterwindlight.h" #include "llviewercontrol.h" #include "llviewerwindow.h" @@ -121,7 +122,7 @@ bool RlvExtGetSet::processCommand(const RlvCommand& rlvCmd, ERlvCmdRet& eRet) { nAngle = RLV_SETROT_OFFSET - nAngle; - gAgent.startCameraAnimation(); + gAgentCamera.startCameraAnimation(); LLVector3 at(LLVector3::x_axis); at.rotVec(nAngle, LLVector3::z_axis); diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 16c415f5c..eb9b26305 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -34,6 +34,8 @@ #include "llviewerobjectlist.h" #include "llviewerregion.h" #include "llviewerwindow.h" +#include "llagentcamera.h" +#include "llagentwearables.h" #include "rlvhandler.h" #include "rlvinventory.h" @@ -739,7 +741,7 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const LLUUID idCompositeItem; if ((type = LLWearable::typeNameToType(strComposite)) != WT_INVALID) { - idCompositeItem = gAgent.getWearableItem(type); + idCompositeItem = gAgentWearables.getWearableItemID(type); } else if ((idxAttachPt = getAttachPointIndex(strComposite, true)) != 0) { @@ -839,7 +841,7 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const LLViewerInventoryCategory* pFolder; if ( (!isWearable(wtType)) || ( (gAgent.getWearable(wtType)) && (!isRemovable(wtType)) ) || - ( (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) && + ( (gRlvHandler.getCompositeInfo(gAgentWearables.getWearableItemID(wtType), NULL, &pFolder)) && (pFolder->getUUID() != pItem->getParentUUID()) && (!gRlvHandler.canTakeOffComposite(pFolder)) ) ) { return false; @@ -1153,7 +1155,7 @@ ERlvCmdRet RlvHandler::processAddRemCommand(const RlvCommand& rlvCmd) // Get rid of the build floater if it's open [copy/paste from toggle_build_mode()] if (gFloaterTools->getVisible()) { - gAgent.resetView(FALSE); + gAgentCamera.resetView(FALSE); gFloaterTools->close(); gViewerWindow->showCursor(); } @@ -2002,7 +2004,7 @@ ERlvCmdRet RlvHandler::onGetOutfit(const RlvCommand& rlvCmd, std::string& strRep { // We never hide body parts, even if they're "locked" and we're hiding locked layers // (nor do we hide a layer if the issuing object is the only one that has this layer locked) - bool fWorn = (gAgent.getWearable(wtRlvTypes[idxType])) && + bool fWorn = (gAgentWearables.getWearable(wtRlvTypes[idxType])) && ( (!RlvSettings::getHideLockedLayers()) || (LLAssetType::AT_BODYPART == LLWearable::typeToAssetType(wtRlvTypes[idxType])) || (RlvForceWear::isForceRemovable(wtRlvTypes[idxType], true, rlvCmd.getObjectID())) ); @@ -2030,7 +2032,7 @@ ERlvCmdRet RlvHandler::onGetOutfitNames(const RlvCommand& rlvCmd, std::string& s switch (rlvCmd.getBehaviourType()) { case RLV_BHVR_GETOUTFITNAMES: // Every layer that's worn - fAdd = (gAgent.getWearable(wtType) != NULL); + fAdd = (gAgentWearables.getWearable(wtType) != NULL); break; /* case RLV_BHVR_GETADDOUTFITNAMES: // Every layer that can be worn on (but ignore any locks set by the issuer) diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index bd6989755..57f3037ee 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -28,6 +28,7 @@ #include "llvoavatar.h" #include "llwearablelist.h" #include "llwlparammanager.h" +#include "llagentwearables.h" #include "rlvhelper.h" #include "rlvinventory.h" @@ -211,7 +212,7 @@ RlvCommandOptionGetPath::RlvCommandOptionGetPath(const RlvCommand& rlvCmd) if (rlvCmdOption.isWearableType()) //