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