llworldmap.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llworldmap.h"
00035 
00036 #include "llregionhandle.h"
00037 #include "message.h"
00038 
00039 #include "viewer.h"     // for gPacificDaylightTime
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; // 10 minutes
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 // World Map
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 //      mAgentLocationsMap.clear(); // persists
00181 //      mNumAgents.clear(); // persists
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 // Doesn't clear the already-loaded sim infos, just re-requests them
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                 // Request for telehubs
00288                 sendItemRequest(MAP_ITEM_TELEHUB);
00289         }
00290 
00291         if (mPGEvents.size() == 0)
00292         {
00293                 // Request for events
00294                 sendItemRequest(MAP_ITEM_PG_EVENT);
00295         }
00296 
00297         if (mMatureEvents.size() == 0)
00298         {
00299                 // Request for events (mature)
00300                 sendItemRequest(MAP_ITEM_MATURE_EVENT);
00301         }
00302 
00303         if (mPopular.size() == 0)
00304         {
00305                 // Request for popular
00306                 sendItemRequest(MAP_ITEM_POPULAR);
00307         }
00308 
00309         if (mLandForSale.size() == 0)
00310         {
00311                 // Request for Land For Sale
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); // Filled in on sim
00335         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
00336 
00337         msg->nextBlockFast(_PREHASH_RequestData);
00338         msg->addU32Fast(_PREHASH_ItemType, type);
00339         msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim
00340 
00341         gAgent.sendReliableMessage();
00342 }
00343 
00344 // public
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                 // Request for layer
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); // Filled in on sim
00370                 msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
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); // Filled in on sim
00381                         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
00382                         gAgent.sendReliableMessage();
00383                 }
00384         }
00385 }
00386 
00387 // public
00388 void LLWorldMap::sendNamedRegionRequest(std::string region_name)
00389 {
00390         LLMessageSystem* msg = gMessageSystem;
00391         S32 layer = mCurrentMap;
00392 
00393         // Request for layer
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); // Filled in on sim
00400         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
00401         msg->nextBlockFast(_PREHASH_NameData);
00402         msg->addStringFast(_PREHASH_Name, region_name);
00403         gAgent.sendReliableMessage();
00404 }
00405 // public
00406 void LLWorldMap::sendNamedRegionRequest(std::string region_name, 
00407                 url_callback_t callback,
00408                 const std::string& callback_url,
00409                 bool teleport)  // immediately teleport when result returned
00410 {
00411         mSLURLRegionName = region_name;
00412         mSLURL = callback_url;
00413         mSLURLCallback = callback;
00414         mSLURLTeleport = teleport;
00415 
00416         sendNamedRegionRequest(region_name);
00417 }
00418 
00419 // public
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); // Filled in on sim
00432         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
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); // Filled in on sim
00448                 msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
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 // public static
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         //U32 left, right, top, bottom;
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 // public static
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];          /* Flawfinder: ignore */
00535                 U8 access;              /* Flawfinder: ignore */
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);          /* Flawfinder: ignore */
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                         // This region doesn't exist
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                                 // We were tracking this location, but it doesn't exist
00564                                 gWorldMap->mInvalidLocation = TRUE;
00565                         }
00566 
00567                         found_null_sim = true;
00568                 }
00569                 else if(gWorldMap->mSLURLCallback != NULL)
00570                 {
00571                         // Server returns definitive capitalization, SLURL might
00572                         // not have that.
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 //                      llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl;
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;              /* Flawfinder: ignore */
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                                         // We were tracking this location, but it doesn't exist
00630                                         gWorldMap->mInvalidLocation = true;
00631                                 }
00632                                 else
00633                                 {
00634                                         // We were tracking this location, and it does exist
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 // public static
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];          /* Flawfinder: ignore */
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: // telehubs
00683                         {
00684                                 // Telehub color, store in extra as 4 U8's
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                                 // extra2 specifies whether this is an infohub or a telehub.
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: // events
00710                         case MAP_ITEM_MATURE_EVENT:
00711                         {
00712                                 char buffer[32];                /* Flawfinder: ignore */
00713                                 struct tm* timep;
00714                                 // Convert to Pacific, based on server's opinion of whether
00715                                 // it's daylight savings time there.
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",          /* Flawfinder: ignore */
00722                                         display_hour,
00723                                         timep->tm_min,
00724                                         (timep->tm_hour < 12 ? "AM" : "PM") );
00725                                 new_item.mToolTip.assign( buffer );
00726 
00727                                 // HACK: store Z in extra2
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: // 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: // 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: // classifieds
00752                         {
00753                                 // HACK: Z-height is in Extra2 field.
00754                                 new_item.mPosGlobal.mdV[VZ] = (F64)extra2;
00755                                 gWorldMap->mClassifieds.push_back(new_item);
00756                                 break;
00757                         }
00758                         case MAP_ITEM_AGENT_LOCATIONS: // 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 //                              llinfos << "New Location " << new_item.mName << llendl;
00766 
00767                                 item_info_list_t& agentcounts = gWorldMap->mAgentLocationsMap[new_item.mRegionHandle];
00768 
00769                                 // Find the last item in the list with a different name and erase them
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                                 // Now append the new location
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                         //<< " " << info->mTelehubName
00812                         //<< " " << info->mTelehubPosition
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         /*if (!mTelehubCoverageMap)
00871         {
00872                 return FALSE;
00873         }
00874         U32 x_pos, y_pos;
00875         from_region_handle(infop->mHandle, &x_pos, &y_pos);
00876         x_pos /= REGION_WIDTH_UNITS;
00877         y_pos /= REGION_WIDTH_UNITS;
00878 
00879         S32 index = x_pos - (mMinX / REGION_WIDTH_UNITS - 1) + (mNeighborMapWidth * (y_pos - (mMinY / REGION_WIDTH_UNITS - 1)));
00880         return mTelehubCoverageMap[index] != 0; */
00881         return FALSE;
00882 }
00883 
00884 void LLWorldMap::updateTelehubCoverage()
00885 {
00886         /*S32 neighbor_width = getWorldWidth() / REGION_WIDTH_UNITS + 2;
00887         S32 neighbor_height = getWorldHeight() / REGION_WIDTH_UNITS + 2;
00888         if (neighbor_width > mNeighborMapWidth || neighbor_height > mNeighborMapHeight)
00889         {
00890                 mNeighborMapWidth = neighbor_width;
00891                 mNeighborMapHeight = neighbor_height;
00892                 delete mNeighborMap;
00893                 delete mTelehubCoverageMap;
00894 
00895                 mNeighborMap = new U8[mNeighborMapWidth * mNeighborMapHeight];
00896                 mTelehubCoverageMap = new U8[mNeighborMapWidth * mNeighborMapHeight];
00897         }
00898 
00899         memset(mNeighborMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8));
00900         memset(mTelehubCoverageMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8));
00901 
00902         // leave 1 sim border
00903         S32 min_x = (mMinX / REGION_WIDTH_UNITS) - 1;
00904         S32 min_y = (mMinY / REGION_WIDTH_UNITS) - 1;
00905 
00906         std::map<U64, LLSimInfo*>::const_iterator it;
00907         for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00908         {
00909                 U64 handle = (*it).first;
00910                 //LLSimInfo* info = (*it).second;
00911 
00912                 U32 x_pos, y_pos;
00913                 from_region_handle(handle, &x_pos, &y_pos);
00914                 x_pos /= REGION_WIDTH_UNITS;
00915                 y_pos /= REGION_WIDTH_UNITS;
00916                 x_pos -= min_x;
00917                 y_pos -= min_y;
00918 
00919                 S32 index = x_pos + (mNeighborMapWidth * y_pos);
00920                 mNeighborMap[index - 1]++;
00921                 mNeighborMap[index + 1]++;
00922                 mNeighborMap[index - mNeighborMapWidth]++;
00923                 mNeighborMap[index + mNeighborMapWidth]++;
00924         }
00925 
00926         for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00927         {
00928                 U64 handle = (*it).first;
00929                 LLSimInfo* info = (*it).second;
00930 
00931                 U32 x_pos, y_pos;
00932                 from_region_handle(handle, &x_pos, &y_pos);
00933                 x_pos /= REGION_WIDTH_UNITS;
00934                 y_pos /= REGION_WIDTH_UNITS;
00935                 x_pos -= min_x;
00936                 y_pos -= min_y;
00937 
00938                 S32 index = x_pos + (mNeighborMapWidth * y_pos);
00939 
00940                 if (!info->mTelehubName.empty() && mNeighborMap[index])
00941                 {
00942                         S32 x_start = llmax(0, S32(x_pos - 5));
00943                         S32 x_span = llmin(mNeighborMapWidth - 1, (S32)(x_pos + 5)) - x_start + 1;
00944                         S32 y_start = llmax(0, (S32)y_pos - 5);
00945                         S32 y_end = llmin(mNeighborMapHeight - 1, (S32)(y_pos + 5));
00946                         for (S32 y_index = y_start; y_index <= y_end; y_index++)
00947                         {
00948                                 memset(&mTelehubCoverageMap[x_start + y_index * mNeighborMapWidth], 0xff, sizeof(U8) * x_span);
00949                         }
00950                 }
00951         }
00952 
00953         for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00954         {
00955                 U64 handle = (*it).first;
00956                 //LLSimInfo* info = (*it).second;
00957 
00958                 U32 x_pos, y_pos;
00959                 from_region_handle(handle, &x_pos, &y_pos);
00960                 x_pos /= REGION_WIDTH_UNITS;
00961                 y_pos /= REGION_WIDTH_UNITS;
00962 
00963                 S32 index = x_pos - min_x + (mNeighborMapWidth * (y_pos - min_y));
00964                 mTelehubCoverageMap[index] *= mNeighborMap[index];
00965         }*/
00966 }

Generated on Thu Jul 1 06:09:47 2010 for Second Life Viewer by  doxygen 1.4.7