PageRenderTime 158ms CodeModel.GetById 69ms app.highlight 77ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llagent.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2290 lines | 1520 code | 359 blank | 411 comment | 278 complexity | bfe4cf9f8dd32ace522c7ee9a89474c4 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/** 
   2 * @file llagent.cpp
   3 * @brief LLAgent class implementation
   4 *
   5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28
  29#include "llagent.h" 
  30
  31#include "pipeline.h"
  32
  33#include "llagentaccess.h"
  34#include "llagentcamera.h"
  35#include "llagentlistener.h"
  36#include "llagentwearables.h"
  37#include "llagentui.h"
  38#include "llanimationstates.h"
  39#include "llcallingcard.h"
  40#include "llcapabilitylistener.h"
  41#include "llchannelmanager.h"
  42#include "llchicletbar.h"
  43#include "llconsole.h"
  44#include "llenvmanager.h"
  45#include "llfirstuse.h"
  46#include "llfloatercamera.h"
  47#include "llfloaterreg.h"
  48#include "llfloatertools.h"
  49#include "llgroupactions.h"
  50#include "llgroupmgr.h"
  51#include "llhomelocationresponder.h"
  52#include "llhudmanager.h"
  53#include "lljoystickbutton.h"
  54#include "llmorphview.h"
  55#include "llmoveview.h"
  56#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
  57#include "llnearbychatbar.h"
  58#include "llnotificationsutil.h"
  59#include "llpaneltopinfobar.h"
  60#include "llparcel.h"
  61#include "llrendersphere.h"
  62#include "llsdmessage.h"
  63#include "llsdutil.h"
  64#include "llsky.h"
  65#include "llslurl.h"
  66#include "llsmoothstep.h"
  67#include "llstartup.h"
  68#include "llstatusbar.h"
  69#include "llteleportflags.h"
  70#include "lltool.h"
  71#include "lltoolbarview.h"
  72#include "lltoolpie.h"
  73#include "lltoolmgr.h"
  74#include "lltrans.h"
  75#include "lluictrl.h"
  76#include "llurlentry.h"
  77#include "llviewercontrol.h"
  78#include "llviewerdisplay.h"
  79#include "llviewerjoystick.h"
  80#include "llviewermediafocus.h"
  81#include "llviewermenu.h"
  82#include "llviewerobjectlist.h"
  83#include "llviewerparcelmgr.h"
  84#include "llviewerstats.h"
  85#include "llviewerwindow.h"
  86#include "llvoavatarself.h"
  87#include "llwindow.h"
  88#include "llworld.h"
  89#include "llworldmap.h"
  90#include "stringize.h"
  91
  92using namespace LLVOAvatarDefines;
  93
  94extern LLMenuBarGL* gMenuBarView;
  95
  96const BOOL ANIMATE = TRUE;
  97const U8 AGENT_STATE_TYPING =	0x04;
  98const U8 AGENT_STATE_EDITING =  0x10;
  99
 100// Autopilot constants
 101const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f;			// meters
 102const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f;	// meters
 103const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f;		// seconds
 104
 105const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
 106const F64 CHAT_AGE_FAST_RATE = 3.0;
 107
 108// fidget constants
 109const F32 MIN_FIDGET_TIME = 8.f; // seconds
 110const F32 MAX_FIDGET_TIME = 20.f; // seconds
 111
 112// The agent instance.
 113LLAgent gAgent;
 114
 115//--------------------------------------------------------------------
 116// Statics
 117//
 118
 119/// minimum time after setting away state before coming back based on movement
 120const F32 LLAgent::MIN_AFK_TIME = 10.0f;
 121
 122const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;
 123
 124std::map<std::string, std::string> LLAgent::sTeleportErrorMessages;
 125std::map<std::string, std::string> LLAgent::sTeleportProgressMessages;
 126
 127class LLAgentFriendObserver : public LLFriendObserver
 128{
 129public:
 130	LLAgentFriendObserver() {}
 131	virtual ~LLAgentFriendObserver() {}
 132	virtual void changed(U32 mask);
 133};
 134
 135void LLAgentFriendObserver::changed(U32 mask)
 136{
 137	// if there's a change we're interested in.
 138	if((mask & (LLFriendObserver::POWERS)) != 0)
 139	{
 140		gAgent.friendsChanged();
 141	}
 142}
 143
 144bool handleSlowMotionAnimation(const LLSD& newvalue)
 145{
 146	if (newvalue.asBoolean())
 147	{
 148		gAgentAvatarp->setAnimTimeFactor(0.2f);
 149	}
 150	else
 151	{
 152		gAgentAvatarp->setAnimTimeFactor(1.0f);
 153	}
 154	return true;
 155}
 156
 157// static
 158void LLAgent::parcelChangedCallback()
 159{
 160	bool can_edit = LLToolMgr::getInstance()->canEdit();
 161
 162	gAgent.mCanEditParcel = can_edit;
 163}
 164
 165// static
 166bool LLAgent::isActionAllowed(const LLSD& sdname)
 167{
 168	bool retval = false;
 169
 170	const std::string& param = sdname.asString();
 171
 172	if (param == "build")
 173	{
 174		retval = gAgent.canEditParcel();
 175	}
 176	else if (param == "speak")
 177	{
 178		if ( gAgent.isVoiceConnected() && 
 179			LLViewerParcelMgr::getInstance()->allowAgentVoice() &&
 180				! LLVoiceClient::getInstance()->inTuningMode() )
 181		{
 182			retval = true;
 183		}
 184		else
 185		{
 186			retval = false;
 187		}
 188	}
 189
 190	return retval;
 191}
 192
 193// static 
 194void LLAgent::pressMicrophone(const LLSD& name)
 195{
 196	LLFirstUse::speak(false);
 197
 198	 LLVoiceClient::getInstance()->inputUserControlState(true);
 199}
 200
 201// static 
 202void LLAgent::releaseMicrophone(const LLSD& name)
 203{
 204	LLVoiceClient::getInstance()->inputUserControlState(false);
 205}
 206
 207// static
 208void LLAgent::toggleMicrophone(const LLSD& name)
 209{
 210	LLVoiceClient::getInstance()->toggleUserPTTState();
 211}
 212
 213// static
 214bool LLAgent::isMicrophoneOn(const LLSD& sdname)
 215{
 216	return LLVoiceClient::getInstance()->getUserPTTState();
 217}
 218
 219// ************************************************************
 220// Enabled this definition to compile a 'hacked' viewer that
 221// locally believes the end user has godlike powers.
 222// #define HACKED_GODLIKE_VIEWER
 223// For a toggled version, see viewer.h for the
 224// TOGGLE_HACKED_GODLIKE_VIEWER define, instead.
 225// ************************************************************
 226
 227// Constructors and Destructors
 228
 229// JC - Please try to make this order match the order in the header
 230// file.  Otherwise it's hard to find variables that aren't initialized.
 231//-----------------------------------------------------------------------------
 232// LLAgent()
 233//-----------------------------------------------------------------------------
 234LLAgent::LLAgent() :
 235	mGroupPowers(0),
 236	mHideGroupTitle(FALSE),
 237	mGroupID(),
 238
 239	mInitialized(FALSE),
 240	mListener(),
 241
 242	mDoubleTapRunTimer(),
 243	mDoubleTapRunMode(DOUBLETAP_NONE),
 244
 245	mbAlwaysRun(false),
 246	mbRunning(false),
 247	mbTeleportKeepsLookAt(false),
 248
 249	mAgentAccess(new LLAgentAccess(gSavedSettings)),
 250	mCanEditParcel(false),
 251	mTeleportSourceSLURL(new LLSLURL),
 252	mTeleportState( TELEPORT_NONE ),
 253	mRegionp(NULL),
 254
 255	mAgentOriginGlobal(),
 256	mPositionGlobal(),
 257
 258	mDistanceTraveled(0.F),
 259	mLastPositionGlobal(LLVector3d::zero),
 260
 261	mRenderState(0),
 262	mTypingTimer(),
 263
 264	mViewsPushed(FALSE),
 265
 266	mCustomAnim(FALSE),
 267	mShowAvatar(TRUE),
 268	mFrameAgent(),
 269
 270	mIsBusy(FALSE),
 271
 272	mControlFlags(0x00000000),
 273	mbFlagsDirty(FALSE),
 274	mbFlagsNeedReset(FALSE),
 275
 276	mAutoPilot(FALSE),
 277	mAutoPilotFlyOnStop(FALSE),
 278	mAutoPilotAllowFlying(TRUE),
 279	mAutoPilotTargetGlobal(),
 280	mAutoPilotStopDistance(1.f),
 281	mAutoPilotUseRotation(FALSE),
 282	mAutoPilotTargetFacing(LLVector3::zero),
 283	mAutoPilotTargetDist(0.f),
 284	mAutoPilotNoProgressFrameCount(0),
 285	mAutoPilotRotationThreshold(0.f),
 286	mAutoPilotFinishedCallback(NULL),
 287	mAutoPilotCallbackData(NULL),
 288	
 289	mEffectColor(new LLUIColor(LLColor4(0.f, 1.f, 1.f, 1.f))),
 290
 291	mHaveHomePosition(FALSE),
 292	mHomeRegionHandle( 0 ),
 293	mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f),
 294
 295	mNextFidgetTime(0.f),
 296	mCurrentFidget(0),
 297	mFirstLogin(FALSE),
 298	mGenderChosen(FALSE),
 299	
 300	mVoiceConnected(false),
 301
 302	mAppearanceSerialNum(0),
 303
 304	mMouselookModeInSignal(NULL),
 305	mMouselookModeOutSignal(NULL)
 306{
 307	for (U32 i = 0; i < TOTAL_CONTROLS; i++)
 308	{
 309		mControlsTakenCount[i] = 0;
 310		mControlsTakenPassedOnCount[i] = 0;
 311	}
 312
 313	mListener.reset(new LLAgentListener(*this));
 314
 315	mMoveTimer.stop();
 316}
 317
 318// Requires gSavedSettings to be initialized.
 319//-----------------------------------------------------------------------------
 320// init()
 321//-----------------------------------------------------------------------------
 322void LLAgent::init()
 323{
 324	mMoveTimer.start();
 325
 326	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE);
 327	gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
 328	
 329	// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
 330
 331	setFlying( gSavedSettings.getBOOL("FlyingAtExit") );
 332
 333	*mEffectColor = LLUIColorTable::instance().getColor("EffectColor");
 334
 335	gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));
 336	gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2));
 337
 338	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback));
 339
 340	mInitialized = TRUE;
 341}
 342
 343//-----------------------------------------------------------------------------
 344// cleanup()
 345//-----------------------------------------------------------------------------
 346void LLAgent::cleanup()
 347{
 348	mRegionp = NULL;
 349}
 350
 351//-----------------------------------------------------------------------------
 352// LLAgent()
 353//-----------------------------------------------------------------------------
 354LLAgent::~LLAgent()
 355{
 356	cleanup();
 357
 358	delete mMouselookModeInSignal;
 359	mMouselookModeInSignal = NULL;
 360	delete mMouselookModeOutSignal;
 361	mMouselookModeOutSignal = NULL;
 362
 363	delete mAgentAccess;
 364	mAgentAccess = NULL;
 365	delete mEffectColor;
 366	mEffectColor = NULL;
 367	delete mTeleportSourceSLURL;
 368	mTeleportSourceSLURL = NULL;
 369}
 370
 371// Handle any actions that need to be performed when the main app gains focus
 372// (such as through alt-tab).
 373//-----------------------------------------------------------------------------
 374// onAppFocusGained()
 375//-----------------------------------------------------------------------------
 376void LLAgent::onAppFocusGained()
 377{
 378	if (CAMERA_MODE_MOUSELOOK == gAgentCamera.getCameraMode())
 379	{
 380		gAgentCamera.changeCameraToDefault();
 381		LLToolMgr::getInstance()->clearSavedTool();
 382	}
 383}
 384
 385
 386void LLAgent::ageChat()
 387{
 388	if (isAgentAvatarValid())
 389	{
 390		// get amount of time since I last chatted
 391		F64 elapsed_time = (F64)gAgentAvatarp->mChatTimer.getElapsedTimeF32();
 392		// add in frame time * 3 (so it ages 4x)
 393		gAgentAvatarp->mChatTimer.setAge(elapsed_time + (F64)gFrameDTClamped * (CHAT_AGE_FAST_RATE - 1.0));
 394	}
 395}
 396
 397//-----------------------------------------------------------------------------
 398// moveAt()
 399//-----------------------------------------------------------------------------
 400void LLAgent::moveAt(S32 direction, bool reset)
 401{
 402	mMoveTimer.reset();
 403	LLFirstUse::notMoving(false);
 404
 405	// age chat timer so it fades more quickly when you are intentionally moving
 406	ageChat();
 407
 408	gAgentCamera.setAtKey(LLAgentCamera::directionToKey(direction));
 409
 410	if (direction > 0)
 411	{
 412		setControlFlags(AGENT_CONTROL_AT_POS | AGENT_CONTROL_FAST_AT);
 413	}
 414	else if (direction < 0)
 415	{
 416		setControlFlags(AGENT_CONTROL_AT_NEG | AGENT_CONTROL_FAST_AT);
 417	}
 418
 419	if (reset)
 420	{
 421		gAgentCamera.resetView();
 422	}
 423}
 424
 425//-----------------------------------------------------------------------------
 426// moveAtNudge()
 427//-----------------------------------------------------------------------------
 428void LLAgent::moveAtNudge(S32 direction)
 429{
 430	mMoveTimer.reset();
 431	LLFirstUse::notMoving(false);
 432
 433	// age chat timer so it fades more quickly when you are intentionally moving
 434	ageChat();
 435
 436	gAgentCamera.setWalkKey(LLAgentCamera::directionToKey(direction));
 437
 438	if (direction > 0)
 439	{
 440		setControlFlags(AGENT_CONTROL_NUDGE_AT_POS);
 441	}
 442	else if (direction < 0)
 443	{
 444		setControlFlags(AGENT_CONTROL_NUDGE_AT_NEG);
 445	}
 446
 447	gAgentCamera.resetView();
 448}
 449
 450//-----------------------------------------------------------------------------
 451// moveLeft()
 452//-----------------------------------------------------------------------------
 453void LLAgent::moveLeft(S32 direction)
 454{
 455	mMoveTimer.reset();
 456	LLFirstUse::notMoving(false);
 457
 458	// age chat timer so it fades more quickly when you are intentionally moving
 459	ageChat();
 460
 461	gAgentCamera.setLeftKey(LLAgentCamera::directionToKey(direction));
 462
 463	if (direction > 0)
 464	{
 465		setControlFlags(AGENT_CONTROL_LEFT_POS | AGENT_CONTROL_FAST_LEFT);
 466	}
 467	else if (direction < 0)
 468	{
 469		setControlFlags(AGENT_CONTROL_LEFT_NEG | AGENT_CONTROL_FAST_LEFT);
 470	}
 471
 472	gAgentCamera.resetView();
 473}
 474
 475//-----------------------------------------------------------------------------
 476// moveLeftNudge()
 477//-----------------------------------------------------------------------------
 478void LLAgent::moveLeftNudge(S32 direction)
 479{
 480	mMoveTimer.reset();
 481	LLFirstUse::notMoving(false);
 482
 483	// age chat timer so it fades more quickly when you are intentionally moving
 484	ageChat();
 485
 486	gAgentCamera.setLeftKey(LLAgentCamera::directionToKey(direction));
 487
 488	if (direction > 0)
 489	{
 490		setControlFlags(AGENT_CONTROL_NUDGE_LEFT_POS);
 491	}
 492	else if (direction < 0)
 493	{
 494		setControlFlags(AGENT_CONTROL_NUDGE_LEFT_NEG);
 495	}
 496
 497	gAgentCamera.resetView();
 498}
 499
 500//-----------------------------------------------------------------------------
 501// moveUp()
 502//-----------------------------------------------------------------------------
 503void LLAgent::moveUp(S32 direction)
 504{
 505	mMoveTimer.reset();
 506	LLFirstUse::notMoving(false);
 507
 508	// age chat timer so it fades more quickly when you are intentionally moving
 509	ageChat();
 510
 511	gAgentCamera.setUpKey(LLAgentCamera::directionToKey(direction));
 512
 513	if (direction > 0)
 514	{
 515		setControlFlags(AGENT_CONTROL_UP_POS | AGENT_CONTROL_FAST_UP);
 516	}
 517	else if (direction < 0)
 518	{
 519		setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP);
 520	}
 521
 522	gAgentCamera.resetView();
 523}
 524
 525//-----------------------------------------------------------------------------
 526// moveYaw()
 527//-----------------------------------------------------------------------------
 528void LLAgent::moveYaw(F32 mag, bool reset_view)
 529{
 530	gAgentCamera.setYawKey(mag);
 531
 532	if (mag > 0)
 533	{
 534		setControlFlags(AGENT_CONTROL_YAW_POS);
 535	}
 536	else if (mag < 0)
 537	{
 538		setControlFlags(AGENT_CONTROL_YAW_NEG);
 539	}
 540
 541    if (reset_view)
 542	{
 543        gAgentCamera.resetView();
 544	}
 545}
 546
 547//-----------------------------------------------------------------------------
 548// movePitch()
 549//-----------------------------------------------------------------------------
 550void LLAgent::movePitch(F32 mag)
 551{
 552	gAgentCamera.setPitchKey(mag);
 553
 554	if (mag > 0)
 555	{
 556		setControlFlags(AGENT_CONTROL_PITCH_POS);
 557	}
 558	else if (mag < 0)
 559	{
 560		setControlFlags(AGENT_CONTROL_PITCH_NEG);
 561	}
 562}
 563
 564
 565// Does this parcel allow you to fly?
 566BOOL LLAgent::canFly()
 567{
 568	if (isGodlike()) return TRUE;
 569
 570	LLViewerRegion* regionp = getRegion();
 571	if (regionp && regionp->getBlockFly()) return FALSE;
 572	
 573	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
 574	if (!parcel) return FALSE;
 575
 576	// Allow owners to fly on their own land.
 577	if (LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_ALLOW_FLY))
 578	{
 579		return TRUE;
 580	}
 581
 582	return parcel->getAllowFly();
 583}
 584
 585BOOL LLAgent::getFlying() const
 586{ 
 587	return mControlFlags & AGENT_CONTROL_FLY; 
 588}
 589
 590//-----------------------------------------------------------------------------
 591// setFlying()
 592//-----------------------------------------------------------------------------
 593void LLAgent::setFlying(BOOL fly)
 594{
 595	if (isAgentAvatarValid())
 596	{
 597		// *HACK: Don't allow to start the flying mode if we got ANIM_AGENT_STANDUP signal
 598		// because in this case we won't get a signal to start avatar flying animation and
 599		// it will be walking with flying mode "ON" indication. However we allow to switch
 600		// the flying mode off if we get ANIM_AGENT_STANDUP signal. See process_avatar_animation().
 601		// See EXT-2781.
 602		if(fly && gAgentAvatarp->mSignaledAnimations.find(ANIM_AGENT_STANDUP) != gAgentAvatarp->mSignaledAnimations.end())
 603		{
 604			return;
 605		}
 606
 607		// don't allow taking off while sitting
 608		if (fly && gAgentAvatarp->isSitting())
 609		{
 610			return;
 611		}
 612	}
 613
 614	if (fly)
 615	{
 616		BOOL was_flying = getFlying();
 617		if (!canFly() && !was_flying)
 618		{
 619			// parcel doesn't let you start fly
 620			// gods can always fly
 621			// and it's OK if you're already flying
 622			make_ui_sound("UISndBadKeystroke");
 623			return;
 624		}
 625		if( !was_flying )
 626		{
 627			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT);
 628		}
 629		setControlFlags(AGENT_CONTROL_FLY);
 630	}
 631	else
 632	{
 633		clearControlFlags(AGENT_CONTROL_FLY);
 634	}
 635
 636
 637	// Update Movement Controls according to Fly mode
 638	LLFloaterMove::setFlyingMode(fly);
 639
 640	mbFlagsDirty = TRUE;
 641}
 642
 643
 644// UI based mechanism of setting fly state
 645//-----------------------------------------------------------------------------
 646// toggleFlying()
 647//-----------------------------------------------------------------------------
 648// static
 649void LLAgent::toggleFlying()
 650{
 651	if ( gAgent.mAutoPilot )
 652	{
 653		LLToolPie::instance().stopClickToWalk();
 654	}
 655
 656	BOOL fly = !gAgent.getFlying();
 657
 658	gAgent.mMoveTimer.reset();
 659	LLFirstUse::notMoving(false);
 660
 661	gAgent.setFlying( fly );
 662	gAgentCamera.resetView();
 663}
 664
 665// static
 666bool LLAgent::enableFlying()
 667{
 668	BOOL sitting = FALSE;
 669	if (isAgentAvatarValid())
 670	{
 671		sitting = gAgentAvatarp->isSitting();
 672	}
 673	return !sitting;
 674}
 675
 676void LLAgent::standUp()
 677{
 678	setControlFlags(AGENT_CONTROL_STAND_UP);
 679}
 680
 681
 682//-----------------------------------------------------------------------------
 683// setRegion()
 684//-----------------------------------------------------------------------------
 685void LLAgent::setRegion(LLViewerRegion *regionp)
 686{
 687	bool teleport = true;
 688
 689	llassert(regionp);
 690	if (mRegionp != regionp)
 691	{
 692		// std::string host_name;
 693		// host_name = regionp->getHost().getHostName();
 694
 695		std::string ip = regionp->getHost().getString();
 696		llinfos << "Moving agent into region: " << regionp->getName()
 697				<< " located at " << ip << llendl;
 698		if (mRegionp)
 699		{
 700			// We've changed regions, we're now going to change our agent coordinate frame.
 701			mAgentOriginGlobal = regionp->getOriginGlobal();
 702			LLVector3d agent_offset_global = mRegionp->getOriginGlobal();
 703
 704			LLVector3 delta;
 705			delta.setVec(regionp->getOriginGlobal() - mRegionp->getOriginGlobal());
 706
 707			setPositionAgent(getPositionAgent() - delta);
 708
 709			LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
 710			LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
 711
 712			// Update all of the regions.
 713			LLWorld::getInstance()->updateAgentOffset(agent_offset_global);
 714
 715			// Hack to keep sky in the agent's region, otherwise it may get deleted - DJS 08/02/02
 716			// *TODO: possibly refactor into gSky->setAgentRegion(regionp)? -Brad
 717			if (gSky.mVOSkyp)
 718			{
 719				gSky.mVOSkyp->setRegion(regionp);
 720			}
 721			if (gSky.mVOGroundp)
 722			{
 723				gSky.mVOGroundp->setRegion(regionp);
 724			}
 725
 726			// Notify windlight managers
 727			teleport = (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE);
 728		}
 729		else
 730		{
 731			// First time initialization.
 732			// We've changed regions, we're now going to change our agent coordinate frame.
 733			mAgentOriginGlobal = regionp->getOriginGlobal();
 734
 735			LLVector3 delta;
 736			delta.setVec(regionp->getOriginGlobal());
 737
 738			setPositionAgent(getPositionAgent() - delta);
 739			LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
 740			LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
 741
 742			// Update all of the regions.
 743			LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal);
 744		}
 745
 746		// Pass new region along to metrics components that care about this level of detail.
 747		LLAppViewer::metricsUpdateRegion(regionp->getHandle());
 748	}
 749	mRegionp = regionp;
 750
 751	// Pass the region host to LLUrlEntryParcel to resolve parcel name
 752	// with a server request.
 753	LLUrlEntryParcel::setRegionHost(getRegionHost());
 754
 755	// Must shift hole-covering water object locations because local
 756	// coordinate frame changed.
 757	LLWorld::getInstance()->updateWaterObjects();
 758
 759	// keep a list of regions we've been too
 760	// this is just an interesting stat, logged at the dataserver
 761	// we could trake this at the dataserver side, but that's harder
 762	U64 handle = regionp->getHandle();
 763	mRegionsVisited.insert(handle);
 764
 765	LLSelectMgr::getInstance()->updateSelectionCenter();
 766
 767	LLFloaterMove::sUpdateFlyingStatus();
 768
 769	if (teleport)
 770	{
 771		LLEnvManagerNew::instance().onTeleport();
 772	}
 773	else
 774	{
 775		LLEnvManagerNew::instance().onRegionCrossing();
 776	}
 777}
 778
 779
 780//-----------------------------------------------------------------------------
 781// getRegion()
 782//-----------------------------------------------------------------------------
 783LLViewerRegion *LLAgent::getRegion() const
 784{
 785	return mRegionp;
 786}
 787
 788
 789LLHost LLAgent::getRegionHost() const
 790{
 791	if (mRegionp)
 792	{
 793		return mRegionp->getHost();
 794	}
 795	else
 796	{
 797		return LLHost::invalid;
 798	}
 799}
 800
 801//-----------------------------------------------------------------------------
 802// inPrelude()
 803//-----------------------------------------------------------------------------
 804BOOL LLAgent::inPrelude()
 805{
 806	return mRegionp && mRegionp->isPrelude();
 807}
 808
 809
 810//-----------------------------------------------------------------------------
 811// canManageEstate()
 812//-----------------------------------------------------------------------------
 813
 814BOOL LLAgent::canManageEstate() const
 815{
 816	return mRegionp && mRegionp->canManageEstate();
 817}
 818
 819//-----------------------------------------------------------------------------
 820// sendMessage()
 821//-----------------------------------------------------------------------------
 822void LLAgent::sendMessage()
 823{
 824	if (gDisconnected)
 825	{
 826		llwarns << "Trying to send message when disconnected!" << llendl;
 827		return;
 828	}
 829	if (!mRegionp)
 830	{
 831		llerrs << "No region for agent yet!" << llendl;
 832		return;
 833	}
 834	gMessageSystem->sendMessage(mRegionp->getHost());
 835}
 836
 837
 838//-----------------------------------------------------------------------------
 839// sendReliableMessage()
 840//-----------------------------------------------------------------------------
 841void LLAgent::sendReliableMessage()
 842{
 843	if (gDisconnected)
 844	{
 845		lldebugs << "Trying to send message when disconnected!" << llendl;
 846		return;
 847	}
 848	if (!mRegionp)
 849	{
 850		lldebugs << "LLAgent::sendReliableMessage No region for agent yet, not sending message!" << llendl;
 851		return;
 852	}
 853	gMessageSystem->sendReliable(mRegionp->getHost());
 854}
 855
 856//-----------------------------------------------------------------------------
 857// getVelocity()
 858//-----------------------------------------------------------------------------
 859LLVector3 LLAgent::getVelocity() const
 860{
 861	if (isAgentAvatarValid())
 862	{
 863		return gAgentAvatarp->getVelocity();
 864	}
 865	else
 866	{
 867		return LLVector3::zero;
 868	}
 869}
 870
 871
 872//-----------------------------------------------------------------------------
 873// setPositionAgent()
 874//-----------------------------------------------------------------------------
 875void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
 876{
 877	if (!pos_agent.isFinite())
 878	{
 879		llerrs << "setPositionAgent is not a number" << llendl;
 880	}
 881
 882	if (isAgentAvatarValid() && gAgentAvatarp->getParent())
 883	{
 884		LLVector3 pos_agent_sitting;
 885		LLVector3d pos_agent_d;
 886		LLViewerObject *parent = (LLViewerObject*)gAgentAvatarp->getParent();
 887
 888		pos_agent_sitting = gAgentAvatarp->getPosition() * parent->getRotation() + parent->getPositionAgent();
 889		pos_agent_d.setVec(pos_agent_sitting);
 890
 891		mFrameAgent.setOrigin(pos_agent_sitting);
 892		mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
 893	}
 894	else
 895	{
 896		mFrameAgent.setOrigin(pos_agent);
 897
 898		LLVector3d pos_agent_d;
 899		pos_agent_d.setVec(pos_agent);
 900		mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
 901	}
 902}
 903
 904//-----------------------------------------------------------------------------
 905// getPositionGlobal()
 906//-----------------------------------------------------------------------------
 907const LLVector3d &LLAgent::getPositionGlobal() const
 908{
 909	if (isAgentAvatarValid() && !gAgentAvatarp->mDrawable.isNull())
 910	{
 911		mPositionGlobal = getPosGlobalFromAgent(gAgentAvatarp->getRenderPosition());
 912	}
 913	else
 914	{
 915		mPositionGlobal = getPosGlobalFromAgent(mFrameAgent.getOrigin());
 916	}
 917
 918	return mPositionGlobal;
 919}
 920
 921//-----------------------------------------------------------------------------
 922// getPositionAgent()
 923//-----------------------------------------------------------------------------
 924const LLVector3 &LLAgent::getPositionAgent()
 925{
 926	if (isAgentAvatarValid() && !gAgentAvatarp->mDrawable.isNull())
 927	{
 928		mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition());	
 929	}
 930
 931	return mFrameAgent.getOrigin();
 932}
 933
 934//-----------------------------------------------------------------------------
 935// getRegionsVisited()
 936//-----------------------------------------------------------------------------
 937S32 LLAgent::getRegionsVisited() const
 938{
 939	return mRegionsVisited.size();
 940}
 941
 942//-----------------------------------------------------------------------------
 943// getDistanceTraveled()
 944//-----------------------------------------------------------------------------
 945F64 LLAgent::getDistanceTraveled() const
 946{
 947	return mDistanceTraveled;
 948}
 949
 950
 951//-----------------------------------------------------------------------------
 952// getPosAgentFromGlobal()
 953//-----------------------------------------------------------------------------
 954LLVector3 LLAgent::getPosAgentFromGlobal(const LLVector3d &pos_global) const
 955{
 956	LLVector3 pos_agent;
 957	pos_agent.setVec(pos_global - mAgentOriginGlobal);
 958	return pos_agent;
 959}
 960
 961
 962//-----------------------------------------------------------------------------
 963// getPosGlobalFromAgent()
 964//-----------------------------------------------------------------------------
 965LLVector3d LLAgent::getPosGlobalFromAgent(const LLVector3 &pos_agent) const
 966{
 967	LLVector3d pos_agent_d;
 968	pos_agent_d.setVec(pos_agent);
 969	return pos_agent_d + mAgentOriginGlobal;
 970}
 971
 972void LLAgent::sitDown()
 973{
 974	setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
 975}
 976
 977
 978//-----------------------------------------------------------------------------
 979// resetAxes()
 980//-----------------------------------------------------------------------------
 981void LLAgent::resetAxes()
 982{
 983	mFrameAgent.resetAxes();
 984}
 985
 986
 987// Copied from LLCamera::setOriginAndLookAt
 988// Look_at must be unit vector
 989//-----------------------------------------------------------------------------
 990// resetAxes()
 991//-----------------------------------------------------------------------------
 992void LLAgent::resetAxes(const LLVector3 &look_at)
 993{
 994	LLVector3	skyward = getReferenceUpVector();
 995
 996	// if look_at has zero length, fail
 997	// if look_at and skyward are parallel, fail
 998	//
 999	// Test both of these conditions with a cross product.
1000	LLVector3 cross(look_at % skyward);
1001	if (cross.isNull())
1002	{
1003		llinfos << "LLAgent::resetAxes cross-product is zero" << llendl;
1004		return;
1005	}
1006
1007	// Make sure look_at and skyward are not parallel
1008	// and neither are zero length
1009	LLVector3 left(skyward % look_at);
1010	LLVector3 up(look_at % left);
1011
1012	mFrameAgent.setAxes(look_at, left, up);
1013}
1014
1015
1016//-----------------------------------------------------------------------------
1017// rotate()
1018//-----------------------------------------------------------------------------
1019void LLAgent::rotate(F32 angle, const LLVector3 &axis) 
1020{ 
1021	mFrameAgent.rotate(angle, axis); 
1022}
1023
1024
1025//-----------------------------------------------------------------------------
1026// rotate()
1027//-----------------------------------------------------------------------------
1028void LLAgent::rotate(F32 angle, F32 x, F32 y, F32 z) 
1029{ 
1030	mFrameAgent.rotate(angle, x, y, z); 
1031}
1032
1033
1034//-----------------------------------------------------------------------------
1035// rotate()
1036//-----------------------------------------------------------------------------
1037void LLAgent::rotate(const LLMatrix3 &matrix) 
1038{ 
1039	mFrameAgent.rotate(matrix); 
1040}
1041
1042
1043//-----------------------------------------------------------------------------
1044// rotate()
1045//-----------------------------------------------------------------------------
1046void LLAgent::rotate(const LLQuaternion &quaternion) 
1047{ 
1048	mFrameAgent.rotate(quaternion); 
1049}
1050
1051
1052//-----------------------------------------------------------------------------
1053// getReferenceUpVector()
1054//-----------------------------------------------------------------------------
1055LLVector3 LLAgent::getReferenceUpVector()
1056{
1057	// this vector is in the coordinate frame of the avatar's parent object, or the world if none
1058	LLVector3 up_vector = LLVector3::z_axis;
1059	if (isAgentAvatarValid() && 
1060		gAgentAvatarp->getParent() &&
1061		gAgentAvatarp->mDrawable.notNull())
1062	{
1063		U32 camera_mode = gAgentCamera.getCameraAnimating() ? gAgentCamera.getLastCameraMode() : gAgentCamera.getCameraMode();
1064		// and in third person...
1065		if (camera_mode == CAMERA_MODE_THIRD_PERSON)
1066		{
1067			// make the up vector point to the absolute +z axis
1068			up_vector = up_vector * ~((LLViewerObject*)gAgentAvatarp->getParent())->getRenderRotation();
1069		}
1070		else if (camera_mode == CAMERA_MODE_MOUSELOOK)
1071		{
1072			// make the up vector point to the avatar's +z axis
1073			up_vector = up_vector * gAgentAvatarp->mDrawable->getRotation();
1074		}
1075	}
1076
1077	return up_vector;
1078}
1079
1080
1081// Radians, positive is forward into ground
1082//-----------------------------------------------------------------------------
1083// pitch()
1084//-----------------------------------------------------------------------------
1085void LLAgent::pitch(F32 angle)
1086{
1087	// don't let user pitch if pointed almost all the way down or up
1088	mFrameAgent.pitch(clampPitchToLimits(angle));
1089}
1090
1091
1092// Radians, positive is forward into ground
1093//-----------------------------------------------------------------------------
1094// clampPitchToLimits()
1095//-----------------------------------------------------------------------------
1096F32 LLAgent::clampPitchToLimits(F32 angle)
1097{
1098	// A dot B = mag(A) * mag(B) * cos(angle between A and B)
1099	// so... cos(angle between A and B) = A dot B / mag(A) / mag(B)
1100	//                                  = A dot B for unit vectors
1101
1102	LLVector3 skyward = getReferenceUpVector();
1103
1104	const F32 look_down_limit = 179.f * DEG_TO_RAD;;
1105	const F32 look_up_limit   =   1.f * DEG_TO_RAD;
1106
1107	F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward );
1108
1109	// clamp pitch to limits
1110	if ((angle >= 0.f) && (angle_from_skyward + angle > look_down_limit))
1111	{
1112		angle = look_down_limit - angle_from_skyward;
1113	}
1114	else if ((angle < 0.f) && (angle_from_skyward + angle < look_up_limit))
1115	{
1116		angle = look_up_limit - angle_from_skyward;
1117	}
1118   
1119    return angle;
1120}
1121
1122
1123//-----------------------------------------------------------------------------
1124// roll()
1125//-----------------------------------------------------------------------------
1126void LLAgent::roll(F32 angle)
1127{
1128	mFrameAgent.roll(angle);
1129}
1130
1131
1132//-----------------------------------------------------------------------------
1133// yaw()
1134//-----------------------------------------------------------------------------
1135void LLAgent::yaw(F32 angle)
1136{
1137	if (!rotateGrabbed())
1138	{
1139		mFrameAgent.rotate(angle, getReferenceUpVector());
1140	}
1141}
1142
1143
1144// Returns a quat that represents the rotation of the agent in the absolute frame
1145//-----------------------------------------------------------------------------
1146// getQuat()
1147//-----------------------------------------------------------------------------
1148LLQuaternion LLAgent::getQuat() const
1149{
1150	return mFrameAgent.getQuaternion();
1151}
1152
1153//-----------------------------------------------------------------------------
1154// getControlFlags()
1155//-----------------------------------------------------------------------------
1156U32 LLAgent::getControlFlags()
1157{
1158	return mControlFlags;
1159}
1160
1161//-----------------------------------------------------------------------------
1162// setControlFlags()
1163//-----------------------------------------------------------------------------
1164void LLAgent::setControlFlags(U32 mask)
1165{
1166	mControlFlags |= mask;
1167	mbFlagsDirty = TRUE;
1168}
1169
1170
1171//-----------------------------------------------------------------------------
1172// clearControlFlags()
1173//-----------------------------------------------------------------------------
1174void LLAgent::clearControlFlags(U32 mask)
1175{
1176	U32 old_flags = mControlFlags;
1177	mControlFlags &= ~mask;
1178	if (old_flags != mControlFlags)
1179	{
1180		mbFlagsDirty = TRUE;
1181	}
1182}
1183
1184//-----------------------------------------------------------------------------
1185// controlFlagsDirty()
1186//-----------------------------------------------------------------------------
1187BOOL LLAgent::controlFlagsDirty() const
1188{
1189	return mbFlagsDirty;
1190}
1191
1192//-----------------------------------------------------------------------------
1193// enableControlFlagReset()
1194//-----------------------------------------------------------------------------
1195void LLAgent::enableControlFlagReset()
1196{
1197	mbFlagsNeedReset = TRUE;
1198}
1199
1200//-----------------------------------------------------------------------------
1201// resetControlFlags()
1202//-----------------------------------------------------------------------------
1203void LLAgent::resetControlFlags()
1204{
1205	if (mbFlagsNeedReset)
1206	{
1207		mbFlagsNeedReset = FALSE;
1208		mbFlagsDirty = FALSE;
1209		// reset all of the ephemeral flags
1210		// some flags are managed elsewhere
1211		mControlFlags &= AGENT_CONTROL_AWAY | AGENT_CONTROL_FLY | AGENT_CONTROL_MOUSELOOK;
1212	}
1213}
1214
1215//-----------------------------------------------------------------------------
1216// setAFK()
1217//-----------------------------------------------------------------------------
1218void LLAgent::setAFK()
1219{
1220	if (!gAgent.getRegion())
1221	{
1222		// Don't set AFK if we're not talking to a region yet.
1223		return;
1224	}
1225
1226	if (!(mControlFlags & AGENT_CONTROL_AWAY))
1227	{
1228		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START);
1229		setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP);
1230		LL_INFOS("AFK") << "Setting Away" << LL_ENDL;
1231		gAwayTimer.start();
1232		if (gAFKMenu)
1233		{
1234			gAFKMenu->setLabel(LLTrans::getString("AvatarSetNotAway"));
1235		}
1236	}
1237}
1238
1239//-----------------------------------------------------------------------------
1240// clearAFK()
1241//-----------------------------------------------------------------------------
1242void LLAgent::clearAFK()
1243{
1244	gAwayTriggerTimer.reset();
1245
1246	// Gods can sometimes get into away state (via gestures)
1247	// without setting the appropriate control flag. JC
1248	if (mControlFlags & AGENT_CONTROL_AWAY
1249		|| (isAgentAvatarValid()
1250			&& (gAgentAvatarp->mSignaledAnimations.find(ANIM_AGENT_AWAY) != gAgentAvatarp->mSignaledAnimations.end())))
1251	{
1252		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP);
1253		clearControlFlags(AGENT_CONTROL_AWAY);
1254		LL_INFOS("AFK") << "Clearing Away" << LL_ENDL;
1255		if (gAFKMenu)
1256		{
1257			gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway"));
1258		}
1259	}
1260}
1261
1262//-----------------------------------------------------------------------------
1263// getAFK()
1264//-----------------------------------------------------------------------------
1265BOOL LLAgent::getAFK() const
1266{
1267	return (mControlFlags & AGENT_CONTROL_AWAY) != 0;
1268}
1269
1270//-----------------------------------------------------------------------------
1271// setBusy()
1272//-----------------------------------------------------------------------------
1273void LLAgent::setBusy()
1274{
1275	sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_START);
1276	mIsBusy = TRUE;
1277	if (gBusyMenu)
1278	{
1279		gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy"));
1280	}
1281	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(true);
1282}
1283
1284//-----------------------------------------------------------------------------
1285// clearBusy()
1286//-----------------------------------------------------------------------------
1287void LLAgent::clearBusy()
1288{
1289	mIsBusy = FALSE;
1290	sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP);
1291	if (gBusyMenu)
1292	{
1293		gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy"));
1294	}
1295	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(false);
1296}
1297
1298//-----------------------------------------------------------------------------
1299// getBusy()
1300//-----------------------------------------------------------------------------
1301BOOL LLAgent::getBusy() const
1302{
1303	return mIsBusy;
1304}
1305
1306
1307//-----------------------------------------------------------------------------
1308// startAutoPilotGlobal()
1309//-----------------------------------------------------------------------------
1310void LLAgent::startAutoPilotGlobal(
1311	const LLVector3d &target_global,
1312	const std::string& behavior_name,
1313	const LLQuaternion *target_rotation,
1314	void (*finish_callback)(BOOL, void *),
1315	void *callback_data,
1316	F32 stop_distance,
1317	F32 rot_threshold,
1318	BOOL allow_flying)
1319{
1320	if (!isAgentAvatarValid())
1321	{
1322		return;
1323	}
1324	
1325	// Are there any pending callbacks from previous auto pilot requests?
1326	if (mAutoPilotFinishedCallback)
1327	{
1328		mAutoPilotFinishedCallback(dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData);
1329	}
1330
1331	mAutoPilotFinishedCallback = finish_callback;
1332	mAutoPilotCallbackData = callback_data;
1333	mAutoPilotRotationThreshold = rot_threshold;
1334	mAutoPilotBehaviorName = behavior_name;
1335	mAutoPilotAllowFlying = allow_flying;
1336
1337	LLVector3d delta_pos( target_global );
1338	delta_pos -= getPositionGlobal();
1339	F64 distance = delta_pos.magVec();
1340	LLVector3d trace_target = target_global;
1341
1342	trace_target.mdV[VZ] -= 10.f;
1343
1344	LLVector3d intersection;
1345	LLVector3 normal;
1346	LLViewerObject *hit_obj;
1347	F32 heightDelta = LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, trace_target, intersection, normal, &hit_obj);
1348
1349	if (stop_distance > 0.f)
1350	{
1351		mAutoPilotStopDistance = stop_distance;
1352	}
1353	else
1354	{
1355		// Guess at a reasonable stop distance.
1356		mAutoPilotStopDistance = (F32) sqrt( distance );
1357		if (mAutoPilotStopDistance < 0.5f) 
1358		{
1359			mAutoPilotStopDistance = 0.5f;
1360		}
1361	}
1362
1363	if (mAutoPilotAllowFlying)
1364	{
1365		mAutoPilotFlyOnStop = getFlying();
1366	}
1367	else
1368	{
1369		mAutoPilotFlyOnStop = FALSE;
1370	}
1371
1372	if (distance > 30.0 && mAutoPilotAllowFlying)
1373	{
1374		setFlying(TRUE);
1375	}
1376
1377	if ( distance > 1.f && 
1378		mAutoPilotAllowFlying &&
1379		heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f))
1380	{
1381		setFlying(TRUE);
1382		// Do not force flying for "Sit" behavior to prevent flying after pressing "Stand"
1383		// from an object. See EXT-1655.
1384		if ("Sit" != mAutoPilotBehaviorName)
1385			mAutoPilotFlyOnStop = TRUE;
1386	}
1387
1388	mAutoPilot = TRUE;
1389	setAutoPilotTargetGlobal(target_global);
1390
1391	if (target_rotation)
1392	{
1393		mAutoPilotUseRotation = TRUE;
1394		mAutoPilotTargetFacing = LLVector3::x_axis * *target_rotation;
1395		mAutoPilotTargetFacing.mV[VZ] = 0.f;
1396		mAutoPilotTargetFacing.normalize();
1397	}
1398	else
1399	{
1400		mAutoPilotUseRotation = FALSE;
1401	}
1402
1403	mAutoPilotNoProgressFrameCount = 0;
1404}
1405
1406
1407//-----------------------------------------------------------------------------
1408// setAutoPilotTargetGlobal
1409//-----------------------------------------------------------------------------
1410void LLAgent::setAutoPilotTargetGlobal(const LLVector3d &target_global)
1411{
1412	if (mAutoPilot)
1413	{
1414		mAutoPilotTargetGlobal = target_global;
1415
1416		// trace ray down to find height of destination from ground
1417		LLVector3d traceEndPt = target_global;
1418		traceEndPt.mdV[VZ] -= 20.f;
1419
1420		LLVector3d targetOnGround;
1421		LLVector3 groundNorm;
1422		LLViewerObject *obj;
1423
1424		LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj);
1425		F64 target_height = llmax((F64)gAgentAvatarp->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]);
1426
1427		// clamp z value of target to minimum height above ground
1428		mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height;
1429		mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal);
1430	}
1431}
1432
1433//-----------------------------------------------------------------------------
1434// startFollowPilot()
1435//-----------------------------------------------------------------------------
1436void LLAgent::startFollowPilot(const LLUUID &leader_id, BOOL allow_flying, F32 stop_distance)
1437{
1438	mLeaderID = leader_id;
1439	if ( mLeaderID.isNull() ) return;
1440
1441	LLViewerObject* object = gObjectList.findObject(mLeaderID);
1442	if (!object) 
1443	{
1444		mLeaderID = LLUUID::null;
1445		return;
1446	}
1447
1448	startAutoPilotGlobal(object->getPositionGlobal(), 
1449						 std::string(),	// behavior_name
1450						 NULL,			// target_rotation
1451						 NULL,			// finish_callback
1452						 NULL,			// callback_data
1453						 stop_distance,
1454						 0.03f,			// rotation_threshold
1455						 allow_flying);
1456}
1457
1458
1459//-----------------------------------------------------------------------------
1460// stopAutoPilot()
1461//-----------------------------------------------------------------------------
1462void LLAgent::stopAutoPilot(BOOL user_cancel)
1463{
1464	if (mAutoPilot)
1465	{
1466		mAutoPilot = FALSE;
1467		if (mAutoPilotUseRotation && !user_cancel)
1468		{
1469			resetAxes(mAutoPilotTargetFacing);
1470		}
1471		// Restore previous flying state before invoking mAutoPilotFinishedCallback to allow
1472		// callback function to change the flying state (like in near_sit_down_point()).
1473		// If the user cancelled, don't change the fly state
1474		if (!user_cancel)
1475		{
1476			setFlying(mAutoPilotFlyOnStop);
1477		}
1478		//NB: auto pilot can terminate for a reason other than reaching the destination
1479		if (mAutoPilotFinishedCallback)
1480		{
1481			mAutoPilotFinishedCallback(!user_cancel && dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData);
1482			mAutoPilotFinishedCallback = NULL;
1483		}
1484		mLeaderID = LLUUID::null;
1485
1486		setControlFlags(AGENT_CONTROL_STOP);
1487
1488		if (user_cancel && !mAutoPilotBehaviorName.empty())
1489		{
1490			if (mAutoPilotBehaviorName == "Sit")
1491				LLNotificationsUtil::add("CancelledSit");
1492			else if (mAutoPilotBehaviorName == "Attach")
1493				LLNotificationsUtil::add("CancelledAttach");
1494			else
1495				LLNotificationsUtil::add("Cancelled");
1496		}
1497	}
1498}
1499
1500
1501// Returns necessary agent pitch and yaw changes, radians.
1502//-----------------------------------------------------------------------------
1503// autoPilot()
1504//-----------------------------------------------------------------------------
1505void LLAgent::autoPilot(F32 *delta_yaw)
1506{
1507	if (mAutoPilot)
1508	{
1509		if (!mLeaderID.isNull())
1510		{
1511			LLViewerObject* object = gObjectList.findObject(mLeaderID);
1512			if (!object) 
1513			{
1514				stopAutoPilot();
1515				return;
1516			}
1517			mAutoPilotTargetGlobal = object->getPositionGlobal();
1518		}
1519		
1520		if (!isAgentAvatarValid()) return;
1521
1522		if (gAgentAvatarp->mInAir && mAutoPilotAllowFlying)
1523		{
1524			setFlying(TRUE);
1525		}
1526	
1527		LLVector3 at;
1528		at.setVec(mFrameAgent.getAtAxis());
1529		LLVector3 target_agent = getPosAgentFromGlobal(mAutoPilotTargetGlobal);
1530		LLVector3 direction = target_agent - getPositionAgent();
1531
1532		F32 target_dist = direction.magVec();
1533
1534		if (target_dist >= mAutoPilotTargetDist)
1535		{
1536			mAutoPilotNoProgressFrameCount++;
1537			if (mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped)
1538			{
1539				stopAutoPilot();
1540				return;
1541			}
1542		}
1543
1544		mAutoPilotTargetDist = target_dist;
1545
1546		// Make this a two-dimensional solution
1547		at.mV[VZ] = 0.f;
1548		direction.mV[VZ] = 0.f;
1549
1550		at.normalize();
1551		F32 xy_distance = direction.normalize();
1552
1553		F32 yaw = 0.f;
1554		if (mAutoPilotTargetDist > mAutoPilotStopDistance)
1555		{
1556			yaw = angle_between(mFrameAgent.getAtAxis(), direction);
1557		}
1558		else if (mAutoPilotUseRotation)
1559		{
1560			// we're close now just aim at target facing
1561			yaw = angle_between(at, mAutoPilotTargetFacing);
1562			direction = mAutoPilotTargetFacing;
1563		}
1564
1565		yaw = 4.f * yaw / gFPSClamped;
1566
1567		// figure out which direction to turn
1568		LLVector3 scratch(at % direction);
1569
1570		if (scratch.mV[VZ] > 0.f)
1571		{
1572			setControlFlags(AGENT_CONTROL_YAW_POS);
1573		}
1574		else
1575		{
1576			yaw = -yaw;
1577			setControlFlags(AGENT_CONTROL_YAW_NEG);
1578		}
1579
1580		*delta_yaw = yaw;
1581
1582		// Compute when to start slowing down and when to stop
1583		F32 stop_distance = mAutoPilotStopDistance;
1584		F32 slow_distance;
1585		if (getFlying())
1586		{
1587			slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
1588			stop_distance = llmax(2.f, mAutoPilotStopDistance);
1589		}
1590		else
1591		{
1592			slow_distance = llmax(3.f, mAutoPilotStopDistance + 2.f);
1593		}
1594
1595		// If we're flying, handle autopilot points above or below you.
1596		if (getFlying() && xy_distance < AUTOPILOT_HEIGHT_ADJUST_DISTANCE)
1597		{
1598			if (isAgentAvatarValid())
1599			{
1600				F64 current_height = gAgentAvatarp->getPositionGlobal().mdV[VZ];
1601				F32 delta_z = (F32)(mAutoPilotTargetGlobal.mdV[VZ] - current_height);
1602				F32 slope = delta_z / xy_distance;
1603				if (slope > 0.45f && delta_z > 6.f)
1604				{
1605					setControlFlags(AGENT_CONTROL_FAST_UP | AGENT_CONTROL_UP_POS);
1606				}
1607				else if (slope > 0.002f && delta_z > 0.5f)
1608				{
1609					setControlFlags(AGENT_CONTROL_UP_POS);
1610				}
1611				else if (slope < -0.45f && delta_z < -6.f && current_height > AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND)
1612				{
1613					setControlFlags(AGENT_CONTROL_FAST_UP | AGENT_CONTROL_UP_NEG);
1614				}
1615				else if (slope < -0.002f && delta_z < -0.5f && current_height > AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND)
1616				{
1617					setControlFlags(AGENT_CONTROL_UP_NEG);
1618				}
1619			}
1620		}
1621
1622		//  calculate delta rotation to target heading
1623		F32 delta_target_heading = angle_between(mFrameAgent.getAtAxis(), mAutoPilotTargetFacing);
1624
1625		if (xy_distance > slow_distance && yaw < (F_PI / 10.f))
1626		{
1627			// walking/flying fast
1628			setControlFlags(AGENT_CONTROL_FAST_AT | AGENT_CONTROL_AT_POS);
1629		}
1630		else if (mAutoPilotTargetDist > mAutoPilotStopDistance)
1631		{
1632			// walking/flying slow
1633			if (at * direction > 0.9f)
1634			{
1635				setControlFlags(AGENT_CONTROL_AT_POS);
1636			}
1637			else if (at * direction < -0.9f)
1638			{
1639				setControlFlags(AGENT_CONTROL_AT_NEG);
1640			}
1641		}
1642
1643		// check to see if we need to keep rotating to target orientation
1644		if (mAutoPilotTargetDist < mAutoPilotStopDistance)
1645		{
1646			setControlFlags(AGENT_CONTROL_STOP);
1647			if(!mAutoPilotUseRotation || (delta_target_heading < mAutoPilotRotationThreshold))
1648			{
1649				stopAutoPilot();
1650			}
1651		}
1652	}
1653}
1654
1655
1656//-----------------------------------------------------------------------------
1657// propagate()
1658//-----------------------------------------------------------------------------
1659void LLAgent::propagate(const F32 dt)
1660{
1661	// Update UI based on agent motion
1662	LLFloaterMove *floater_move = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
1663	if (floater_move)
1664	{
1665		floater_move->mForwardButton   ->setToggleState( gAgentCamera.getAtKey() > 0 || gAgentCamera.getWalkKey() > 0 );
1666		floater_move->mBackwardButton  ->setToggleState( gAgentCamera.getAtKey() < 0 || gAgentCamera.getWalkKey() < 0 );
1667		floater_move->mTurnLeftButton  ->setToggleState( gAgentCamera.getYawKey() > 0.f );
1668		floater_move->mTurnRightButton ->setToggleState( gAgentCamera.getYawKey() < 0.f );
1669		floater_move->mSlideLeftButton  ->setToggleState( gAgentCamera.getLeftKey() > 0.f );
1670		floater_move->mSlideRightButton ->setToggleState( gAgentCamera.getLeftKey() < 0.f );
1671		floater_move->mMoveUpButton    ->setToggleState( gAgentCamera.getUpKey() > 0 );
1672		floater_move->mMoveDownButton  ->setToggleState( gAgentCamera.getUpKey() < 0 );
1673	}
1674
1675	// handle rotation based on keyboard levels
1676	const F32 YAW_RATE = 90.f * DEG_TO_RAD;				// radians per second
1677	yaw(YAW_RATE * gAgentCamera.getYawKey() * dt);
1678
1679	const F32 PITCH_RATE = 90.f * DEG_TO_RAD;			// radians per second
1680	pitch(PITCH_RATE * gAgentCamera.getPitchKey() * dt);
1681	
1682	// handle auto-land behavior
1683	if (isAgentAvatarValid())
1684	{
1685		BOOL in_air = gAgentAvatarp->mInAir;
1686		LLVector3 land_vel = getVelocity();
1687		land_vel.mV[VZ] = 0.f;
1688
1689		if (!in_air 
1690			&& gAgentCamera.getUpKey() < 0 
1691			&& land_vel.magVecSquared() < MAX_VELOCITY_AUTO_LAND_SQUARED
1692			&& gSavedSettings.getBOOL("AutomaticFly"))
1693		{
1694			// land automatically
1695			setFlying(FALSE);
1696		}
1697	}
1698
1699	gAgentCamera.clearGeneralKeys();
1700}
1701
1702//-----------------------------------------------------------------------------
1703// updateAgentPosition()
1704//-----------------------------------------------------------------------------
1705void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y)
1706{
1707	if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > gSavedSettings.getF32("NotMovingHintTimeout"))
1708	{
1709		LLFirstUse::notMoving();
1710	}
1711
1712	propagate(dt);
1713
1714	// static S32 cameraUpdateCount = 0;
1715
1716	rotate(yaw_radians, 0, 0, 1);
1717	
1718	//
1719	// Check for water and land collision, set underwater flag
1720	//
1721
1722	gAgentCamera.updateLookAt(mouse_x, mouse_y);
1723}
1724
1725// friends and operators
1726
1727std::ostream& operator<<(std::ostream &s, const LLAgent &agent)
1728{
1729	// This is unfinished, but might never be used. 
1730	// We'll just leave it for now; we can always delete it.
1731	s << " { "
1732	  << "  Frame = " << agent.mFrameAgent << "\n"
1733	  << " }";
1734	return s;
1735}
1736
1737// TRUE if your own avatar needs to be rendered.  Usually only
1738// in third person and build.
1739//-----------------------------------------------------------------------------
1740// needsRenderAvatar()
1741//-----------------------------------------------------------------------------
1742BOOL LLAgent::needsRenderAvatar()
1743{
1744	if (gAgentCamera.cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson)
1745	{
1746		return FALSE;
1747	}
1748
1749	return mShowAvatar && mGenderChosen;
1750}
1751
1752// TRUE if we need to render your own avatar's head.
1753BOOL LLAgent::needsRenderHead()
1754{
1755	return (LLVOAvatar::sVisibleInFirstPerson && LLPipeline::sReflectionRender) || (mShowAvatar && !gAgentCamera.cameraMouselook());
1756}
1757
1758//-----------------------------------------------------------------------------
1759// startTyping()
1760//-----------------------------------------------------------------------------
1761void LLAgent::startTyping()
1762{
1763	mTypingTimer.reset();
1764
1765	if (getRenderState() & AGENT_STATE_TYPING)
1766	{
1767		// already typing, don't trigger a different animation
1768		return;
1769	}
1770	setRenderState(AGENT_STATE_TYPING);
1771
1772	if (mChatTimer.getElapsedTimeF32() < 2.f)
1773	{
1774		LLViewerObject* chatter = gObjectList.findObject(mLastChatterID);
1775		if (chatter && chatter->isAvatar())
1776		{
1777			gAgentCamera.setLookAt(LOOKAT_TARGET_RESPOND, chatter, LLVector3::zero);
1778		}
1779	}
1780
1781	if (gSavedSettings.getBOOL("PlayTypingAnim"))
1782	{
1783		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
1784	}
1785	LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
1786}
1787
1788//-----------------------------------------------------------------------------
1789// stopTyping()
1790//-----------------------------------------------------------------------------
1791void LLAgent::stopTyping()
1792{
1793	if (mRenderState & AGENT_STATE_TYPING)
1794	{
1795		clearRenderState(AGENT_STATE_TYPING);
1796		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
1797		LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
1798	}
1799}
1800
1801//-----------------------------------------------------------------------------
1802// setRenderState()
1803//-----------------------------------------------------------------------------
1804void LLAgent::setRenderState(U8 newstate)
1805{
1806	mRenderState |= newstate;
1807}
1808
1809//-----------------------------------------------------------------------------
1810// clearRenderState()
1811//-----…

Large files files are truncated, but you can click here to view the full file