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 "llappviewer.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 const F32 REQUEST_ITEMS_TIMER =  10.f * 60.f; // 10 minutes
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 // World Map
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 //      mAgentLocationsMap.clear(); // persists
00179 //      mNumAgents.clear(); // persists
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 // Doesn't clear the already-loaded sim infos, just re-requests them
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                 // Request for telehubs
00286                 sendItemRequest(MAP_ITEM_TELEHUB);
00287         }
00288 
00289         if (mPGEvents.size() == 0)
00290         {
00291                 // Request for events
00292                 sendItemRequest(MAP_ITEM_PG_EVENT);
00293         }
00294 
00295         if (mMatureEvents.size() == 0)
00296         {
00297                 // Request for events (mature)
00298                 sendItemRequest(MAP_ITEM_MATURE_EVENT);
00299         }
00300 
00301         if (mLandForSale.size() == 0)
00302         {
00303                 // Request for Land For Sale
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); // Filled in on sim
00327         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
00328 
00329         msg->nextBlockFast(_PREHASH_RequestData);
00330         msg->addU32Fast(_PREHASH_ItemType, type);
00331         msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim
00332 
00333         gAgent.sendReliableMessage();
00334 }
00335 
00336 // public
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                 // Request for layer
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); // Filled in on sim
00364                 msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
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); // Filled in on sim
00375                         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
00376                         gAgent.sendReliableMessage();
00377                 }
00378         }
00379 }
00380 
00381 // public
00382 void LLWorldMap::sendNamedRegionRequest(std::string region_name)
00383 {
00384         LLMessageSystem* msg = gMessageSystem;
00385         S32 layer = mCurrentMap;
00386 
00387         // Request for layer
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); // Filled in on sim
00394         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
00395         msg->nextBlockFast(_PREHASH_NameData);
00396         msg->addStringFast(_PREHASH_Name, region_name);
00397         gAgent.sendReliableMessage();
00398 }
00399 // public
00400 void LLWorldMap::sendNamedRegionRequest(std::string region_name, 
00401                 url_callback_t callback,
00402                 const std::string& callback_url,
00403                 bool teleport)  // immediately teleport when result returned
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)  // immediately teleport when result returned
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 // public
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); // Filled in on sim
00447         msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
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); // Filled in on sim
00463                 msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim
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 // public static
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         //U32 left, right, top, bottom;
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 // public static
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];          /* Flawfinder: ignore */
00550                 U8 access;              /* Flawfinder: ignore */
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);          /* Flawfinder: ignore */
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                         // This region doesn't exist
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                                 // We were tracking this location, but it doesn't exist
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 //                      llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl;
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;              /* Flawfinder: ignore */
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                                         // We were tracking this location, but it doesn't exist
00634                                         LLWorldMap::getInstance()->mInvalidLocation = true;
00635                                 }
00636                                 else
00637                                 {
00638                                         // We were tracking this location, and it does exist
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                         // Server returns definitive capitalization, SLURL might
00653                         // not have that.
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 // public static
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];          /* Flawfinder: ignore */
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: // telehubs
00703                         {
00704                                 // Telehub color, store in extra as 4 U8's
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                                 // extra2 specifies whether this is an infohub or a telehub.
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: // events
00730                         case MAP_ITEM_MATURE_EVENT:
00731                         {
00732                                 char buffer[32];                /* Flawfinder: ignore */
00733                                 struct tm* timep;
00734                                 // Convert to Pacific, based on server's opinion of whether
00735                                 // it's daylight savings time there.
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",          /* Flawfinder: ignore */
00742                                         display_hour,
00743                                         timep->tm_min,
00744                                         (timep->tm_hour < 12 ? "AM" : "PM") );
00745                                 new_item.mToolTip.assign( buffer );
00746 
00747                                 // HACK: store Z in extra2
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: // 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: // classifieds
00766                         {
00767                                 // HACK: Z-height is in Extra2 field.
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: // 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 //                              llinfos << "New Location " << new_item.mName << llendl;
00780 
00781                                 item_info_list_t& agentcounts = LLWorldMap::getInstance()->mAgentLocationsMap[new_item.mRegionHandle];
00782 
00783                                 // Find the last item in the list with a different name and erase them
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                                 // Now append the new location
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                         //<< " " << info->mTelehubName
00826                         //<< " " << info->mTelehubPosition
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         /*if (!mTelehubCoverageMap)
00885         {
00886                 return FALSE;
00887         }
00888         U32 x_pos, y_pos;
00889         from_region_handle(infop->mHandle, &x_pos, &y_pos);
00890         x_pos /= REGION_WIDTH_UNITS;
00891         y_pos /= REGION_WIDTH_UNITS;
00892 
00893         S32 index = x_pos - (mMinX / REGION_WIDTH_UNITS - 1) + (mNeighborMapWidth * (y_pos - (mMinY / REGION_WIDTH_UNITS - 1)));
00894         return mTelehubCoverageMap[index] != 0; */
00895         return FALSE;
00896 }
00897 
00898 void LLWorldMap::updateTelehubCoverage()
00899 {
00900         /*S32 neighbor_width = getWorldWidth() / REGION_WIDTH_UNITS + 2;
00901         S32 neighbor_height = getWorldHeight() / REGION_WIDTH_UNITS + 2;
00902         if (neighbor_width > mNeighborMapWidth || neighbor_height > mNeighborMapHeight)
00903         {
00904                 mNeighborMapWidth = neighbor_width;
00905                 mNeighborMapHeight = neighbor_height;
00906                 delete mNeighborMap;
00907                 delete mTelehubCoverageMap;
00908 
00909                 mNeighborMap = new U8[mNeighborMapWidth * mNeighborMapHeight];
00910                 mTelehubCoverageMap = new U8[mNeighborMapWidth * mNeighborMapHeight];
00911         }
00912 
00913         memset(mNeighborMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8));
00914         memset(mTelehubCoverageMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8));
00915 
00916         // leave 1 sim border
00917         S32 min_x = (mMinX / REGION_WIDTH_UNITS) - 1;
00918         S32 min_y = (mMinY / REGION_WIDTH_UNITS) - 1;
00919 
00920         std::map<U64, LLSimInfo*>::const_iterator it;
00921         for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00922         {
00923                 U64 handle = (*it).first;
00924                 //LLSimInfo* info = (*it).second;
00925 
00926                 U32 x_pos, y_pos;
00927                 from_region_handle(handle, &x_pos, &y_pos);
00928                 x_pos /= REGION_WIDTH_UNITS;
00929                 y_pos /= REGION_WIDTH_UNITS;
00930                 x_pos -= min_x;
00931                 y_pos -= min_y;
00932 
00933                 S32 index = x_pos + (mNeighborMapWidth * y_pos);
00934                 mNeighborMap[index - 1]++;
00935                 mNeighborMap[index + 1]++;
00936                 mNeighborMap[index - mNeighborMapWidth]++;
00937                 mNeighborMap[index + mNeighborMapWidth]++;
00938         }
00939 
00940         for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00941         {
00942                 U64 handle = (*it).first;
00943                 LLSimInfo* info = (*it).second;
00944 
00945                 U32 x_pos, y_pos;
00946                 from_region_handle(handle, &x_pos, &y_pos);
00947                 x_pos /= REGION_WIDTH_UNITS;
00948                 y_pos /= REGION_WIDTH_UNITS;
00949                 x_pos -= min_x;
00950                 y_pos -= min_y;
00951 
00952                 S32 index = x_pos + (mNeighborMapWidth * y_pos);
00953 
00954                 if (!info->mTelehubName.empty() && mNeighborMap[index])
00955                 {
00956                         S32 x_start = llmax(0, S32(x_pos - 5));
00957                         S32 x_span = llmin(mNeighborMapWidth - 1, (S32)(x_pos + 5)) - x_start + 1;
00958                         S32 y_start = llmax(0, (S32)y_pos - 5);
00959                         S32 y_end = llmin(mNeighborMapHeight - 1, (S32)(y_pos + 5));
00960                         for (S32 y_index = y_start; y_index <= y_end; y_index++)
00961                         {
00962                                 memset(&mTelehubCoverageMap[x_start + y_index * mNeighborMapWidth], 0xff, sizeof(U8) * x_span);
00963                         }
00964                 }
00965         }
00966 
00967         for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it)
00968         {
00969                 U64 handle = (*it).first;
00970                 //LLSimInfo* info = (*it).second;
00971 
00972                 U32 x_pos, y_pos;
00973                 from_region_handle(handle, &x_pos, &y_pos);
00974                 x_pos /= REGION_WIDTH_UNITS;
00975                 y_pos /= REGION_WIDTH_UNITS;
00976 
00977                 S32 index = x_pos - min_x + (mNeighborMapWidth * (y_pos - min_y));
00978                 mTelehubCoverageMap[index] *= mNeighborMap[index];
00979         }*/
00980 }

Generated on Fri May 16 08:34:26 2008 for SecondLife by  doxygen 1.5.5