00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llworldmap.h"
00035
00036 #include "llregionhandle.h"
00037 #include "message.h"
00038
00039 #include "viewer.h"
00040 #include "llagent.h"
00041 #include "llmapresponders.h"
00042 #include "llviewercontrol.h"
00043 #include "llfloaterworldmap.h"
00044 #include "lltracker.h"
00045 #include "llviewerimagelist.h"
00046 #include "llviewerregion.h"
00047 #include "llregionflags.h"
00048
00049 LLWorldMap* gWorldMap = NULL;
00050
00051 const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f;
00052
00053 LLItemInfo::LLItemInfo(F32 global_x, F32 global_y,
00054 const std::string& name,
00055 LLUUID id,
00056 S32 extra, S32 extra2)
00057 : mName(name),
00058 mToolTip(""),
00059 mPosGlobal(global_x, global_y, 40.0),
00060 mID(id),
00061 mSelected(FALSE),
00062 mExtra(extra),
00063 mExtra2(extra2)
00064 {
00065 mRegionHandle = to_region_handle(mPosGlobal);
00066 }
00067
00068 LLSimInfo::LLSimInfo()
00069 : mHandle(0),
00070 mName(),
00071 mAgentsUpdateTime(0),
00072 mAccess(0x0),
00073 mRegionFlags(0x0),
00074 mWaterHeight(0.f),
00075 mAlpha(-1.f)
00076 {
00077 }
00078
00079
00080 LLVector3d LLSimInfo::getGlobalPos(LLVector3 local_pos) const
00081 {
00082 LLVector3d pos = from_region_handle(mHandle);
00083 pos.mdV[VX] += local_pos.mV[VX];
00084 pos.mdV[VY] += local_pos.mV[VY];
00085 pos.mdV[VZ] += local_pos.mV[VZ];
00086 return pos;
00087 }
00088
00089
00090
00091
00092
00093
00094 LLWorldMap::LLWorldMap() :
00095 mIsTrackingUnknownLocation( FALSE ),
00096 mInvalidLocation( FALSE ),
00097 mIsTrackingDoubleClick( FALSE ),
00098 mIsTrackingCommit( FALSE ),
00099 mUnknownLocation( 0, 0, 0 ),
00100 mRequestLandForSale(true),
00101 mCurrentMap(0),
00102 mMinX(U32_MAX),
00103 mMaxX(U32_MIN),
00104 mMinY(U32_MAX),
00105 mMaxY(U32_MIN),
00106 mNeighborMap(NULL),
00107 mTelehubCoverageMap(NULL),
00108 mNeighborMapWidth(0),
00109 mNeighborMapHeight(0),
00110 mSLURLRegionName(),
00111 mSLURL(),
00112 mSLURLCallback(0),
00113 mSLURLTeleport(false)
00114 {
00115 for (S32 map=0; map<MAP_SIM_IMAGE_TYPES; ++map)
00116 {
00117 mMapLoaded[map] = FALSE;
00118 mMapBlockLoaded[map] = new BOOL[MAP_BLOCK_RES*MAP_BLOCK_RES];
00119 for (S32 idx=0; idx<MAP_BLOCK_RES*MAP_BLOCK_RES; ++idx)
00120 {
00121 mMapBlockLoaded[map][idx] = FALSE;
00122 }
00123 }
00124 }
00125
00126
00127 LLWorldMap::~LLWorldMap()
00128 {
00129 reset();
00130 for (S32 map=0; map<MAP_SIM_IMAGE_TYPES; ++map)
00131 {
00132 delete[] mMapBlockLoaded[map];
00133 }
00134 }
00135
00136
00137 void LLWorldMap::reset()
00138 {
00139 for_each(mSimInfoMap.begin(), mSimInfoMap.end(), DeletePairedPointer());
00140 mSimInfoMap.clear();
00141
00142 for (S32 m=0; m<MAP_SIM_IMAGE_TYPES; ++m)
00143 {
00144 mMapLoaded[m] = FALSE;
00145 }
00146
00147 clearSimFlags();
00148
00149 eraseItems();
00150
00151 mMinX = U32_MAX;
00152 mMaxX = U32_MIN;
00153
00154 mMinY = U32_MAX;
00155 mMaxY = U32_MIN;
00156
00157 delete [] mNeighborMap;
00158 mNeighborMap = NULL;
00159 delete [] mTelehubCoverageMap;
00160 mTelehubCoverageMap = NULL;
00161
00162 mNeighborMapWidth = 0;
00163 mNeighborMapHeight = 0;
00164 }
00165
00166 void LLWorldMap::eraseItems()
00167 {
00168 if (mRequestTimer.getElapsedTimeF32() > REQUEST_ITEMS_TIMER)
00169 {
00170 mRequestTimer.reset();
00171
00172 mTelehubs.clear();
00173 mInfohubs.clear();
00174 mPGEvents.clear();
00175 mMatureEvents.clear();
00176 mPopular.clear();
00177 mLandForSale.clear();
00178 mClassifieds.clear();
00179 }
00180
00181
00182 }
00183
00184
00185 void LLWorldMap::clearImageRefs()
00186 {
00187 for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00188 {
00189 LLSimInfo* info = (*it).second;
00190 if (info->mCurrentImage)
00191 {
00192 info->mCurrentImage->setBoostLevel(0);
00193 info->mCurrentImage = NULL;
00194 }
00195 if (info->mOverlayImage)
00196 {
00197 info->mOverlayImage->setBoostLevel(0);
00198 info->mOverlayImage = NULL;
00199 }
00200 }
00201 }
00202
00203
00204 void LLWorldMap::clearSimFlags()
00205 {
00206 for (S32 map=0; map<MAP_SIM_IMAGE_TYPES; ++map)
00207 {
00208 for (S32 idx=0; idx<MAP_BLOCK_RES*MAP_BLOCK_RES; ++idx)
00209 {
00210 mMapBlockLoaded[map][idx] = FALSE;
00211 }
00212 }
00213 }
00214
00215 LLSimInfo* LLWorldMap::simInfoFromPosGlobal(const LLVector3d& pos_global)
00216 {
00217 U64 handle = to_region_handle(pos_global);
00218 return simInfoFromHandle(handle);
00219 }
00220
00221 LLSimInfo* LLWorldMap::simInfoFromHandle(const U64 handle)
00222 {
00223 sim_info_map_t::iterator it = mSimInfoMap.find(handle);
00224 if (it != mSimInfoMap.end())
00225 {
00226 LLSimInfo* sim_info = (*it).second;
00227 if (sim_info)
00228 {
00229 return sim_info;
00230 }
00231 }
00232 return NULL;
00233 }
00234
00235
00236 LLSimInfo* LLWorldMap::simInfoFromName(const LLString& sim_name)
00237 {
00238 LLSimInfo* sim_info = NULL;
00239 if (!sim_name.empty())
00240 {
00241 for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00242 {
00243 sim_info = (*it).second;
00244 if (sim_info
00245 && (0 == LLString::compareInsensitive(sim_name.c_str(), sim_info->mName.c_str())) )
00246 {
00247 break;
00248 }
00249 sim_info = NULL;
00250 }
00251 }
00252 return sim_info;
00253 }
00254
00255 bool LLWorldMap::simNameFromPosGlobal(const LLVector3d& pos_global, LLString & outSimName )
00256 {
00257 bool gotSimName = true;
00258
00259 U64 handle = to_region_handle(pos_global);
00260
00261 sim_info_map_t::iterator it = mSimInfoMap.find(handle);
00262 if (it != mSimInfoMap.end())
00263 {
00264 LLSimInfo* info = (*it).second;
00265 outSimName = info->mName.c_str();
00266 }
00267 else
00268 {
00269 gotSimName = false;
00270 outSimName = "(unknown region)";
00271 }
00272
00273 return gotSimName;
00274 }
00275
00276 void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer)
00277 {
00278 mCurrentMap = layer;
00279 if (!mMapLoaded[layer] || request_layer)
00280 {
00281 sendMapLayerRequest();
00282 }
00283
00284 if (mTelehubs.size() == 0 ||
00285 mInfohubs.size() == 0)
00286 {
00287
00288 sendItemRequest(MAP_ITEM_TELEHUB);
00289 }
00290
00291 if (mPGEvents.size() == 0)
00292 {
00293
00294 sendItemRequest(MAP_ITEM_PG_EVENT);
00295 }
00296
00297 if (mMatureEvents.size() == 0)
00298 {
00299
00300 sendItemRequest(MAP_ITEM_MATURE_EVENT);
00301 }
00302
00303 if (mPopular.size() == 0)
00304 {
00305
00306 sendItemRequest(MAP_ITEM_POPULAR);
00307 }
00308
00309 if (mLandForSale.size() == 0)
00310 {
00311
00312 sendItemRequest(MAP_ITEM_LAND_FOR_SALE);
00313 }
00314
00315 if (mClassifieds.size() == 0)
00316 {
00317 sendItemRequest(MAP_ITEM_CLASSIFIED);
00318 }
00319
00320 clearImageRefs();
00321 clearSimFlags();
00322 }
00323
00324 void LLWorldMap::sendItemRequest(U32 type, U64 handle)
00325 {
00326 LLMessageSystem* msg = gMessageSystem;
00327 S32 layer = mCurrentMap;
00328
00329 msg->newMessageFast(_PREHASH_MapItemRequest);
00330 msg->nextBlockFast(_PREHASH_AgentData);
00331 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00332 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00333 msg->addU32Fast(_PREHASH_Flags, layer);
00334 msg->addU32Fast(_PREHASH_EstateID, 0);
00335 msg->addBOOLFast(_PREHASH_Godlike, FALSE);
00336
00337 msg->nextBlockFast(_PREHASH_RequestData);
00338 msg->addU32Fast(_PREHASH_ItemType, type);
00339 msg->addU64Fast(_PREHASH_RegionHandle, handle);
00340
00341 gAgent.sendReliableMessage();
00342 }
00343
00344
00345 void LLWorldMap::sendMapLayerRequest()
00346 {
00347 LLSD body;
00348 body["Flags"] = mCurrentMap;
00349 std::string url = gAgent.getRegion()->getCapability(
00350 gAgent.isGodlike() ? "MapLayerGod" : "MapLayer");
00351
00352 if (!url.empty())
00353 {
00354 llinfos << "LLWorldMap::sendMapLayerRequest via capability" << llendl;
00355 LLHTTPClient::post(url, body, new LLMapLayerResponder());
00356 }
00357 else
00358 {
00359 llinfos << "LLWorldMap::sendMapLayerRequest via message system" << llendl;
00360 LLMessageSystem* msg = gMessageSystem;
00361 S32 layer = mCurrentMap;
00362
00363
00364 msg->newMessageFast(_PREHASH_MapLayerRequest);
00365 msg->nextBlockFast(_PREHASH_AgentData);
00366 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00367 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00368 msg->addU32Fast(_PREHASH_Flags, layer);
00369 msg->addU32Fast(_PREHASH_EstateID, 0);
00370 msg->addBOOLFast(_PREHASH_Godlike, FALSE);
00371 gAgent.sendReliableMessage();
00372
00373 if (mRequestLandForSale)
00374 {
00375 msg->newMessageFast(_PREHASH_MapLayerRequest);
00376 msg->nextBlockFast(_PREHASH_AgentData);
00377 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00378 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00379 msg->addU32Fast(_PREHASH_Flags, 2);
00380 msg->addU32Fast(_PREHASH_EstateID, 0);
00381 msg->addBOOLFast(_PREHASH_Godlike, FALSE);
00382 gAgent.sendReliableMessage();
00383 }
00384 }
00385 }
00386
00387
00388 void LLWorldMap::sendNamedRegionRequest(std::string region_name)
00389 {
00390 LLMessageSystem* msg = gMessageSystem;
00391 S32 layer = mCurrentMap;
00392
00393
00394 msg->newMessageFast(_PREHASH_MapNameRequest);
00395 msg->nextBlockFast(_PREHASH_AgentData);
00396 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00397 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00398 msg->addU32Fast(_PREHASH_Flags, layer);
00399 msg->addU32Fast(_PREHASH_EstateID, 0);
00400 msg->addBOOLFast(_PREHASH_Godlike, FALSE);
00401 msg->nextBlockFast(_PREHASH_NameData);
00402 msg->addStringFast(_PREHASH_Name, region_name);
00403 gAgent.sendReliableMessage();
00404 }
00405
00406 void LLWorldMap::sendNamedRegionRequest(std::string region_name,
00407 url_callback_t callback,
00408 const std::string& callback_url,
00409 bool teleport)
00410 {
00411 mSLURLRegionName = region_name;
00412 mSLURL = callback_url;
00413 mSLURLCallback = callback;
00414 mSLURLTeleport = teleport;
00415
00416 sendNamedRegionRequest(region_name);
00417 }
00418
00419
00420 void LLWorldMap::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent)
00421 {
00422 S32 layer = mCurrentMap;
00423 LLMessageSystem* msg = gMessageSystem;
00424 msg->newMessageFast(_PREHASH_MapBlockRequest);
00425 msg->nextBlockFast(_PREHASH_AgentData);
00426 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00427 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00428 U32 flags = layer;
00429 flags |= (return_nonexistent ? 0x10000 : 0);
00430 msg->addU32Fast(_PREHASH_Flags, flags);
00431 msg->addU32Fast(_PREHASH_EstateID, 0);
00432 msg->addBOOLFast(_PREHASH_Godlike, FALSE);
00433 msg->nextBlockFast(_PREHASH_PositionData);
00434 msg->addU16Fast(_PREHASH_MinX, min_x);
00435 msg->addU16Fast(_PREHASH_MinY, min_y);
00436 msg->addU16Fast(_PREHASH_MaxX, max_x);
00437 msg->addU16Fast(_PREHASH_MaxY, max_y);
00438 gAgent.sendReliableMessage();
00439
00440 if (mRequestLandForSale)
00441 {
00442 msg->newMessageFast(_PREHASH_MapBlockRequest);
00443 msg->nextBlockFast(_PREHASH_AgentData);
00444 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00445 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00446 msg->addU32Fast(_PREHASH_Flags, 2);
00447 msg->addU32Fast(_PREHASH_EstateID, 0);
00448 msg->addBOOLFast(_PREHASH_Godlike, FALSE);
00449 msg->nextBlockFast(_PREHASH_PositionData);
00450 msg->addU16Fast(_PREHASH_MinX, min_x);
00451 msg->addU16Fast(_PREHASH_MinY, min_y);
00452 msg->addU16Fast(_PREHASH_MaxX, max_x);
00453 msg->addU16Fast(_PREHASH_MaxY, max_y);
00454 gAgent.sendReliableMessage();
00455 }
00456 }
00457
00458
00459 void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**)
00460 {
00461 llinfos << "LLWorldMap::processMapLayerReply from message system" << llendl;
00462
00463 U32 agent_flags;
00464 msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags);
00465
00466 if (agent_flags != (U32)gWorldMap->mCurrentMap)
00467 {
00468 llwarns << "Invalid or out of date map image type returned!" << llendl;
00469 return;
00470 }
00471
00472 LLUUID image_id;
00473
00474
00475 S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_LayerData);
00476
00477 gWorldMap->mMapLayers[agent_flags].clear();
00478
00479 BOOL adjust = FALSE;
00480 for (S32 block=0; block<num_blocks; ++block)
00481 {
00482 LLWorldMapLayer new_layer;
00483 new_layer.LayerDefined = TRUE;
00484 msg->getUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block);
00485 new_layer.LayerImage = gImageList.getImage(new_layer.LayerImageID, MIPMAP_TRUE, FALSE);
00486 new_layer.LayerImage->bindTexture(0);
00487 new_layer.LayerImage->setClamp(TRUE, TRUE);
00488
00489 U32 left, right, top, bottom;
00490 msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Left, left, block);
00491 msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Right, right, block);
00492 msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Top, top, block);
00493 msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Bottom, bottom, block);
00494
00495 new_layer.LayerExtents.mLeft = left;
00496 new_layer.LayerExtents.mRight = right;
00497 new_layer.LayerExtents.mBottom = bottom;
00498 new_layer.LayerExtents.mTop = top;
00499
00500 F32 x_meters = F32(left*REGION_WIDTH_UNITS);
00501 F32 y_meters = F32(bottom*REGION_WIDTH_UNITS);
00502 adjust = gWorldMap->extendAABB(U32(x_meters), U32(y_meters),
00503 U32(x_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getWidth()),
00504 U32(y_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getHeight())) || adjust;
00505
00506 gWorldMap->mMapLayers[agent_flags].push_back(new_layer);
00507 }
00508
00509 gWorldMap->mMapLoaded[agent_flags] = TRUE;
00510 if(adjust) gFloaterWorldMap->adjustZoomSliderBounds();
00511 }
00512
00513
00514 void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**)
00515 {
00516 U32 agent_flags;
00517 msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags);
00518
00519 if ((S32)agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES)
00520 {
00521 llwarns << "Invalid map image type returned! " << agent_flags << llendl;
00522 return;
00523 }
00524
00525 S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data);
00526
00527 bool found_null_sim = false;
00528
00529 BOOL adjust = FALSE;
00530 for (S32 block=0; block<num_blocks; ++block)
00531 {
00532 U16 x_regions;
00533 U16 y_regions;
00534 char name[MAX_STRING];
00535 U8 access;
00536 U32 region_flags;
00537 U8 water_height;
00538 U8 agents;
00539 LLUUID image_id;
00540 msg->getU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block);
00541 msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block);
00542 msg->getStringFast(_PREHASH_Data, _PREHASH_Name, MAX_STRING, name, block);
00543 msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, access, block);
00544 msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block);
00545 msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block);
00546 msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block);
00547 msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block);
00548
00549 U32 x_meters = x_regions * REGION_WIDTH_UNITS;
00550 U32 y_meters = y_regions * REGION_WIDTH_UNITS;
00551
00552 U64 handle = to_region_handle(x_meters, y_meters);
00553
00554 if (access == 255)
00555 {
00556
00557 if (gWorldMap->mIsTrackingUnknownLocation &&
00558 gWorldMap->mUnknownLocation.mdV[0] >= x_meters &&
00559 gWorldMap->mUnknownLocation.mdV[0] < x_meters + 256 &&
00560 gWorldMap->mUnknownLocation.mdV[1] >= y_meters &&
00561 gWorldMap->mUnknownLocation.mdV[1] < y_meters + 256)
00562 {
00563
00564 gWorldMap->mInvalidLocation = TRUE;
00565 }
00566
00567 found_null_sim = true;
00568 }
00569 else if(gWorldMap->mSLURLCallback != NULL)
00570 {
00571
00572
00573 if (!stricmp(gWorldMap->mSLURLRegionName.c_str(), name))
00574 {
00575 gWorldMap->mSLURLCallback(handle, gWorldMap->mSLURL, image_id, gWorldMap->mSLURLTeleport);
00576 gWorldMap->mSLURLCallback = NULL;
00577 gWorldMap->mSLURLRegionName.clear();
00578 }
00579 }
00580 else
00581 {
00582 adjust = gWorldMap->extendAABB(x_meters,
00583 y_meters,
00584 x_meters+REGION_WIDTH_UNITS,
00585 y_meters+REGION_WIDTH_UNITS) || adjust;
00586
00587
00588
00589 LLSimInfo* siminfo = new LLSimInfo();
00590 sim_info_map_t::iterator iter = gWorldMap->mSimInfoMap.find(handle);
00591 if (iter != gWorldMap->mSimInfoMap.end())
00592 {
00593 LLSimInfo* oldinfo = iter->second;
00594 for (S32 image=0; image<MAP_SIM_IMAGE_TYPES; ++image)
00595 {
00596 siminfo->mMapImageID[image] = oldinfo->mMapImageID[image];
00597 }
00598 delete oldinfo;
00599 }
00600 gWorldMap->mSimInfoMap[handle] = siminfo;
00601
00602 siminfo->mHandle = handle;
00603 siminfo->mName.assign( name );
00604 siminfo->mAccess = access;
00605 siminfo->mRegionFlags = region_flags;
00606 siminfo->mWaterHeight = (F32) water_height;
00607 siminfo->mMapImageID[agent_flags] = image_id;
00608 siminfo->mCurrentImage = gImageList.getImage(siminfo->mMapImageID[gWorldMap->mCurrentMap], MIPMAP_TRUE, FALSE);
00609 siminfo->mCurrentImage->bindTexture(0);
00610 siminfo->mCurrentImage->setClamp(TRUE, TRUE);
00611
00612 if (siminfo->mMapImageID[2].notNull())
00613 {
00614 siminfo->mOverlayImage = gImageList.getImage(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE);
00615 }
00616 else
00617 {
00618 siminfo->mOverlayImage = NULL;
00619 }
00620
00621 if (gWorldMap->mIsTrackingUnknownLocation &&
00622 gWorldMap->mUnknownLocation.mdV[0] >= x_meters &&
00623 gWorldMap->mUnknownLocation.mdV[0] < x_meters + 256 &&
00624 gWorldMap->mUnknownLocation.mdV[1] >= y_meters &&
00625 gWorldMap->mUnknownLocation.mdV[1] < y_meters + 256)
00626 {
00627 if (siminfo->mAccess == SIM_ACCESS_DOWN)
00628 {
00629
00630 gWorldMap->mInvalidLocation = true;
00631 }
00632 else
00633 {
00634
00635 bool is_tracking_dbl = gWorldMap->mIsTrackingDoubleClick == TRUE;
00636 gFloaterWorldMap->trackLocation(gWorldMap->mUnknownLocation);
00637 if (is_tracking_dbl)
00638 {
00639 LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
00640 gAgent.teleportViaLocation( pos_global );
00641 }
00642 }
00643 }
00644 }
00645 }
00646
00647 if(adjust) gFloaterWorldMap->adjustZoomSliderBounds();
00648 gFloaterWorldMap->updateSims(found_null_sim);
00649 }
00650
00651
00652 void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**)
00653 {
00654 U32 type;
00655 msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ItemType, type);
00656
00657 S32 num_blocks = msg->getNumberOfBlocks("Data");
00658
00659 for (S32 block=0; block<num_blocks; ++block)
00660 {
00661 U32 X, Y;
00662 char name[MAX_STRING];
00663 S32 extra, extra2;
00664 LLUUID uuid;
00665 msg->getU32Fast(_PREHASH_Data, _PREHASH_X, X, block);
00666 msg->getU32Fast(_PREHASH_Data, _PREHASH_Y, Y, block);
00667 msg->getStringFast(_PREHASH_Data, _PREHASH_Name, MAX_STRING, name, block);
00668 msg->getUUIDFast(_PREHASH_Data, _PREHASH_ID, uuid, block);
00669 msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra, extra, block);
00670 msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra2, extra2, block);
00671
00672 F32 world_x = (F32)X;
00673 X /= REGION_WIDTH_UNITS;
00674 F32 world_y = (F32)Y;
00675 Y /= REGION_WIDTH_UNITS;
00676
00677 LLItemInfo new_item(world_x, world_y, name, uuid, extra, extra2);
00678 LLSimInfo* siminfo = gWorldMap->simInfoFromHandle(new_item.mRegionHandle);
00679
00680 switch (type)
00681 {
00682 case MAP_ITEM_TELEHUB:
00683 {
00684
00685 U8 *color = (U8 *)&new_item.mExtra;
00686
00687 F32 red = fmod((F32)X * 0.11f, 1.f) * 0.8f;
00688 F32 green = fmod((F32)Y * 0.11f, 1.f) * 0.8f;
00689 F32 blue = fmod(1.5f * (F32)(X + Y) * 0.11f, 1.f) * 0.8f;
00690 F32 add_amt = (X % 2) ? 0.15f : -0.15f;
00691 add_amt += (Y % 2) ? -0.15f : 0.15f;
00692 color[0] = U8((red + add_amt) * 255);
00693 color[1] = U8((green + add_amt) * 255);
00694 color[2] = U8((blue + add_amt) * 255);
00695 color[3] = 255;
00696
00697
00698 if (extra2)
00699 {
00700 gWorldMap->mInfohubs.push_back(new_item);
00701 }
00702 else
00703 {
00704 gWorldMap->mTelehubs.push_back(new_item);
00705 }
00706
00707 break;
00708 }
00709 case MAP_ITEM_PG_EVENT:
00710 case MAP_ITEM_MATURE_EVENT:
00711 {
00712 char buffer[32];
00713 struct tm* timep;
00714
00715
00716 timep = utc_to_pacific_time(extra, gPacificDaylightTime);
00717
00718 S32 display_hour = timep->tm_hour % 12;
00719 if (display_hour == 0) display_hour = 12;
00720
00721 snprintf(buffer, sizeof(buffer), "%d:%02d %s",
00722 display_hour,
00723 timep->tm_min,
00724 (timep->tm_hour < 12 ? "AM" : "PM") );
00725 new_item.mToolTip.assign( buffer );
00726
00727
00728 new_item.mPosGlobal.mdV[VZ] = (F64)extra2;
00729 if (type == MAP_ITEM_PG_EVENT)
00730 {
00731 gWorldMap->mPGEvents.push_back(new_item);
00732 }
00733 else
00734 {
00735 gWorldMap->mMatureEvents.push_back(new_item);
00736 }
00737 break;
00738 }
00739 case MAP_ITEM_POPULAR:
00740 {
00741 new_item.mPosGlobal.mdV[VZ] = (F64)extra2;
00742 gWorldMap->mPopular.push_back(new_item);
00743 break;
00744 }
00745 case MAP_ITEM_LAND_FOR_SALE:
00746 {
00747 new_item.mToolTip = llformat("%d sq. m. L$%d", new_item.mExtra, new_item.mExtra2);
00748 gWorldMap->mLandForSale.push_back(new_item);
00749 break;
00750 }
00751 case MAP_ITEM_CLASSIFIED:
00752 {
00753
00754 new_item.mPosGlobal.mdV[VZ] = (F64)extra2;
00755 gWorldMap->mClassifieds.push_back(new_item);
00756 break;
00757 }
00758 case MAP_ITEM_AGENT_LOCATIONS:
00759 {
00760 if (!siminfo)
00761 {
00762 llinfos << "siminfo missing for " << new_item.mPosGlobal.mdV[0] << ", " << new_item.mPosGlobal.mdV[1] << llendl;
00763 break;
00764 }
00765
00766
00767 item_info_list_t& agentcounts = gWorldMap->mAgentLocationsMap[new_item.mRegionHandle];
00768
00769
00770 item_info_list_t::iterator lastiter;
00771 for (lastiter = agentcounts.begin(); lastiter!=agentcounts.end(); ++lastiter)
00772 {
00773 const LLItemInfo& info = *lastiter;
00774 if (info.mName == new_item.mName)
00775 {
00776 break;
00777 }
00778 }
00779 if (lastiter != agentcounts.begin())
00780 {
00781 agentcounts.erase(agentcounts.begin(), lastiter);
00782 }
00783
00784 if (new_item.mExtra > 0)
00785 {
00786 agentcounts.push_back(new_item);
00787 }
00788 break;
00789 }
00790 default:
00791 break;
00792 };
00793 }
00794 }
00795
00796 void LLWorldMap::dump()
00797 {
00798 for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00799 {
00800 U64 handle = (*it).first;
00801 LLSimInfo* info = (*it).second;
00802
00803 U32 x_pos, y_pos;
00804 from_region_handle(handle, &x_pos, &y_pos);
00805
00806 llinfos << x_pos << "," << y_pos
00807 << " " << info->mName.c_str()
00808 << " " << (S32)info->mAccess
00809 << " " << std::hex << info->mRegionFlags << std::dec
00810 << " " << info->mWaterHeight
00811
00812
00813 << llendl;
00814
00815 if (info->mCurrentImage)
00816 {
00817 llinfos << "image discard " << (S32)info->mCurrentImage->getDiscardLevel()
00818 << " fullwidth " << info->mCurrentImage->getWidth(0)
00819 << " fullheight " << info->mCurrentImage->getHeight(0)
00820 << " maxvirt " << info->mCurrentImage->mMaxVirtualSize
00821 << " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel()
00822 << llendl;
00823 }
00824 }
00825 }
00826
00827
00828 BOOL LLWorldMap::extendAABB(U32 min_x, U32 min_y, U32 max_x, U32 max_y)
00829 {
00830 BOOL rv = FALSE;
00831 if (min_x < mMinX)
00832 {
00833 rv = TRUE;
00834 mMinX = min_x;
00835 }
00836 if (min_y < mMinY)
00837 {
00838 rv = TRUE;
00839 mMinY = min_y;
00840 }
00841 if (max_x > mMaxX)
00842 {
00843 rv = TRUE;
00844 mMaxX = max_x;
00845 }
00846 if (max_y > mMaxY)
00847 {
00848 rv = TRUE;
00849 mMaxY = max_y;
00850 }
00851 lldebugs << "World map aabb: (" << mMinX << ", " << mMinY << "), ("
00852 << mMaxX << ", " << mMaxY << ")" << llendl;
00853 return rv;
00854 }
00855
00856
00857 U32 LLWorldMap::getWorldWidth() const
00858 {
00859 return mMaxX - mMinX;
00860 }
00861
00862
00863 U32 LLWorldMap::getWorldHeight() const
00864 {
00865 return mMaxY - mMinY;
00866 }
00867
00868 BOOL LLWorldMap::coveredByTelehub(LLSimInfo* infop)
00869 {
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 return FALSE;
00882 }
00883
00884 void LLWorldMap::updateTelehubCoverage()
00885 {
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 }