PageRenderTime 172ms CodeModel.GetById 59ms app.highlight 102ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llworld.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1252 lines | 953 code | 193 blank | 106 comment | 144 complexity | d5c9f0695c2ff37537564c06f8f6c545 MD5 | raw file
   1/** 
   2 * @file llworld.cpp
   3 * @brief Initial test structure to organize viewer regions
   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 "llworld.h"
  30#include "llrender.h"
  31
  32#include "indra_constants.h"
  33#include "llstl.h"
  34
  35#include "llagent.h"
  36#include "llviewercontrol.h"
  37#include "lldrawpool.h"
  38#include "llglheaders.h"
  39#include "llhttpnode.h"
  40#include "llregionhandle.h"
  41#include "llsurface.h"
  42#include "lltrans.h"
  43#include "llviewercamera.h"
  44#include "llviewertexture.h"
  45#include "llviewertexturelist.h"
  46#include "llviewernetwork.h"
  47#include "llviewerobjectlist.h"
  48#include "llviewerparceloverlay.h"
  49#include "llviewerregion.h"
  50#include "llviewerstats.h"
  51#include "llvlcomposition.h"
  52#include "llvoavatar.h"
  53#include "llvocache.h"
  54#include "llvowater.h"
  55#include "message.h"
  56#include "pipeline.h"
  57#include "llappviewer.h"		// for do_disconnect()
  58
  59#include <deque>
  60#include <queue>
  61#include <map>
  62#include <cstring>
  63
  64
  65//
  66// Globals
  67//
  68U32			gAgentPauseSerialNum = 0;
  69
  70//
  71// Constants
  72//
  73const S32 MAX_NUMBER_OF_CLOUDS	= 750;
  74const S32 WORLD_PATCH_SIZE = 16;
  75
  76extern LLColor4U MAX_WATER_COLOR;
  77
  78const U32 LLWorld::mWidth = 256;
  79
  80// meters/point, therefore mWidth * mScale = meters per edge
  81const F32 LLWorld::mScale = 1.f;
  82
  83const F32 LLWorld::mWidthInMeters = mWidth * mScale;
  84
  85//
  86// Functions
  87//
  88
  89// allocate the stack
  90LLWorld::LLWorld() :
  91	mLandFarClip(DEFAULT_FAR_PLANE),
  92	mLastPacketsIn(0),
  93	mLastPacketsOut(0),
  94	mLastPacketsLost(0),
  95	mSpaceTimeUSec(0)
  96{
  97	for (S32 i = 0; i < 8; i++)
  98	{
  99		mEdgeWaterObjects[i] = NULL;
 100	}
 101
 102	LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4);
 103	U8 *default_texture = raw->getData();
 104	*(default_texture++) = MAX_WATER_COLOR.mV[0];
 105	*(default_texture++) = MAX_WATER_COLOR.mV[1];
 106	*(default_texture++) = MAX_WATER_COLOR.mV[2];
 107	*(default_texture++) = MAX_WATER_COLOR.mV[3];
 108	
 109	mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
 110	gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
 111	mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
 112
 113}
 114
 115
 116void LLWorld::destroyClass()
 117{
 118	mHoleWaterObjects.clear();
 119	gObjectList.destroy();
 120	for(region_list_t::iterator region_it = mRegionList.begin(); region_it != mRegionList.end(); )
 121	{
 122		LLViewerRegion* region_to_delete = *region_it++;
 123		removeRegion(region_to_delete->getHost());
 124	}
 125	if(LLVOCache::hasInstance())
 126	{
 127		LLVOCache::getInstance()->destroyClass() ;
 128	}
 129	LLViewerPartSim::getInstance()->destroyClass();
 130
 131	mDefaultWaterTexturep = NULL ;
 132	for (S32 i = 0; i < 8; i++)
 133	{
 134		mEdgeWaterObjects[i] = NULL;
 135	}
 136}
 137
 138
 139LLViewerRegion* LLWorld::addRegion(const U64 &region_handle, const LLHost &host)
 140{
 141	LLMemType mt(LLMemType::MTYPE_REGIONS);
 142	llinfos << "Add region with handle: " << region_handle << " on host " << host << llendl;
 143	LLViewerRegion *regionp = getRegionFromHandle(region_handle);
 144	if (regionp)
 145	{
 146		llinfos << "Region exists, removing it " << llendl;
 147		LLHost old_host = regionp->getHost();
 148		// region already exists!
 149		if (host == old_host && regionp->isAlive())
 150		{
 151			// This is a duplicate for the same host and it's alive, don't bother.
 152			return regionp;
 153		}
 154
 155		if (host != old_host)
 156		{
 157			llwarns << "LLWorld::addRegion exists, but old host " << old_host
 158					<< " does not match new host " << host << llendl;
 159		}
 160		if (!regionp->isAlive())
 161		{
 162			llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl;
 163		}
 164
 165		// Kill the old host, and then we can continue on and add the new host.  We have to kill even if the host
 166		// matches, because all the agent state for the new camera is completely different.
 167		removeRegion(old_host);
 168	}
 169
 170	U32 iindex = 0;
 171	U32 jindex = 0;
 172	from_region_handle(region_handle, &iindex, &jindex);
 173	S32 x = (S32)(iindex/mWidth);
 174	S32 y = (S32)(jindex/mWidth);
 175	llinfos << "Adding new region (" << x << ":" << y << ")" << llendl;
 176	llinfos << "Host: " << host << llendl;
 177
 178	LLVector3d origin_global;
 179
 180	origin_global = from_region_handle(region_handle);
 181
 182	regionp = new LLViewerRegion(region_handle,
 183								    host,
 184									mWidth,
 185									WORLD_PATCH_SIZE,
 186									getRegionWidthInMeters() );
 187	if (!regionp)
 188	{
 189		llerrs << "Unable to create new region!" << llendl;
 190	}
 191
 192	mRegionList.push_back(regionp);
 193	mActiveRegionList.push_back(regionp);
 194	mCulledRegionList.push_back(regionp);
 195
 196
 197	// Find all the adjacent regions, and attach them.
 198	// Generate handles for all of the adjacent regions, and attach them in the correct way.
 199	// connect the edges
 200	F32 adj_x = 0.f;
 201	F32 adj_y = 0.f;
 202	F32 region_x = 0.f;
 203	F32 region_y = 0.f;
 204	U64 adj_handle = 0;
 205
 206	F32 width = getRegionWidthInMeters();
 207
 208	LLViewerRegion *neighborp;
 209	from_region_handle(region_handle, &region_x, &region_y);
 210
 211	// Iterate through all directions, and connect neighbors if there.
 212	S32 dir;
 213	for (dir = 0; dir < 8; dir++)
 214	{
 215		adj_x = region_x + width * gDirAxes[dir][0];
 216		adj_y = region_y + width * gDirAxes[dir][1];
 217		to_region_handle(adj_x, adj_y, &adj_handle);
 218
 219		neighborp = getRegionFromHandle(adj_handle);
 220		if (neighborp)
 221		{
 222			//llinfos << "Connecting " << region_x << ":" << region_y << " -> " << adj_x << ":" << adj_y << llendl;
 223			regionp->connectNeighbor(neighborp, dir);
 224		}
 225	}
 226
 227	updateWaterObjects();
 228
 229	return regionp;
 230}
 231
 232
 233void LLWorld::removeRegion(const LLHost &host)
 234{
 235	F32 x, y;
 236
 237	LLViewerRegion *regionp = getRegion(host);
 238	if (!regionp)
 239	{
 240		llwarns << "Trying to remove region that doesn't exist!" << llendl;
 241		return;
 242	}
 243	
 244	if (regionp == gAgent.getRegion())
 245	{
 246		for (region_list_t::iterator iter = mRegionList.begin();
 247			 iter != mRegionList.end(); ++iter)
 248		{
 249			LLViewerRegion* reg = *iter;
 250			llwarns << "RegionDump: " << reg->getName()
 251				<< " " << reg->getHost()
 252				<< " " << reg->getOriginGlobal()
 253				<< llendl;
 254		}
 255
 256		llwarns << "Agent position global " << gAgent.getPositionGlobal() 
 257			<< " agent " << gAgent.getPositionAgent()
 258			<< llendl;
 259
 260		llwarns << "Regions visited " << gAgent.getRegionsVisited() << llendl;
 261
 262		llwarns << "gFrameTimeSeconds " << gFrameTimeSeconds << llendl;
 263
 264		llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl;
 265		LLAppViewer::instance()->forceDisconnect(LLTrans::getString("YouHaveBeenDisconnected"));
 266
 267		regionp->saveObjectCache() ; //force to save objects here in case that the object cache is about to be destroyed.
 268		return;
 269	}
 270
 271	from_region_handle(regionp->getHandle(), &x, &y);
 272	llinfos << "Removing region " << x << ":" << y << llendl;
 273
 274	mRegionList.remove(regionp);
 275	mActiveRegionList.remove(regionp);
 276	mCulledRegionList.remove(regionp);
 277	mVisibleRegionList.remove(regionp);
 278	
 279	delete regionp;
 280
 281	updateWaterObjects();
 282
 283	//double check all objects of this region are removed.
 284	gObjectList.clearAllMapObjectsInRegion(regionp) ;
 285	//llassert_always(!gObjectList.hasMapObjectInRegion(regionp)) ;
 286}
 287
 288
 289LLViewerRegion* LLWorld::getRegion(const LLHost &host)
 290{
 291	for (region_list_t::iterator iter = mRegionList.begin();
 292		 iter != mRegionList.end(); ++iter)
 293	{
 294		LLViewerRegion* regionp = *iter;
 295		if (regionp->getHost() == host)
 296		{
 297			return regionp;
 298		}
 299	}
 300	return NULL;
 301}
 302
 303LLViewerRegion* LLWorld::getRegionFromPosAgent(const LLVector3 &pos)
 304{
 305	return getRegionFromPosGlobal(gAgent.getPosGlobalFromAgent(pos));
 306}
 307
 308LLViewerRegion* LLWorld::getRegionFromPosGlobal(const LLVector3d &pos)
 309{
 310	for (region_list_t::iterator iter = mRegionList.begin();
 311		 iter != mRegionList.end(); ++iter)
 312	{
 313		LLViewerRegion* regionp = *iter;
 314		if (regionp->pointInRegionGlobal(pos))
 315		{
 316			return regionp;
 317		}
 318	}
 319	return NULL;
 320}
 321
 322
 323LLVector3d	LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos)
 324{
 325	if (positionRegionValidGlobal(end_pos))
 326	{
 327		return end_pos;
 328	}
 329
 330	LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos);
 331	if (!regionp) 
 332	{
 333		return start_pos;
 334	}
 335
 336	LLVector3d delta_pos = end_pos - start_pos;
 337	LLVector3d delta_pos_abs;
 338	delta_pos_abs.setVec(delta_pos);
 339	delta_pos_abs.abs();
 340
 341	LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos);
 342	F64 clip_factor = 1.0;
 343	F32 region_width = regionp->getWidth();
 344	if (region_coord.mV[VX] < 0.f)
 345	{
 346		if (region_coord.mV[VY] < region_coord.mV[VX])
 347		{
 348			// clip along y -
 349			clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
 350		}
 351		else
 352		{
 353			// clip along x -
 354			clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]);
 355		}
 356	}
 357	else if (region_coord.mV[VX] > region_width)
 358	{
 359		if (region_coord.mV[VY] > region_coord.mV[VX])
 360		{
 361			// clip along y +
 362			clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
 363		}
 364		else
 365		{
 366			//clip along x +
 367			clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX];
 368		}
 369	}
 370	else if (region_coord.mV[VY] < 0.f)
 371	{
 372		// clip along y -
 373		clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
 374	}
 375	else if (region_coord.mV[VY] > region_width)
 376	{ 
 377		// clip along y +
 378		clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
 379	}
 380
 381	// clamp to within region dimensions
 382	LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
 383	final_region_pos.mdV[VX] = llclamp(final_region_pos.mdV[VX], 0.0,
 384									   (F64)(region_width - F_ALMOST_ZERO));
 385	final_region_pos.mdV[VY] = llclamp(final_region_pos.mdV[VY], 0.0,
 386									   (F64)(region_width - F_ALMOST_ZERO));
 387	final_region_pos.mdV[VZ] = llclamp(final_region_pos.mdV[VZ], 0.0,
 388									   (F64)(LLWorld::getInstance()->getRegionMaxHeight() - F_ALMOST_ZERO));
 389	return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos));
 390}
 391
 392LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
 393{
 394	for (region_list_t::iterator iter = mRegionList.begin();
 395		 iter != mRegionList.end(); ++iter)
 396	{
 397		LLViewerRegion* regionp = *iter;
 398		if (regionp->getHandle() == handle)
 399		{
 400			return regionp;
 401		}
 402	}
 403	return NULL;
 404}
 405
 406
 407void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
 408{
 409#if 0
 410	for (region_list_t::iterator iter = mRegionList.begin();
 411		 iter != mRegionList.end(); ++iter)
 412	{
 413		LLViewerRegion* regionp = *iter;
 414		regionp->setAgentOffset(offset_global);
 415	}
 416#endif
 417}
 418
 419
 420BOOL LLWorld::positionRegionValidGlobal(const LLVector3d &pos_global)
 421{
 422	for (region_list_t::iterator iter = mRegionList.begin();
 423		 iter != mRegionList.end(); ++iter)
 424	{
 425		LLViewerRegion* regionp = *iter;
 426		if (regionp->pointInRegionGlobal(pos_global))
 427		{
 428			return TRUE;
 429		}
 430	}
 431	return FALSE;
 432}
 433
 434
 435// Allow objects to go up to their radius underground.
 436F32 LLWorld::getMinAllowedZ(LLViewerObject* object, const LLVector3d &global_pos)
 437{
 438	F32 land_height = resolveLandHeightGlobal(global_pos);
 439	F32 radius = 0.5f * object->getScale().length();
 440	return land_height - radius;
 441}
 442
 443
 444
 445LLViewerRegion* LLWorld::resolveRegionGlobal(LLVector3 &pos_region, const LLVector3d &pos_global)
 446{
 447	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 448
 449	if (regionp)
 450	{
 451		pos_region = regionp->getPosRegionFromGlobal(pos_global);
 452		return regionp;
 453	}
 454
 455	return NULL;
 456}
 457
 458
 459LLViewerRegion* LLWorld::resolveRegionAgent(LLVector3 &pos_region, const LLVector3 &pos_agent)
 460{
 461	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
 462	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 463
 464	if (regionp)
 465	{
 466		pos_region = regionp->getPosRegionFromGlobal(pos_global);
 467		return regionp;
 468	}
 469
 470	return NULL;
 471}
 472
 473
 474F32 LLWorld::resolveLandHeightAgent(const LLVector3 &pos_agent)
 475{
 476	LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
 477	return resolveLandHeightGlobal(pos_global);
 478}
 479
 480
 481F32 LLWorld::resolveLandHeightGlobal(const LLVector3d &pos_global)
 482{
 483	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 484	if (regionp)
 485	{
 486		return regionp->getLand().resolveHeightGlobal(pos_global);
 487	}
 488	return 0.0f;
 489}
 490
 491
 492// Takes a line defined by "point_a" and "point_b" and determines the closest (to point_a) 
 493// point where the the line intersects an object or the land surface.  Stores the results
 494// in "intersection" and "intersection_normal" and returns a scalar value that represents
 495// the normalized distance along the line from "point_a" to "intersection".
 496//
 497// Currently assumes point_a and point_b only differ in z-direction, 
 498// but it may eventually become more general.
 499F32 LLWorld::resolveStepHeightGlobal(const LLVOAvatar* avatarp, const LLVector3d &point_a, const LLVector3d &point_b, 
 500							   LLVector3d &intersection, LLVector3 &intersection_normal,
 501							   LLViewerObject **viewerObjectPtr)
 502{
 503	// initialize return value to null
 504	if (viewerObjectPtr)
 505	{
 506		*viewerObjectPtr = NULL;
 507	}
 508
 509	LLViewerRegion *regionp = getRegionFromPosGlobal(point_a);
 510	if (!regionp)
 511	{
 512		// We're outside the world 
 513		intersection = 0.5f * (point_a + point_b);
 514		intersection_normal.setVec(0.0f, 0.0f, 1.0f);
 515		return 0.5f;
 516	}
 517	
 518	// calculate the length of the segment
 519	F32 segment_length = (F32)((point_a - point_b).length());
 520	if (0.0f == segment_length)
 521	{
 522		intersection = point_a;
 523		intersection_normal.setVec(0.0f, 0.0f, 1.0f);
 524		return segment_length;
 525	}
 526
 527	// get land height	
 528	// Note: we assume that the line is parallel to z-axis here
 529	LLVector3d land_intersection = point_a;
 530	F32 normalized_land_distance;
 531
 532	land_intersection.mdV[VZ] = regionp->getLand().resolveHeightGlobal(point_a);
 533	normalized_land_distance = (F32)(point_a.mdV[VZ] - land_intersection.mdV[VZ]) / segment_length;
 534	intersection = land_intersection;
 535	intersection_normal = resolveLandNormalGlobal(land_intersection);
 536
 537	if (avatarp && !avatarp->mFootPlane.isExactlyClear())
 538	{
 539		LLVector3 foot_plane_normal(avatarp->mFootPlane.mV);
 540		LLVector3 start_pt = avatarp->getRegion()->getPosRegionFromGlobal(point_a);
 541		// added 0.05 meters to compensate for error in foot plane reported by Havok
 542		F32 norm_dist_from_plane = ((start_pt * foot_plane_normal) - avatarp->mFootPlane.mV[VW]) + 0.05f;
 543		norm_dist_from_plane = llclamp(norm_dist_from_plane / segment_length, 0.f, 1.f);
 544		if (norm_dist_from_plane < normalized_land_distance)
 545		{
 546			// collided with object before land
 547			normalized_land_distance = norm_dist_from_plane;
 548			intersection = point_a;
 549			intersection.mdV[VZ] -= norm_dist_from_plane * segment_length;
 550			intersection_normal = foot_plane_normal;
 551		}
 552		else
 553		{
 554			intersection = land_intersection;
 555			intersection_normal = resolveLandNormalGlobal(land_intersection);
 556		}
 557	}
 558
 559	return normalized_land_distance;
 560}
 561
 562
 563LLSurfacePatch * LLWorld::resolveLandPatchGlobal(const LLVector3d &pos_global)
 564{
 565	//  returns a pointer to the patch at this location
 566	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 567	if (!regionp)
 568	{
 569		return NULL;
 570	}
 571
 572	return regionp->getLand().resolvePatchGlobal(pos_global);
 573}
 574
 575
 576LLVector3 LLWorld::resolveLandNormalGlobal(const LLVector3d &pos_global)
 577{
 578	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
 579	if (!regionp)
 580	{
 581		return LLVector3::z_axis;
 582	}
 583
 584	return regionp->getLand().resolveNormalGlobal(pos_global);
 585}
 586
 587
 588void LLWorld::updateVisibilities()
 589{
 590	F32 cur_far_clip = LLViewerCamera::getInstance()->getFar();
 591
 592	// Go through the culled list and check for visible regions (region is visible if land is visible)
 593	for (region_list_t::iterator iter = mCulledRegionList.begin();
 594		 iter != mCulledRegionList.end(); )
 595	{
 596		region_list_t::iterator curiter = iter++;
 597		LLViewerRegion* regionp = *curiter;
 598		
 599		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
 600		if (part)
 601		{
 602			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
 603			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
 604			{
 605				mCulledRegionList.erase(curiter);
 606				mVisibleRegionList.push_back(regionp);
 607			}
 608		}
 609	}
 610	
 611	// Update all of the visible regions 
 612	for (region_list_t::iterator iter = mVisibleRegionList.begin();
 613		 iter != mVisibleRegionList.end(); )
 614	{
 615		region_list_t::iterator curiter = iter++;
 616		LLViewerRegion* regionp = *curiter;
 617		if (!regionp->getLand().hasZData())
 618		{
 619			continue;
 620		}
 621
 622		LLSpatialPartition* part = regionp->getSpatialPartition(LLViewerRegion::PARTITION_TERRAIN);
 623		if (part)
 624		{
 625			LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0);
 626			if (LLViewerCamera::getInstance()->AABBInFrustum(group->mBounds[0], group->mBounds[1]))
 627			{
 628				regionp->calculateCameraDistance();
 629				regionp->getLand().updatePatchVisibilities(gAgent);
 630			}
 631			else
 632			{
 633				mVisibleRegionList.erase(curiter);
 634				mCulledRegionList.push_back(regionp);
 635			}
 636		}
 637	}
 638
 639	// Sort visible regions
 640	mVisibleRegionList.sort(LLViewerRegion::CompareDistance());
 641	
 642	LLViewerCamera::getInstance()->setFar(cur_far_clip);
 643}
 644
 645void LLWorld::updateRegions(F32 max_update_time)
 646{
 647	LLMemType mt_ur(LLMemType::MTYPE_IDLE_UPDATE_REGIONS);
 648	LLTimer update_timer;
 649	BOOL did_one = FALSE;
 650	
 651	// Perform idle time updates for the regions (and associated surfaces)
 652	for (region_list_t::iterator iter = mRegionList.begin();
 653		 iter != mRegionList.end(); ++iter)
 654	{
 655		LLViewerRegion* regionp = *iter;
 656		F32 max_time = max_update_time - update_timer.getElapsedTimeF32();
 657		if (did_one && max_time <= 0.f)
 658			break;
 659		max_time = llmin(max_time, max_update_time*.1f);
 660		did_one |= regionp->idleUpdate(max_update_time);
 661	}
 662}
 663
 664void LLWorld::updateParticles()
 665{
 666	LLViewerPartSim::getInstance()->updateSimulation();
 667}
 668
 669void LLWorld::renderPropertyLines()
 670{
 671	S32 region_count = 0;
 672	S32 vertex_count = 0;
 673
 674	for (region_list_t::iterator iter = mVisibleRegionList.begin();
 675		 iter != mVisibleRegionList.end(); ++iter)
 676	{
 677		LLViewerRegion* regionp = *iter;
 678		region_count++;
 679		vertex_count += regionp->renderPropertyLines();
 680	}
 681}
 682
 683
 684void LLWorld::updateNetStats()
 685{
 686	F32 bits = 0.f;
 687	U32 packets = 0;
 688
 689	for (region_list_t::iterator iter = mActiveRegionList.begin();
 690		 iter != mActiveRegionList.end(); ++iter)
 691	{
 692		LLViewerRegion* regionp = *iter;
 693		regionp->updateNetStats();
 694		bits += regionp->mBitStat.getCurrent();
 695		packets += llfloor( regionp->mPacketsStat.getCurrent() );
 696	}
 697
 698	S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn;
 699	S32 packets_out = gMessageSystem->mPacketsOut - mLastPacketsOut;
 700	S32 packets_lost = gMessageSystem->mDroppedPackets - mLastPacketsLost;
 701
 702	S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();
 703	S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits();
 704	LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f);
 705	LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f);
 706	LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f);
 707	LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
 708	LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
 709	LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
 710	if (packets_in)
 711	{
 712		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
 713	}
 714	else
 715	{
 716		LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);
 717	}
 718
 719	mLastPacketsIn = gMessageSystem->mPacketsIn;
 720	mLastPacketsOut = gMessageSystem->mPacketsOut;
 721	mLastPacketsLost = gMessageSystem->mDroppedPackets;
 722}
 723
 724
 725void LLWorld::printPacketsLost()
 726{
 727	llinfos << "Simulators:" << llendl;
 728	llinfos << "----------" << llendl;
 729
 730	LLCircuitData *cdp = NULL;
 731	for (region_list_t::iterator iter = mActiveRegionList.begin();
 732		 iter != mActiveRegionList.end(); ++iter)
 733	{
 734		LLViewerRegion* regionp = *iter;
 735		cdp = gMessageSystem->mCircuitInfo.findCircuit(regionp->getHost());
 736		if (cdp)
 737		{
 738			LLVector3d range = regionp->getCenterGlobal() - gAgent.getPositionGlobal();
 739				
 740			llinfos << regionp->getHost() << ", range: " << range.length()
 741					<< " packets lost: " << cdp->getPacketsLost() << llendl;
 742		}
 743	}
 744}
 745
 746void LLWorld::processCoarseUpdate(LLMessageSystem* msg, void** user_data)
 747{
 748	LLViewerRegion* region = LLWorld::getInstance()->getRegion(msg->getSender());
 749	if( region )
 750	{
 751		region->updateCoarseLocations(msg);
 752	}
 753}
 754
 755F32 LLWorld::getLandFarClip() const
 756{
 757	return mLandFarClip;
 758}
 759
 760void LLWorld::setLandFarClip(const F32 far_clip)
 761{
 762	static S32 const rwidth = (S32)REGION_WIDTH_U32;
 763	S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
 764	S32 const n2 = (llceil(far_clip) - 1) / rwidth;
 765	bool need_water_objects_update = n1 != n2;
 766
 767	mLandFarClip = far_clip;
 768
 769	if (need_water_objects_update)
 770	{
 771		updateWaterObjects();
 772	}
 773}
 774
 775// Some region that we're connected to, but not the one we're in, gave us
 776// a (possibly) new water height. Update it in our local copy.
 777void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_height)
 778{
 779	for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter)
 780	{
 781		if ((*iter)->getName() == sim_name)
 782		{
 783			(*iter)->setWaterHeight(water_height);
 784			break;
 785		}
 786	}
 787}
 788
 789void LLWorld::updateWaterObjects()
 790{
 791	if (!gAgent.getRegion())
 792	{
 793		return;
 794	}
 795	if (mRegionList.empty())
 796	{
 797		llwarns << "No regions!" << llendl;
 798		return;
 799	}
 800
 801	// First, determine the min and max "box" of water objects
 802	S32 min_x = 0;
 803	S32 min_y = 0;
 804	S32 max_x = 0;
 805	S32 max_y = 0;
 806	U32 region_x, region_y;
 807
 808	S32 rwidth = 256;
 809
 810	// We only want to fill in water for stuff that's near us, say, within 256 or 512m
 811	S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256;
 812
 813	LLViewerRegion* regionp = gAgent.getRegion();
 814	from_region_handle(regionp->getHandle(), &region_x, &region_y);
 815
 816	min_x = (S32)region_x - range;
 817	min_y = (S32)region_y - range;
 818	max_x = (S32)region_x + range;
 819	max_y = (S32)region_y + range;
 820
 821	for (region_list_t::iterator iter = mRegionList.begin();
 822		 iter != mRegionList.end(); ++iter)
 823	{
 824		LLViewerRegion* regionp = *iter;
 825		LLVOWater* waterp = regionp->getLand().getWaterObj();
 826		if (waterp)
 827		{
 828			gObjectList.updateActive(waterp);
 829		}
 830	}
 831
 832	for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin();
 833		 iter != mHoleWaterObjects.end(); ++ iter)
 834	{
 835		LLVOWater* waterp = *iter;
 836		gObjectList.killObject(waterp);
 837	}
 838	mHoleWaterObjects.clear();
 839
 840	// Now, get a list of the holes
 841	S32 x, y;
 842	F32 water_height = gAgent.getRegion()->getWaterHeight() + 256.f;
 843	for (x = min_x; x <= max_x; x += rwidth)
 844	{
 845		for (y = min_y; y <= max_y; y += rwidth)
 846		{
 847			U64 region_handle = to_region_handle(x, y);
 848			if (!getRegionFromHandle(region_handle))
 849			{
 850				LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
 851				waterp->setUseTexture(FALSE);
 852				waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
 853													 y + rwidth/2,
 854													 water_height));
 855				waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
 856				gPipeline.createObject(waterp);
 857				mHoleWaterObjects.push_back(waterp);
 858			}
 859		}
 860	}
 861
 862	// Update edge water objects
 863	S32 wx, wy;
 864	S32 center_x, center_y;
 865	wx = (max_x - min_x) + rwidth;
 866	wy = (max_y - min_y) + rwidth;
 867	center_x = min_x + (wx >> 1);
 868	center_y = min_y + (wy >> 1);
 869
 870	S32 add_boundary[4] = {
 871		512 - (max_x - region_x),
 872		512 - (max_y - region_y),
 873		512 - (region_x - min_x),
 874		512 - (region_y - min_y) };
 875		
 876	S32 dir;
 877	for (dir = 0; dir < 8; dir++)
 878	{
 879		S32 dim[2] = { 0 };
 880		switch (gDirAxes[dir][0])
 881		{
 882		case -1: dim[0] = add_boundary[2]; break;
 883		case  0: dim[0] = wx; break;
 884		default: dim[0] = add_boundary[0]; break;
 885		}
 886		switch (gDirAxes[dir][1])
 887		{
 888		case -1: dim[1] = add_boundary[3]; break;
 889		case  0: dim[1] = wy; break;
 890		default: dim[1] = add_boundary[1]; break;
 891		}
 892
 893		// Resize and reshape the water objects
 894		const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]);
 895		const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]);
 896		
 897		LLVOWater* waterp = mEdgeWaterObjects[dir];
 898		if (!waterp || waterp->isDead())
 899		{
 900			// The edge water objects can be dead because they're attached to the region that the
 901			// agent was in when they were originally created.
 902			mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_VOID_WATER,
 903																				 gAgent.getRegion());
 904			waterp = mEdgeWaterObjects[dir];
 905			waterp->setUseTexture(FALSE);
 906			waterp->setIsEdgePatch(TRUE);
 907			gPipeline.createObject(waterp);
 908		}
 909
 910		waterp->setRegion(gAgent.getRegion());
 911		LLVector3d water_pos(water_center_x, water_center_y, water_height) ;
 912		LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
 913
 914		//stretch out to horizon
 915		water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]);
 916		water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]);
 917
 918		water_pos.mdV[0] += 1024.f * gDirAxes[dir][0];
 919		water_pos.mdV[1] += 1024.f * gDirAxes[dir][1];
 920
 921		waterp->setPositionGlobal(water_pos);
 922		waterp->setScale(water_scale);
 923
 924		gObjectList.updateActive(waterp);
 925	}
 926}
 927
 928
 929void LLWorld::shiftRegions(const LLVector3& offset)
 930{
 931	for (region_list_t::const_iterator i = getRegionList().begin(); i != getRegionList().end(); ++i)
 932	{
 933		LLViewerRegion* region = *i;
 934		region->updateRenderMatrix();
 935	}
 936
 937	LLViewerPartSim::getInstance()->shift(offset);
 938}
 939
 940LLViewerTexture* LLWorld::getDefaultWaterTexture()
 941{
 942	return mDefaultWaterTexturep;
 943}
 944
 945void LLWorld::setSpaceTimeUSec(const U64 space_time_usec)
 946{
 947	mSpaceTimeUSec = space_time_usec;
 948}
 949
 950U64 LLWorld::getSpaceTimeUSec() const
 951{
 952	return mSpaceTimeUSec;
 953}
 954
 955void LLWorld::requestCacheMisses()
 956{
 957	for (region_list_t::iterator iter = mRegionList.begin();
 958		 iter != mRegionList.end(); ++iter)
 959	{
 960		LLViewerRegion* regionp = *iter;
 961		regionp->requestCacheMisses();
 962	}
 963}
 964
 965void LLWorld::getInfo(LLSD& info)
 966{
 967	LLSD region_info;
 968	for (region_list_t::iterator iter = mRegionList.begin();
 969		 iter != mRegionList.end(); ++iter)
 970	{	
 971		LLViewerRegion* regionp = *iter;
 972		regionp->getInfo(region_info);
 973		info["World"].append(region_info);
 974	}
 975}
 976
 977void LLWorld::disconnectRegions()
 978{
 979	LLMessageSystem* msg = gMessageSystem;
 980	for (region_list_t::iterator iter = mRegionList.begin();
 981		 iter != mRegionList.end(); ++iter)
 982	{
 983		LLViewerRegion* regionp = *iter;
 984		if (regionp == gAgent.getRegion())
 985		{
 986			// Skip the main agent
 987			continue;
 988		}
 989
 990		llinfos << "Sending AgentQuitCopy to: " << regionp->getHost() << llendl;
 991		msg->newMessageFast(_PREHASH_AgentQuitCopy);
 992		msg->nextBlockFast(_PREHASH_AgentData);
 993		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 994		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 995		msg->nextBlockFast(_PREHASH_FuseBlock);
 996		msg->addU32Fast(_PREHASH_ViewerCircuitCode, gMessageSystem->mOurCircuitCode);
 997		msg->sendMessage(regionp->getHost());
 998	}
 999}
1000
1001static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim");
1002
1003void process_enable_simulator(LLMessageSystem *msg, void **user_data)
1004{
1005	LLFastTimer t(FTM_ENABLE_SIMULATOR);
1006	// enable the appropriate circuit for this simulator and 
1007	// add its values into the gSimulator structure
1008	U64		handle;
1009	U32		ip_u32;
1010	U16		port;
1011
1012	msg->getU64Fast(_PREHASH_SimulatorInfo, _PREHASH_Handle, handle);
1013	msg->getIPAddrFast(_PREHASH_SimulatorInfo, _PREHASH_IP, ip_u32);
1014	msg->getIPPortFast(_PREHASH_SimulatorInfo, _PREHASH_Port, port);
1015
1016	// which simulator should we modify?
1017	LLHost sim(ip_u32, port);
1018
1019	// Viewer trusts the simulator.
1020	msg->enableCircuit(sim, TRUE);
1021	LLWorld::getInstance()->addRegion(handle, sim);
1022
1023	// give the simulator a message it can use to get ip and port
1024	llinfos << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << llendl;
1025	msg->newMessageFast(_PREHASH_UseCircuitCode);
1026	msg->nextBlockFast(_PREHASH_CircuitCode);
1027	msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode());
1028	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
1029	msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
1030	msg->sendReliable(sim);
1031}
1032
1033class LLEstablishAgentCommunication : public LLHTTPNode
1034{
1035	LOG_CLASS(LLEstablishAgentCommunication);
1036public:
1037 	virtual void describe(Description& desc) const
1038	{
1039		desc.shortInfo("seed capability info for a region");
1040		desc.postAPI();
1041		desc.input(
1042			"{ seed-capability: ..., sim-ip: ..., sim-port }");
1043		desc.source(__FILE__, __LINE__);
1044	}
1045
1046	virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const
1047	{
1048		if (!input["body"].has("agent-id") ||
1049			!input["body"].has("sim-ip-and-port") ||
1050			!input["body"].has("seed-capability"))
1051		{
1052			llwarns << "invalid parameters" << llendl;
1053            return;
1054		}
1055
1056		LLHost sim(input["body"]["sim-ip-and-port"].asString());
1057	
1058		LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim);
1059		if (!regionp)
1060		{
1061			llwarns << "Got EstablishAgentCommunication for unknown region "
1062					<< sim << llendl;
1063			return;
1064		}
1065		regionp->setSeedCapability(input["body"]["seed-capability"]);
1066	}
1067};
1068
1069// disable the circuit to this simulator
1070// Called in response to "DisableSimulator" message.
1071void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data)
1072{	
1073	LLHost host = mesgsys->getSender();
1074
1075	//llinfos << "Disabling simulator with message from " << host << llendl;
1076	LLWorld::getInstance()->removeRegion(host);
1077
1078	mesgsys->disableCircuit(host);
1079}
1080
1081
1082void process_region_handshake(LLMessageSystem* msg, void** user_data)
1083{
1084	LLHost host = msg->getSender();
1085	LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(host);
1086	if (!regionp)
1087	{
1088		llwarns << "Got region handshake for unknown region "
1089			<< host << llendl;
1090		return;
1091	}
1092
1093	regionp->unpackRegionHandshake();
1094}
1095
1096
1097void send_agent_pause()
1098{
1099	// *NOTE:Mani Pausing the mainloop timeout. Otherwise a long modal event may cause
1100	// the thread monitor to timeout.
1101	LLAppViewer::instance()->pauseMainloopTimeout();
1102	
1103	// Note: used to check for LLWorld initialization before it became a singleton.
1104	// Rather than just remove this check I'm changing it to assure that the message 
1105	// system has been initialized. -MG
1106	if (!gMessageSystem)
1107	{
1108		return;
1109	}
1110	
1111	gMessageSystem->newMessageFast(_PREHASH_AgentPause);
1112	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
1113	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
1114	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
1115
1116	gAgentPauseSerialNum++;
1117	gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum);
1118
1119	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1120		 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1121	{
1122		LLViewerRegion* regionp = *iter;
1123		gMessageSystem->sendReliable(regionp->getHost());
1124	}
1125
1126	gObjectList.mWasPaused = TRUE;
1127}
1128
1129
1130void send_agent_resume()
1131{
1132	// Note: used to check for LLWorld initialization before it became a singleton.
1133	// Rather than just remove this check I'm changing it to assure that the message 
1134	// system has been initialized. -MG
1135	if (!gMessageSystem)
1136	{
1137		return;
1138	}
1139
1140	gMessageSystem->newMessageFast(_PREHASH_AgentResume);
1141	gMessageSystem->nextBlockFast(_PREHASH_AgentData);
1142	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
1143	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
1144
1145	gAgentPauseSerialNum++;
1146	gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum);
1147	
1148
1149	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1150		 iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1151	{
1152		LLViewerRegion* regionp = *iter;
1153		gMessageSystem->sendReliable(regionp->getHost());
1154	}
1155
1156	// Reset the FPS counter to avoid an invalid fps
1157	LLViewerStats::getInstance()->mFPSStat.start();
1158
1159	LLAppViewer::instance()->resumeMainloopTimeout();
1160}
1161
1162static LLVector3d unpackLocalToGlobalPosition(U32 compact_local, const LLVector3d& region_origin)
1163{
1164	LLVector3d pos_global;
1165	LLVector3 pos_local;
1166	U8 bits;
1167
1168	bits = compact_local & 0xFF;
1169	pos_local.mV[VZ] = F32(bits) * 4.f;
1170	compact_local >>= 8;
1171
1172	bits = compact_local & 0xFF;
1173	pos_local.mV[VY] = (F32)bits;
1174	compact_local >>= 8;
1175
1176	bits = compact_local & 0xFF;
1177	pos_local.mV[VX] = (F32)bits;
1178
1179	pos_global.setVec( pos_local );
1180	pos_global += region_origin;
1181	return pos_global;
1182}
1183
1184void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positions, const LLVector3d& relative_to, F32 radius) const
1185{
1186	F32 radius_squared = radius * radius;
1187	
1188	if(avatar_ids != NULL)
1189	{
1190		avatar_ids->clear();
1191	}
1192	if(positions != NULL)
1193	{
1194		positions->clear();
1195	}
1196	// get the list of avatars from the character list first, so distances are correct
1197	// when agent is above 1020m and other avatars are nearby
1198	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
1199		iter != LLCharacter::sInstances.end(); ++iter)
1200	{
1201		LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter;
1202		if(!pVOAvatar->isDead() && !pVOAvatar->isSelf())
1203		{
1204			LLUUID uuid = pVOAvatar->getID();
1205			if(!uuid.isNull())
1206			{
1207				LLVector3d pos_global = pVOAvatar->getPositionGlobal();
1208				if(dist_vec_squared(pos_global, relative_to) <= radius_squared)
1209				{
1210					if(positions != NULL)
1211					{
1212						positions->push_back(pos_global);
1213					}
1214					if(avatar_ids !=NULL)
1215					{
1216						avatar_ids->push_back(uuid);
1217					}
1218				}
1219			}
1220		}
1221	}
1222	// region avatars added for situations where radius is greater than RenderFarClip
1223	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
1224		iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
1225	{
1226		LLViewerRegion* regionp = *iter;
1227		const LLVector3d& origin_global = regionp->getOriginGlobal();
1228		S32 count = regionp->mMapAvatars.count();
1229		for (S32 i = 0; i < count; i++)
1230		{
1231			LLVector3d pos_global = unpackLocalToGlobalPosition(regionp->mMapAvatars.get(i), origin_global);
1232			if(dist_vec_squared(pos_global, relative_to) <= radius_squared)
1233			{
1234				LLUUID uuid = regionp->mMapAvatarIDs.get(i);
1235				// if this avatar doesn't already exist in the list, add it
1236				if(uuid.notNull() && avatar_ids!=NULL && std::find(avatar_ids->begin(), avatar_ids->end(), uuid) == avatar_ids->end())
1237				{
1238					if(positions != NULL)
1239					{
1240						positions->push_back(pos_global);
1241					}
1242					avatar_ids->push_back(uuid);
1243				}
1244			}
1245		}
1246	}
1247}
1248
1249
1250LLHTTPRegistration<LLEstablishAgentCommunication>
1251	gHTTPRegistrationEstablishAgentCommunication(
1252							"/message/EstablishAgentCommunication");