00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llworld.h"
00035
00036 #include "indra_constants.h"
00037 #include "llstl.h"
00038
00039 #include "llagent.h"
00040 #include "llviewercontrol.h"
00041 #include "lldrawpool.h"
00042 #include "llglheaders.h"
00043 #include "llhttpnode.h"
00044 #include "llregionhandle.h"
00045 #include "llsurface.h"
00046 #include "llviewercamera.h"
00047 #include "llviewerimage.h"
00048 #include "llviewerimagelist.h"
00049 #include "llviewernetwork.h"
00050 #include "llviewerobjectlist.h"
00051 #include "llviewerparceloverlay.h"
00052 #include "llviewerregion.h"
00053 #include "llviewerstats.h"
00054 #include "llvlcomposition.h"
00055 #include "llvoavatar.h"
00056 #include "llvowater.h"
00057 #include "message.h"
00058 #include "pipeline.h"
00059 #include "llappviewer.h"
00060
00061
00062
00063
00064 U32 gAgentPauseSerialNum = 0;
00065
00066
00067
00068
00069 const S32 MAX_NUMBER_OF_CLOUDS = 750;
00070 const S32 WORLD_PATCH_SIZE = 16;
00071
00072 extern LLColor4U MAX_WATER_COLOR;
00073
00074 const U32 LLWorld::mWidth = 256;
00075
00076
00077 const F32 LLWorld::mScale = 1.f;
00078
00079 const F32 LLWorld::mWidthInMeters = mWidth * mScale;
00080
00081
00082
00083
00084
00085
00086 LLWorld::LLWorld() :
00087 mLandFarClip(DEFAULT_FAR_PLANE),
00088 mLastPacketsIn(0),
00089 mLastPacketsOut(0),
00090 mLastPacketsLost(0),
00091 mMinRegionX(0),
00092 mMaxRegionX(0),
00093 mMinRegionY(0),
00094 mMaxRegionY(0),
00095 mSpaceTimeUSec(0)
00096 {
00097 for (S32 i = 0; i < 8; i++)
00098 {
00099 mEdgeWaterObjects[i] = NULL;
00100 }
00101
00102 if (gNoRender)
00103 {
00104 return;
00105 }
00106
00107 LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4);
00108 U8 *default_texture = raw->getData();
00109 *(default_texture++) = MAX_WATER_COLOR.mV[0];
00110 *(default_texture++) = MAX_WATER_COLOR.mV[1];
00111 *(default_texture++) = MAX_WATER_COLOR.mV[2];
00112 *(default_texture++) = MAX_WATER_COLOR.mV[3];
00113
00114 mDefaultWaterTexturep = new LLViewerImage(raw, FALSE);
00115 mDefaultWaterTexturep->bind();
00116 mDefaultWaterTexturep->setClamp(TRUE, TRUE);
00117
00118 }
00119
00120
00121 void LLWorld::destroyClass()
00122 {
00123 gObjectList.destroy();
00124 for(region_list_t::iterator region_it = mRegionList.begin(); region_it != mRegionList.end(); )
00125 {
00126 LLViewerRegion* region_to_delete = *region_it++;
00127 removeRegion(region_to_delete->getHost());
00128 }
00129 LLViewerPartSim::getInstance()->destroyClass();
00130 }
00131
00132
00133 LLViewerRegion* LLWorld::addRegion(const U64 ®ion_handle, const LLHost &host)
00134 {
00135 LLMemType mt(LLMemType::MTYPE_REGIONS);
00136
00137 LLViewerRegion *regionp = getRegionFromHandle(region_handle);
00138 if (regionp)
00139 {
00140 LLHost old_host = regionp->getHost();
00141
00142 if (host == old_host && regionp->mAlive)
00143 {
00144
00145 return regionp;
00146 }
00147
00148 if (host != old_host)
00149 {
00150 llwarns << "LLWorld::addRegion exists, but old host " << old_host
00151 << " does not match new host " << host << llendl;
00152 }
00153 if (!regionp->mAlive)
00154 {
00155 llwarns << "LLWorld::addRegion exists, but isn't alive" << llendl;
00156 }
00157
00158
00159
00160 removeRegion(old_host);
00161 }
00162
00163 U32 iindex = 0;
00164 U32 jindex = 0;
00165 from_region_handle(region_handle, &iindex, &jindex);
00166 S32 x = (S32)(iindex/mWidth);
00167 S32 y = (S32)(jindex/mWidth);
00168 llinfos << "Adding new region (" << x << ":" << y << ")" << llendl;
00169 llinfos << "Host: " << host << llendl;
00170
00171 LLVector3d origin_global;
00172
00173 origin_global = from_region_handle(region_handle);
00174
00175 regionp = new LLViewerRegion(region_handle,
00176 host,
00177 mWidth,
00178 WORLD_PATCH_SIZE,
00179 getRegionWidthInMeters() );
00180 if (!regionp)
00181 {
00182 llerrs << "Unable to create new region!" << llendl;
00183 }
00184
00185 regionp->mCloudLayer.create(regionp);
00186 regionp->mCloudLayer.setWidth((F32)mWidth);
00187 regionp->mCloudLayer.setWindPointer(®ionp->mWind);
00188
00189 mRegionList.push_back(regionp);
00190 mActiveRegionList.push_back(regionp);
00191 mCulledRegionList.push_back(regionp);
00192
00193
00194
00195
00196
00197 F32 adj_x = 0.f;
00198 F32 adj_y = 0.f;
00199 F32 region_x = 0.f;
00200 F32 region_y = 0.f;
00201 U64 adj_handle = 0;
00202
00203 F32 width = getRegionWidthInMeters();
00204
00205 LLViewerRegion *neighborp;
00206 from_region_handle(region_handle, ®ion_x, ®ion_y);
00207
00208
00209 S32 dir;
00210 for (dir = 0; dir < 8; dir++)
00211 {
00212 adj_x = region_x + width * gDirAxes[dir][0];
00213 adj_y = region_y + width * gDirAxes[dir][1];
00214 to_region_handle(adj_x, adj_y, &adj_handle);
00215
00216 neighborp = getRegionFromHandle(adj_handle);
00217 if (neighborp)
00218 {
00219
00220 regionp->connectNeighbor(neighborp, dir);
00221 }
00222 }
00223
00224 updateWaterObjects();
00225
00226 return regionp;
00227 }
00228
00229
00230 void LLWorld::removeRegion(const LLHost &host)
00231 {
00232 F32 x, y;
00233
00234 LLViewerRegion *regionp = getRegion(host);
00235 if (!regionp)
00236 {
00237 llwarns << "Trying to remove region that doesn't exist!" << llendl;
00238 return;
00239 }
00240
00241 if (regionp == gAgent.getRegion())
00242 {
00243 for (region_list_t::iterator iter = mRegionList.begin();
00244 iter != mRegionList.end(); ++iter)
00245 {
00246 LLViewerRegion* reg = *iter;
00247 llwarns << "RegionDump: " << reg->getName()
00248 << " " << reg->getHost()
00249 << " " << reg->getOriginGlobal()
00250 << llendl;
00251 }
00252
00253 llwarns << "Agent position global " << gAgent.getPositionGlobal()
00254 << " agent " << gAgent.getPositionAgent()
00255 << llendl;
00256
00257 llwarns << "Regions visited " << gAgent.getRegionsVisited() << llendl;
00258
00259 llwarns << "gFrameTimeSeconds " << gFrameTimeSeconds << llendl;
00260
00261 llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl;
00262 LLAppViewer::instance()->forceDisconnect("You have been disconnected from the region you were in.");
00263 return;
00264 }
00265
00266 from_region_handle(regionp->getHandle(), &x, &y);
00267 llinfos << "Removing region " << x << ":" << y << llendl;
00268
00269 mRegionList.remove(regionp);
00270 mActiveRegionList.remove(regionp);
00271 mCulledRegionList.remove(regionp);
00272 mVisibleRegionList.remove(regionp);
00273
00274 delete regionp;
00275
00276 updateWaterObjects();
00277 }
00278
00279
00280 LLViewerRegion* LLWorld::getRegion(const LLHost &host)
00281 {
00282 for (region_list_t::iterator iter = mRegionList.begin();
00283 iter != mRegionList.end(); ++iter)
00284 {
00285 LLViewerRegion* regionp = *iter;
00286 if (regionp->getHost() == host)
00287 {
00288 return regionp;
00289 }
00290 }
00291 return NULL;
00292 }
00293
00294 LLViewerRegion* LLWorld::getRegionFromPosAgent(const LLVector3 &pos)
00295 {
00296 return getRegionFromPosGlobal(gAgent.getPosGlobalFromAgent(pos));
00297 }
00298
00299 LLViewerRegion* LLWorld::getRegionFromPosGlobal(const LLVector3d &pos)
00300 {
00301 for (region_list_t::iterator iter = mRegionList.begin();
00302 iter != mRegionList.end(); ++iter)
00303 {
00304 LLViewerRegion* regionp = *iter;
00305 if (regionp->pointInRegionGlobal(pos))
00306 {
00307 return regionp;
00308 }
00309 }
00310 return NULL;
00311 }
00312
00313
00314 LLVector3d LLWorld::clipToVisibleRegions(const LLVector3d &start_pos, const LLVector3d &end_pos)
00315 {
00316 if (positionRegionValidGlobal(end_pos))
00317 {
00318 return end_pos;
00319 }
00320
00321 LLViewerRegion* regionp = getRegionFromPosGlobal(start_pos);
00322 if (!regionp)
00323 {
00324 return start_pos;
00325 }
00326
00327 LLVector3d delta_pos = end_pos - start_pos;
00328 LLVector3d delta_pos_abs;
00329 delta_pos_abs.setVec(delta_pos);
00330 delta_pos_abs.abs();
00331
00332 LLVector3 region_coord = regionp->getPosRegionFromGlobal(end_pos);
00333 F64 clip_factor = 1.0;
00334 F32 region_width = regionp->getWidth();
00335 if (region_coord.mV[VX] < 0.f)
00336 {
00337 if (region_coord.mV[VY] < region_coord.mV[VX])
00338 {
00339
00340 clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
00341 }
00342 else
00343 {
00344
00345 clip_factor = -(region_coord.mV[VX] / delta_pos_abs.mdV[VX]);
00346 }
00347 }
00348 else if (region_coord.mV[VX] > region_width)
00349 {
00350 if (region_coord.mV[VY] > region_coord.mV[VX])
00351 {
00352
00353 clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
00354 }
00355 else
00356 {
00357
00358 clip_factor = (region_coord.mV[VX] - region_width) / delta_pos_abs.mdV[VX];
00359 }
00360 }
00361 else if (region_coord.mV[VY] < 0.f)
00362 {
00363
00364 clip_factor = -(region_coord.mV[VY] / delta_pos_abs.mdV[VY]);
00365 }
00366 else if (region_coord.mV[VY] > region_width)
00367 {
00368
00369 clip_factor = (region_coord.mV[VY] - region_width) / delta_pos_abs.mdV[VY];
00370 }
00371
00372
00373 LLVector3d final_region_pos = LLVector3d(region_coord) - (delta_pos * clip_factor);
00374 final_region_pos.clamp(0.0, 255.999);
00375 return regionp->getPosGlobalFromRegion(LLVector3(final_region_pos));
00376 }
00377
00378 LLViewerRegion* LLWorld::getRegionFromHandle(const U64 &handle)
00379 {
00380 for (region_list_t::iterator iter = mRegionList.begin();
00381 iter != mRegionList.end(); ++iter)
00382 {
00383 LLViewerRegion* regionp = *iter;
00384 if (regionp->getHandle() == handle)
00385 {
00386 return regionp;
00387 }
00388 }
00389 return NULL;
00390 }
00391
00392
00393 void LLWorld::updateAgentOffset(const LLVector3d &offset_global)
00394 {
00395 #if 0
00396 for (region_list_t::iterator iter = mRegionList.begin();
00397 iter != mRegionList.end(); ++iter)
00398 {
00399 LLViewerRegion* regionp = *iter;
00400 regionp->setAgentOffset(offset_global);
00401 }
00402 #endif
00403 }
00404
00405
00406 BOOL LLWorld::positionRegionValidGlobal(const LLVector3d &pos_global)
00407 {
00408 for (region_list_t::iterator iter = mRegionList.begin();
00409 iter != mRegionList.end(); ++iter)
00410 {
00411 LLViewerRegion* regionp = *iter;
00412 if (regionp->pointInRegionGlobal(pos_global))
00413 {
00414 return TRUE;
00415 }
00416 }
00417 return FALSE;
00418 }
00419
00420
00421
00422 F32 LLWorld::getMinAllowedZ(LLViewerObject* object)
00423 {
00424 F32 land_height = resolveLandHeightGlobal(object->getPositionGlobal());
00425 F32 radius = 0.5f * object->getScale().magVec();
00426 return land_height - radius;
00427 }
00428
00429
00430 LLViewerRegion* LLWorld::resolveRegionGlobal(LLVector3 &pos_region, const LLVector3d &pos_global)
00431 {
00432 LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
00433
00434 if (regionp)
00435 {
00436 pos_region = regionp->getPosRegionFromGlobal(pos_global);
00437 return regionp;
00438 }
00439
00440 return NULL;
00441 }
00442
00443
00444 LLViewerRegion* LLWorld::resolveRegionAgent(LLVector3 &pos_region, const LLVector3 &pos_agent)
00445 {
00446 LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
00447 LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
00448
00449 if (regionp)
00450 {
00451 pos_region = regionp->getPosRegionFromGlobal(pos_global);
00452 return regionp;
00453 }
00454
00455 return NULL;
00456 }
00457
00458
00459 F32 LLWorld::resolveLandHeightAgent(const LLVector3 &pos_agent)
00460 {
00461 LLVector3d pos_global = gAgent.getPosGlobalFromAgent(pos_agent);
00462 return resolveLandHeightGlobal(pos_global);
00463 }
00464
00465
00466 F32 LLWorld::resolveLandHeightGlobal(const LLVector3d &pos_global)
00467 {
00468 LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
00469 if (regionp)
00470 {
00471 return regionp->getLand().resolveHeightGlobal(pos_global);
00472 }
00473 return 0.0f;
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484 F32 LLWorld::resolveStepHeightGlobal(const LLVOAvatar* avatarp, const LLVector3d &point_a, const LLVector3d &point_b,
00485 LLVector3d &intersection, LLVector3 &intersection_normal,
00486 LLViewerObject **viewerObjectPtr)
00487 {
00488
00489 if (viewerObjectPtr)
00490 {
00491 *viewerObjectPtr = NULL;
00492 }
00493
00494 LLViewerRegion *regionp = getRegionFromPosGlobal(point_a);
00495 if (!regionp)
00496 {
00497
00498 intersection = 0.5f * (point_a + point_b);
00499 intersection_normal.setVec(0.0f, 0.0f, 1.0f);
00500 return 0.5f;
00501 }
00502
00503
00504 F32 segment_length = (F32)((point_a - point_b).magVec());
00505 if (0.0f == segment_length)
00506 {
00507 intersection = point_a;
00508 intersection_normal.setVec(0.0f, 0.0f, 1.0f);
00509 return segment_length;
00510 }
00511
00512
00513
00514 LLVector3d land_intersection = point_a;
00515 F32 normalized_land_distance;
00516
00517 land_intersection.mdV[VZ] = regionp->getLand().resolveHeightGlobal(point_a);
00518 normalized_land_distance = (F32)(point_a.mdV[VZ] - land_intersection.mdV[VZ]) / segment_length;
00519 intersection = land_intersection;
00520 intersection_normal = resolveLandNormalGlobal(land_intersection);
00521
00522 if (avatarp && !avatarp->mFootPlane.isExactlyClear())
00523 {
00524 LLVector3 foot_plane_normal(avatarp->mFootPlane.mV);
00525 LLVector3 start_pt = avatarp->getRegion()->getPosRegionFromGlobal(point_a);
00526
00527 F32 norm_dist_from_plane = ((start_pt * foot_plane_normal) - avatarp->mFootPlane.mV[VW]) + 0.05f;
00528 norm_dist_from_plane = llclamp(norm_dist_from_plane / segment_length, 0.f, 1.f);
00529 if (norm_dist_from_plane < normalized_land_distance)
00530 {
00531
00532 normalized_land_distance = norm_dist_from_plane;
00533 intersection = point_a;
00534 intersection.mdV[VZ] -= norm_dist_from_plane * segment_length;
00535 intersection_normal = foot_plane_normal;
00536 }
00537 else
00538 {
00539 intersection = land_intersection;
00540 intersection_normal = resolveLandNormalGlobal(land_intersection);
00541 }
00542 }
00543
00544 return normalized_land_distance;
00545 }
00546
00547
00548 LLSurfacePatch * LLWorld::resolveLandPatchGlobal(const LLVector3d &pos_global)
00549 {
00550
00551 LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
00552 if (!regionp)
00553 {
00554 return NULL;
00555 }
00556
00557 return regionp->getLand().resolvePatchGlobal(pos_global);
00558 }
00559
00560
00561 LLVector3 LLWorld::resolveLandNormalGlobal(const LLVector3d &pos_global)
00562 {
00563 LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
00564 if (!regionp)
00565 {
00566 return LLVector3::z_axis;
00567 }
00568
00569 return regionp->getLand().resolveNormalGlobal(pos_global);
00570 }
00571
00572
00573 void LLWorld::updateVisibilities()
00574 {
00575 F32 cur_far_clip = LLViewerCamera::getInstance()->getFar();
00576
00577 LLViewerCamera::getInstance()->setFar(mLandFarClip);
00578
00579 F32 diagonal_squared = F_SQRT2 * F_SQRT2 * mWidth * mWidth;
00580
00581 for (region_list_t::iterator iter = mCulledRegionList.begin();
00582 iter != mCulledRegionList.end(); )
00583 {
00584 region_list_t::iterator curiter = iter++;
00585 LLViewerRegion* regionp = *curiter;
00586 F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ();
00587 F32 radius = 0.5f*fsqrtf(height * height + diagonal_squared);
00588 if (!regionp->getLand().hasZData()
00589 || LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius))
00590 {
00591 mCulledRegionList.erase(curiter);
00592 mVisibleRegionList.push_back(regionp);
00593 }
00594 }
00595
00596
00597 for (region_list_t::iterator iter = mVisibleRegionList.begin();
00598 iter != mVisibleRegionList.end(); )
00599 {
00600 region_list_t::iterator curiter = iter++;
00601 LLViewerRegion* regionp = *curiter;
00602 if (!regionp->getLand().hasZData())
00603 {
00604 continue;
00605 }
00606
00607 F32 height = regionp->getLand().getMaxZ() - regionp->getLand().getMinZ();
00608 F32 radius = 0.5f*fsqrtf(height * height + diagonal_squared);
00609 if (LLViewerCamera::getInstance()->sphereInFrustum(regionp->getCenterAgent(), radius))
00610 {
00611 regionp->calculateCameraDistance();
00612 if (!gNoRender)
00613 {
00614 regionp->getLand().updatePatchVisibilities(gAgent);
00615 }
00616 }
00617 else
00618 {
00619 mVisibleRegionList.erase(curiter);
00620 mCulledRegionList.push_back(regionp);
00621 }
00622 }
00623
00624
00625 mVisibleRegionList.sort(LLViewerRegion::CompareDistance());
00626
00627 LLViewerCamera::getInstance()->setFar(cur_far_clip);
00628 }
00629
00630 void LLWorld::updateRegions(F32 max_update_time)
00631 {
00632 LLTimer update_timer;
00633 BOOL did_one = FALSE;
00634
00635
00636 for (region_list_t::iterator iter = mRegionList.begin();
00637 iter != mRegionList.end(); ++iter)
00638 {
00639 LLViewerRegion* regionp = *iter;
00640 F32 max_time = max_update_time - update_timer.getElapsedTimeF32();
00641 if (did_one && max_time <= 0.f)
00642 break;
00643 max_time = llmin(max_time, max_update_time*.1f);
00644 did_one |= regionp->idleUpdate(max_update_time);
00645 }
00646 }
00647
00648 void LLWorld::updateParticles()
00649 {
00650 LLViewerPartSim::getInstance()->updateSimulation();
00651 }
00652
00653 void LLWorld::updateClouds(const F32 dt)
00654 {
00655 if (gSavedSettings.getBOOL("FreezeTime") ||
00656 !gSavedSettings.getBOOL("SkyUseClassicClouds"))
00657 {
00658
00659 return;
00660 }
00661 if (mActiveRegionList.size())
00662 {
00663
00664
00665 for (region_list_t::iterator iter = mActiveRegionList.begin();
00666 iter != mActiveRegionList.end(); ++iter)
00667 {
00668 LLViewerRegion* regionp = *iter;
00669 regionp->mCloudLayer.updatePuffs(dt);
00670 }
00671
00672
00673 for (region_list_t::iterator iter = mActiveRegionList.begin();
00674 iter != mActiveRegionList.end(); ++iter)
00675 {
00676 LLViewerRegion* regionp = *iter;
00677 regionp->mCloudLayer.updatePuffOwnership();
00678 }
00679
00680
00681 for (region_list_t::iterator iter = mActiveRegionList.begin();
00682 iter != mActiveRegionList.end(); ++iter)
00683 {
00684 LLViewerRegion* regionp = *iter;
00685 regionp->mCloudLayer.updatePuffCount();
00686 }
00687 }
00688 }
00689
00690 LLCloudGroup* LLWorld::findCloudGroup(const LLCloudPuff &puff)
00691 {
00692 if (mActiveRegionList.size())
00693 {
00694
00695
00696 for (region_list_t::iterator iter = mActiveRegionList.begin();
00697 iter != mActiveRegionList.end(); ++iter)
00698 {
00699 LLViewerRegion* regionp = *iter;
00700 LLCloudGroup *groupp = regionp->mCloudLayer.findCloudGroup(puff);
00701 if (groupp)
00702 {
00703 return groupp;
00704 }
00705 }
00706 }
00707 return NULL;
00708 }
00709
00710
00711 void LLWorld::renderPropertyLines()
00712 {
00713 S32 region_count = 0;
00714 S32 vertex_count = 0;
00715
00716 for (region_list_t::iterator iter = mVisibleRegionList.begin();
00717 iter != mVisibleRegionList.end(); ++iter)
00718 {
00719 LLViewerRegion* regionp = *iter;
00720 region_count++;
00721 vertex_count += regionp->renderPropertyLines();
00722 }
00723 }
00724
00725
00726 void LLWorld::updateNetStats()
00727 {
00728 F32 bits = 0.f;
00729 U32 packets = 0;
00730
00731 for (region_list_t::iterator iter = mActiveRegionList.begin();
00732 iter != mActiveRegionList.end(); ++iter)
00733 {
00734 LLViewerRegion* regionp = *iter;
00735 regionp->updateNetStats();
00736 bits += regionp->mBitStat.getCurrent();
00737 packets += llfloor( regionp->mPacketsStat.getCurrent() );
00738 }
00739
00740 S32 packets_in = gMessageSystem->mPacketsIn - mLastPacketsIn;
00741 S32 packets_out = gMessageSystem->mPacketsOut - mLastPacketsOut;
00742 S32 packets_lost = gMessageSystem->mDroppedPackets - mLastPacketsLost;
00743
00744 S32 actual_in_bits = gMessageSystem->mPacketRing.getAndResetActualInBits();
00745 S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits();
00746 LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f);
00747 LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f);
00748 LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f);
00749 LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
00750 LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
00751 LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
00752 if (packets_in)
00753 {
00754 LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
00755 }
00756 else
00757 {
00758 LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);
00759 }
00760
00761 mLastPacketsIn = gMessageSystem->mPacketsIn;
00762 mLastPacketsOut = gMessageSystem->mPacketsOut;
00763 mLastPacketsLost = gMessageSystem->mDroppedPackets;
00764 }
00765
00766
00767 void LLWorld::printPacketsLost()
00768 {
00769 llinfos << "Simulators:" << llendl;
00770 llinfos << "----------" << llendl;
00771
00772 LLCircuitData *cdp = NULL;
00773 for (region_list_t::iterator iter = mActiveRegionList.begin();
00774 iter != mActiveRegionList.end(); ++iter)
00775 {
00776 LLViewerRegion* regionp = *iter;
00777 cdp = gMessageSystem->mCircuitInfo.findCircuit(regionp->getHost());
00778 if (cdp)
00779 {
00780 LLVector3d range = regionp->getCenterGlobal() - gAgent.getPositionGlobal();
00781
00782 llinfos << regionp->getHost() << ", range: " << range.magVec()
00783 << " packets lost: " << cdp->getPacketsLost() << llendl;
00784 }
00785 }
00786 }
00787
00788 void LLWorld::processCoarseUpdate(LLMessageSystem* msg, void** user_data)
00789 {
00790 LLViewerRegion* region = LLWorld::getInstance()->getRegion(msg->getSender());
00791 if( region )
00792 {
00793 region->updateCoarseLocations(msg);
00794 }
00795 }
00796
00797 F32 LLWorld::getLandFarClip() const
00798 {
00799 return mLandFarClip;
00800 }
00801
00802 void LLWorld::setLandFarClip(const F32 far_clip)
00803 {
00804 mLandFarClip = far_clip;
00805 }
00806
00807
00808 void LLWorld::updateWaterObjects()
00809 {
00810 if (!gAgent.getRegion())
00811 {
00812 return;
00813 }
00814 if (mRegionList.empty())
00815 {
00816 llwarns << "No regions!" << llendl;
00817 return;
00818 }
00819
00820
00821 S32 min_x = 0;
00822 S32 min_y = 0;
00823 S32 max_x = 0;
00824 S32 max_y = 0;
00825 U32 region_x, region_y;
00826
00827 S32 rwidth = 256;
00828
00829
00830 S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256;
00831
00832 LLViewerRegion* regionp = gAgent.getRegion();
00833 from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y);
00834
00835 min_x = (S32)region_x - range;
00836 min_y = (S32)region_y - range;
00837 max_x = (S32)region_x + range;
00838 max_y = (S32)region_y + range;
00839
00840 F32 height = 0.f;
00841
00842 for (region_list_t::iterator iter = mRegionList.begin();
00843 iter != mRegionList.end(); ++iter)
00844 {
00845 LLViewerRegion* regionp = *iter;
00846 LLVOWater* waterp = regionp->getLand().getWaterObj();
00847 height += regionp->getWaterHeight();
00848 if (waterp)
00849 {
00850 gObjectList.updateActive(waterp);
00851 }
00852 }
00853
00854 for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin();
00855 iter != mHoleWaterObjects.end(); ++ iter)
00856 {
00857 LLVOWater* waterp = *iter;
00858 gObjectList.killObject(waterp);
00859 }
00860 mHoleWaterObjects.clear();
00861
00862
00863 S32 x, y;
00864 for (x = min_x; x <= max_x; x += rwidth)
00865 {
00866 for (y = min_y; y <= max_y; y += rwidth)
00867 {
00868 U64 region_handle = to_region_handle(x, y);
00869 if (!getRegionFromHandle(region_handle))
00870 {
00871 LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion());
00872 waterp->setUseTexture(FALSE);
00873 waterp->setPositionGlobal(LLVector3d(x + rwidth/2,
00874 y + rwidth/2,
00875 256.f+DEFAULT_WATER_HEIGHT));
00876 waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f));
00877 gPipeline.addObject(waterp);
00878 mHoleWaterObjects.push_back(waterp);
00879 }
00880 }
00881 }
00882
00883
00884 S32 wx, wy;
00885 S32 center_x, center_y;
00886 wx = (max_x - min_x) + rwidth;
00887 wy = (max_y - min_y) + rwidth;
00888 center_x = min_x + (wx >> 1);
00889 center_y = min_y + (wy >> 1);
00890
00891 S32 add_boundary[4] = {
00892 512 - (max_x - region_x),
00893 512 - (max_y - region_y),
00894 512 - (region_x - min_x),
00895 512 - (region_y - min_y) };
00896
00897 S32 dir;
00898 for (dir = 0; dir < 8; dir++)
00899 {
00900 S32 dim[2] = { 0 };
00901 switch (gDirAxes[dir][0])
00902 {
00903 case -1: dim[0] = add_boundary[2]; break;
00904 case 0: dim[0] = wx; break;
00905 default: dim[0] = add_boundary[0]; break;
00906 }
00907 switch (gDirAxes[dir][1])
00908 {
00909 case -1: dim[1] = add_boundary[3]; break;
00910 case 0: dim[1] = wy; break;
00911 default: dim[1] = add_boundary[1]; break;
00912 }
00913
00914
00915 const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]);
00916 const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]);
00917
00918 LLVOWater* waterp = mEdgeWaterObjects[dir];
00919 if (!waterp || waterp->isDead())
00920 {
00921
00922
00923 mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER,
00924 gAgent.getRegion());
00925 waterp = mEdgeWaterObjects[dir];
00926 waterp->setUseTexture(FALSE);
00927 waterp->setIsEdgePatch(TRUE);
00928 gPipeline.addObject(waterp);
00929 }
00930
00931 waterp->setRegion(gAgent.getRegion());
00932 LLVector3d water_pos(water_center_x, water_center_y,
00933 DEFAULT_WATER_HEIGHT+256.f);
00934 LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f);
00935
00936
00937 water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]);
00938 water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]);
00939
00940 water_pos.mdV[0] += 1024.f * gDirAxes[dir][0];
00941 water_pos.mdV[1] += 1024.f * gDirAxes[dir][1];
00942
00943 waterp->setPositionGlobal(water_pos);
00944 waterp->setScale(water_scale);
00945
00946 gObjectList.updateActive(waterp);
00947 }
00948 }
00949
00950 void LLWorld::shiftRegions(const LLVector3& offset)
00951 {
00952 for (region_list_t::iterator i = getRegionList().begin(); i != getRegionList().end(); ++i)
00953 {
00954 LLViewerRegion* region = *i;
00955 region->updateRenderMatrix();
00956 }
00957
00958 LLViewerPartSim::getInstance()->shift(offset);
00959 }
00960
00961 LLViewerImage* LLWorld::getDefaultWaterTexture()
00962 {
00963 return mDefaultWaterTexturep;
00964 }
00965
00966 void LLWorld::setSpaceTimeUSec(const U64 space_time_usec)
00967 {
00968 mSpaceTimeUSec = space_time_usec;
00969 }
00970
00971 U64 LLWorld::getSpaceTimeUSec() const
00972 {
00973 return mSpaceTimeUSec;
00974 }
00975
00976 void LLWorld::requestCacheMisses()
00977 {
00978 for (region_list_t::iterator iter = mRegionList.begin();
00979 iter != mRegionList.end(); ++iter)
00980 {
00981 LLViewerRegion* regionp = *iter;
00982 regionp->requestCacheMisses();
00983 }
00984 }
00985
00986 void LLWorld::getInfo(LLSD& info)
00987 {
00988 LLSD region_info;
00989 for (region_list_t::iterator iter = mRegionList.begin();
00990 iter != mRegionList.end(); ++iter)
00991 {
00992 LLViewerRegion* regionp = *iter;
00993 regionp->getInfo(region_info);
00994 info["World"].append(region_info);
00995 }
00996 }
00997
00998 void LLWorld::disconnectRegions()
00999 {
01000 LLMessageSystem* msg = gMessageSystem;
01001 for (region_list_t::iterator iter = mRegionList.begin();
01002 iter != mRegionList.end(); ++iter)
01003 {
01004 LLViewerRegion* regionp = *iter;
01005 if (regionp == gAgent.getRegion())
01006 {
01007
01008 continue;
01009 }
01010
01011 llinfos << "Sending AgentQuitCopy to: " << regionp->getHost() << llendl;
01012 msg->newMessageFast(_PREHASH_AgentQuitCopy);
01013 msg->nextBlockFast(_PREHASH_AgentData);
01014 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
01015 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01016 msg->nextBlockFast(_PREHASH_FuseBlock);
01017 msg->addU32Fast(_PREHASH_ViewerCircuitCode, gMessageSystem->mOurCircuitCode);
01018 msg->sendMessage(regionp->getHost());
01019 }
01020 }
01021
01022
01023 void process_enable_simulator(LLMessageSystem *msg, void **user_data)
01024 {
01025
01026
01027 U64 handle;
01028 U32 ip_u32;
01029 U16 port;
01030
01031 msg->getU64Fast(_PREHASH_SimulatorInfo, _PREHASH_Handle, handle);
01032 msg->getIPAddrFast(_PREHASH_SimulatorInfo, _PREHASH_IP, ip_u32);
01033 msg->getIPPortFast(_PREHASH_SimulatorInfo, _PREHASH_Port, port);
01034
01035
01036 LLHost sim(ip_u32, port);
01037
01038
01039 msg->enableCircuit(sim, TRUE);
01040 LLWorld::getInstance()->addRegion(handle, sim);
01041
01042
01043 llinfos << "simulator_enable() Enabling " << sim << " with code " << msg->getOurCircuitCode() << llendl;
01044 msg->newMessageFast(_PREHASH_UseCircuitCode);
01045 msg->nextBlockFast(_PREHASH_CircuitCode);
01046 msg->addU32Fast(_PREHASH_Code, msg->getOurCircuitCode());
01047 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01048 msg->addUUIDFast(_PREHASH_ID, gAgent.getID());
01049 msg->sendReliable(sim);
01050 }
01051
01052 class LLEstablishAgentCommunication : public LLHTTPNode
01053 {
01054 LOG_CLASS(LLEstablishAgentCommunication);
01055 public:
01056 virtual void describe(Description& desc) const
01057 {
01058 desc.shortInfo("seed capability info for a region");
01059 desc.postAPI();
01060 desc.input(
01061 "{ seed-capability: ..., sim-ip: ..., sim-port }");
01062 desc.source(__FILE__, __LINE__);
01063 }
01064
01065 virtual void post(ResponsePtr response, const LLSD& context, const LLSD& input) const
01066 {
01067 if (!input["body"].has("agent-id") ||
01068 !input["body"].has("sim-ip-and-port") ||
01069 !input["body"].has("seed-capability"))
01070 {
01071 llwarns << "invalid parameters" << llendl;
01072 return;
01073 }
01074
01075 LLHost sim(input["body"]["sim-ip-and-port"].asString());
01076
01077 LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(sim);
01078 if (!regionp)
01079 {
01080 llwarns << "Got EstablishAgentCommunication for unknown region "
01081 << sim << llendl;
01082 return;
01083 }
01084 regionp->setSeedCapability(input["body"]["seed-capability"]);
01085 }
01086 };
01087
01088
01089
01090 void process_disable_simulator(LLMessageSystem *mesgsys, void **user_data)
01091 {
01092 LLHost host = mesgsys->getSender();
01093
01094
01095 LLWorld::getInstance()->removeRegion(host);
01096
01097 mesgsys->disableCircuit(host);
01098 }
01099
01100
01101 void process_region_handshake(LLMessageSystem* msg, void** user_data)
01102 {
01103 LLHost host = msg->getSender();
01104 LLViewerRegion* regionp = LLWorld::getInstance()->getRegion(host);
01105 if (!regionp)
01106 {
01107 llwarns << "Got region handshake for unknown region "
01108 << host << llendl;
01109 return;
01110 }
01111
01112 regionp->unpackRegionHandshake();
01113 }
01114
01115
01116 void send_agent_pause()
01117 {
01118
01119
01120 LLAppViewer::instance()->stopMainloopTimeout();
01121
01122
01123
01124
01125 if (!gMessageSystem)
01126 {
01127 return;
01128 }
01129
01130 gMessageSystem->newMessageFast(_PREHASH_AgentPause);
01131 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
01132 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
01133 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
01134
01135 gAgentPauseSerialNum++;
01136 gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum);
01137
01138 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->mActiveRegionList.begin();
01139 iter != LLWorld::getInstance()->mActiveRegionList.end(); ++iter)
01140 {
01141 LLViewerRegion* regionp = *iter;
01142 gMessageSystem->sendReliable(regionp->getHost());
01143 }
01144
01145 gObjectList.mWasPaused = TRUE;
01146 }
01147
01148
01149 void send_agent_resume()
01150 {
01151
01152
01153
01154 if (!gMessageSystem)
01155 {
01156 return;
01157 }
01158
01159 gMessageSystem->newMessageFast(_PREHASH_AgentResume);
01160 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
01161 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID);
01162 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID);
01163
01164 gAgentPauseSerialNum++;
01165 gMessageSystem->addU32Fast(_PREHASH_SerialNum, gAgentPauseSerialNum);
01166
01167
01168 for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->mActiveRegionList.begin();
01169 iter != LLWorld::getInstance()->mActiveRegionList.end(); ++iter)
01170 {
01171 LLViewerRegion* regionp = *iter;
01172 gMessageSystem->sendReliable(regionp->getHost());
01173 }
01174
01175
01176 LLViewerStats::getInstance()->mFPSStat.start();
01177
01178 LLAppViewer::instance()->startMainloopTimeout();
01179 }
01180
01181
01182 LLHTTPRegistration<LLEstablishAgentCommunication>
01183 gHTTPRegistrationEstablishAgentCommunication(
01184 "/message/EstablishAgentCommunication");