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