diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/newview/llworldmap.cpp |
Print done when done.
Diffstat (limited to 'indra/newview/llworldmap.cpp')
-rw-r--r-- | indra/newview/llworldmap.cpp | 915 |
1 files changed, 915 insertions, 0 deletions
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp new file mode 100644 index 0000000000..42d8b9fd20 --- /dev/null +++ b/indra/newview/llworldmap.cpp @@ -0,0 +1,915 @@ +/** + * @file llworldmap.cpp + * @brief Underlying data representation for map of the world + * + * Copyright (c) 2003-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llworldmap.h" + +#include "llregionhandle.h" +#include "message.h" + +#include "viewer.h" // for gPacificDaylightTime +#include "llagent.h" +#include "llmapresponders.h" +#include "llviewercontrol.h" +#include "llfloaterworldmap.h" +#include "lltracker.h" +#include "llviewerimagelist.h" +#include "llviewerregion.h" +#include "llregionflags.h" + +LLWorldMap* gWorldMap = NULL; + +const F32 REQUEST_ITEMS_TIMER = 10.f * 60.f; // 10 minutes + +LLItemInfo::LLItemInfo(F32 global_x, F32 global_y, + const std::string& name, + LLUUID id, + S32 extra, S32 extra2) +: mName(name), + mToolTip(""), + mPosGlobal(global_x, global_y, 40.0), + mID(id), + mSelected(FALSE), + mExtra(extra), + mExtra2(extra2) +{ + mRegionHandle = to_region_handle(mPosGlobal); +} + +LLSimInfo::LLSimInfo() +: mHandle(0), + mName(), + mAgentsUpdateTime(0), + mAccess(0x0), + mRegionFlags(0x0), + mWaterHeight(0.f), + mAlpha(-1.f) +{ +} + + +LLVector3d LLSimInfo::getGlobalPos(LLVector3 local_pos) const +{ + LLVector3d pos = from_region_handle(mHandle); + pos.mdV[VX] += local_pos.mV[VX]; + pos.mdV[VY] += local_pos.mV[VY]; + pos.mdV[VZ] += local_pos.mV[VZ]; + return pos; +} + + +//--------------------------------------------------------------------------- +// World Map +//--------------------------------------------------------------------------- + +LLWorldMap::LLWorldMap() : + mIsTrackingUnknownLocation( FALSE ), + mInvalidLocation( FALSE ), + mIsTrackingDoubleClick( FALSE ), + mIsTrackingCommit( FALSE ), + mUnknownLocation( 0, 0, 0 ), + mRequestLandForSale(true), + mCurrentMap(0), + mMinX(U32_MAX), + mMaxX(U32_MIN), + mMinY(U32_MAX), + mMaxY(U32_MIN), + mNeighborMap(NULL), + mTelehubCoverageMap(NULL), + mNeighborMapWidth(0), + mNeighborMapHeight(0) +{ + for (S32 map=0; map<MAP_SIM_IMAGE_TYPES; ++map) + { + mMapLoaded[map] = FALSE; + mMapBlockLoaded[map] = new BOOL[MAP_BLOCK_RES*MAP_BLOCK_RES]; + for (S32 idx=0; idx<MAP_BLOCK_RES*MAP_BLOCK_RES; ++idx) + { + mMapBlockLoaded[map][idx] = FALSE; + } + } +} + + +LLWorldMap::~LLWorldMap() +{ + reset(); + for (S32 map=0; map<MAP_SIM_IMAGE_TYPES; ++map) + { + delete[] mMapBlockLoaded[map]; + } +} + + +void LLWorldMap::reset() +{ + for_each(mSimInfoMap.begin(), mSimInfoMap.end(), DeletePairedPointer()); + mSimInfoMap.clear(); + + for (S32 m=0; m<MAP_SIM_IMAGE_TYPES; ++m) + { + mMapLoaded[m] = FALSE; + } + + clearSimFlags(); + + eraseItems(); + + mMinX = U32_MAX; + mMaxX = U32_MIN; + + mMinY = U32_MAX; + mMaxY = U32_MIN; + + delete [] mNeighborMap; + mNeighborMap = NULL; + delete [] mTelehubCoverageMap; + mTelehubCoverageMap = NULL; + + mNeighborMapWidth = 0; + mNeighborMapHeight = 0; +} + +void LLWorldMap::eraseItems() +{ + if (mRequestTimer.getElapsedTimeF32() > REQUEST_ITEMS_TIMER) + { + mRequestTimer.reset(); + + mTelehubs.clear(); + mInfohubs.clear(); + mPGEvents.clear(); + mMatureEvents.clear(); + mPopular.clear(); + mLandForSale.clear(); + mClassifieds.clear(); + } +// mAgentLocationsMap.clear(); // persists +// mNumAgents.clear(); // persists +} + + +void LLWorldMap::clearImageRefs() +{ + for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + LLSimInfo* info = (*it).second; + if (info->mCurrentImage) + { + info->mCurrentImage->setBoostLevel(0); + info->mCurrentImage = NULL; + } + if (info->mOverlayImage) + { + info->mOverlayImage->setBoostLevel(0); + info->mOverlayImage = NULL; + } + } +} + +// Doesn't clear the already-loaded sim infos, just re-requests them +void LLWorldMap::clearSimFlags() +{ + for (S32 map=0; map<MAP_SIM_IMAGE_TYPES; ++map) + { + for (S32 idx=0; idx<MAP_BLOCK_RES*MAP_BLOCK_RES; ++idx) + { + mMapBlockLoaded[map][idx] = FALSE; + } + } +} + +LLSimInfo* LLWorldMap::simInfoFromPosGlobal(const LLVector3d& pos_global) +{ + U64 handle = to_region_handle(pos_global); + return simInfoFromHandle(handle); +} + +LLSimInfo* LLWorldMap::simInfoFromHandle(const U64 handle) +{ + sim_info_map_t::iterator it = mSimInfoMap.find(handle); + if (it != mSimInfoMap.end()) + { + LLSimInfo* sim_info = (*it).second; + if (sim_info) + { + return sim_info; + } + } + return NULL; +} + + +LLSimInfo* LLWorldMap::simInfoFromName(const LLString& sim_name) +{ + LLSimInfo* sim_info = NULL; + if (!sim_name.empty()) + { + for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + sim_info = (*it).second; + if (sim_info + && (0 == LLString::compareInsensitive(sim_name.c_str(), sim_info->mName.c_str())) ) + { + break; + } + sim_info = NULL; + } + } + return sim_info; +} + +LLString LLWorldMap::simNameFromPosGlobal(const LLVector3d& pos_global) +{ + U64 handle = to_region_handle(pos_global); + + sim_info_map_t::iterator it = mSimInfoMap.find(handle); + if (it != mSimInfoMap.end()) + { + LLSimInfo* info = (*it).second; + return info->mName.c_str(); + } + else + { + return "(unknown region)"; + } +} + +void LLWorldMap::setCurrentLayer(S32 layer, bool request_layer) +{ + mCurrentMap = layer; + if (!mMapLoaded[layer] || request_layer) + { + sendMapLayerRequest(); + sendItemRequest(MAP_ITEM_AGENT_COUNT); + } + + if (mTelehubs.size() == 0 || + mInfohubs.size() == 0) + { + // Request for telehubs + sendItemRequest(MAP_ITEM_TELEHUB); + } + + if (mPGEvents.size() == 0) + { + // Request for events + sendItemRequest(MAP_ITEM_PG_EVENT); + } + + if (mMatureEvents.size() == 0) + { + // Request for events (mature) + sendItemRequest(MAP_ITEM_MATURE_EVENT); + } + + if (mPopular.size() == 0) + { + // Request for popular + sendItemRequest(MAP_ITEM_POPULAR); + } + + if (mLandForSale.size() == 0) + { + // Request for Land For Sale + sendItemRequest(MAP_ITEM_LAND_FOR_SALE); + } + + if (mClassifieds.size() == 0) + { + sendItemRequest(MAP_ITEM_CLASSIFIED); + } + + clearImageRefs(); + clearSimFlags(); +} + +void LLWorldMap::sendItemRequest(U32 type, U64 handle) +{ + LLMessageSystem* msg = gMessageSystem; + S32 layer = mCurrentMap; + + msg->newMessageFast(_PREHASH_MapItemRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, layer); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + + msg->nextBlockFast(_PREHASH_RequestData); + msg->addU32Fast(_PREHASH_ItemType, type); + msg->addU64Fast(_PREHASH_RegionHandle, handle); // If zero, filled in on sim + + gAgent.sendReliableMessage(); +} + +// public +void LLWorldMap::sendMapLayerRequest() +{ + LLSD body; + body["Flags"] = mCurrentMap; + std::string url = gAgent.getRegion()->getCapability( + gAgent.isGodlike() ? "MapLayerGod" : "MapLayer"); + + if (!url.empty()) + { + llinfos << "LLWorldMap::sendMapLayerRequest via capability" << llendl; + LLHTTPClient::post(url, body, new LLMapLayerResponder()); + } + else + { + llinfos << "LLWorldMap::sendMapLayerRequest via message system" << llendl; + LLMessageSystem* msg = gMessageSystem; + S32 layer = mCurrentMap; + + // Request for layer + msg->newMessageFast(_PREHASH_MapLayerRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, layer); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + gAgent.sendReliableMessage(); + + if (mRequestLandForSale) + { + msg->newMessageFast(_PREHASH_MapLayerRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, 2); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + gAgent.sendReliableMessage(); + } + } +} + +// public +void LLWorldMap::sendNamedRegionRequest(std::string region_name) +{ + LLMessageSystem* msg = gMessageSystem; + S32 layer = mCurrentMap; + + // Request for layer + msg->newMessageFast(_PREHASH_MapNameRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, layer); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + msg->nextBlockFast(_PREHASH_NameData); + msg->addStringFast(_PREHASH_Name, region_name); + gAgent.sendReliableMessage(); +} + +// public +void LLWorldMap::sendMapBlockRequest(U16 min_x, U16 min_y, U16 max_x, U16 max_y, bool return_nonexistent) +{ + S32 layer = mCurrentMap; + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MapBlockRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + U32 flags = layer; + flags |= (return_nonexistent ? 0x10000 : 0); + msg->addU32Fast(_PREHASH_Flags, flags); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + msg->nextBlockFast(_PREHASH_PositionData); + msg->addU16Fast(_PREHASH_MinX, min_x); + msg->addU16Fast(_PREHASH_MinY, min_y); + msg->addU16Fast(_PREHASH_MaxX, max_x); + msg->addU16Fast(_PREHASH_MaxY, max_y); + gAgent.sendReliableMessage(); + + if (mRequestLandForSale) + { + msg->newMessageFast(_PREHASH_MapBlockRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_Flags, 2); + msg->addU32Fast(_PREHASH_EstateID, 0); // Filled in on sim + msg->addBOOLFast(_PREHASH_Godlike, FALSE); // Filled in on sim + msg->nextBlockFast(_PREHASH_PositionData); + msg->addU16Fast(_PREHASH_MinX, min_x); + msg->addU16Fast(_PREHASH_MinY, min_y); + msg->addU16Fast(_PREHASH_MaxX, max_x); + msg->addU16Fast(_PREHASH_MaxY, max_y); + gAgent.sendReliableMessage(); + } +} + +// public static +void LLWorldMap::processMapLayerReply(LLMessageSystem* msg, void**) +{ + llinfos << "LLWorldMap::processMapLayerReply from message system" << llendl; + + U32 agent_flags; + msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); + + if (agent_flags != (U32)gWorldMap->mCurrentMap) + { + llwarns << "Invalid or out of date map image type returned!" << llendl; + return; + } + + LLUUID image_id; + //U32 left, right, top, bottom; + + S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_LayerData); + + gWorldMap->mMapLayers[agent_flags].clear(); + + BOOL adjust = FALSE; + for (S32 block=0; block<num_blocks; ++block) + { + LLWorldMapLayer new_layer; + new_layer.LayerDefined = TRUE; + msg->getUUIDFast(_PREHASH_LayerData, _PREHASH_ImageID, new_layer.LayerImageID, block); + new_layer.LayerImage = gImageList.getImage(new_layer.LayerImageID, MIPMAP_TRUE, FALSE); + new_layer.LayerImage->bindTexture(0); + new_layer.LayerImage->setClamp(TRUE, TRUE); + + U32 left, right, top, bottom; + msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Left, left, block); + msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Right, right, block); + msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Top, top, block); + msg->getU32Fast(_PREHASH_LayerData, _PREHASH_Bottom, bottom, block); + + new_layer.LayerExtents.mLeft = left; + new_layer.LayerExtents.mRight = right; + new_layer.LayerExtents.mBottom = bottom; + new_layer.LayerExtents.mTop = top; + + F32 x_meters = F32(left*REGION_WIDTH_UNITS); + F32 y_meters = F32(bottom*REGION_WIDTH_UNITS); + adjust = gWorldMap->extendAABB(U32(x_meters), U32(y_meters), + U32(x_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getWidth()), + U32(y_meters+REGION_WIDTH_UNITS*new_layer.LayerExtents.getHeight())) || adjust; + + gWorldMap->mMapLayers[agent_flags].push_back(new_layer); + } + + gWorldMap->mMapLoaded[agent_flags] = TRUE; + if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); +} + +// public static +void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) +{ + U32 agent_flags; + msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); + + if (agent_flags < 0 || agent_flags >= MAP_SIM_IMAGE_TYPES) + { + llwarns << "Invalid map image type returned! " << agent_flags << llendl; + return; + } + + S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_Data); + + bool found_null_sim = false; + + BOOL adjust = FALSE; + for (S32 block=0; block<num_blocks; ++block) + { + U16 x_regions; + U16 y_regions; + char name[MAX_STRING]; + U8 access; + U32 region_flags; + U8 water_height; + U8 agents; + LLUUID image_id; + msg->getU16Fast(_PREHASH_Data, _PREHASH_X, x_regions, block); + msg->getU16Fast(_PREHASH_Data, _PREHASH_Y, y_regions, block); + msg->getStringFast(_PREHASH_Data, _PREHASH_Name, MAX_STRING, name, block); + msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, access, block); + msg->getU32Fast(_PREHASH_Data, _PREHASH_RegionFlags, region_flags, block); + msg->getU8Fast(_PREHASH_Data, _PREHASH_WaterHeight, water_height, block); + msg->getU8Fast(_PREHASH_Data, _PREHASH_Agents, agents, block); + msg->getUUIDFast(_PREHASH_Data, _PREHASH_MapImageID, image_id, block); + + U32 x_meters = x_regions * REGION_WIDTH_UNITS; + U32 y_meters = y_regions * REGION_WIDTH_UNITS; + + if (access == 255) + { + // This region doesn't exist + if (gWorldMap->mIsTrackingUnknownLocation && + gWorldMap->mUnknownLocation.mdV[0] >= x_meters && + gWorldMap->mUnknownLocation.mdV[0] < x_meters + 256 && + gWorldMap->mUnknownLocation.mdV[1] >= y_meters && + gWorldMap->mUnknownLocation.mdV[1] < y_meters + 256) + { + // We were tracking this location, but it doesn't exist + gWorldMap->mInvalidLocation = TRUE; + } + + found_null_sim = true; + } + else + { + adjust = gWorldMap->extendAABB(x_meters, + y_meters, + x_meters+REGION_WIDTH_UNITS, + y_meters+REGION_WIDTH_UNITS) || adjust; + U64 handle = to_region_handle(x_meters, y_meters); + +// llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl; + + LLSimInfo* siminfo = new LLSimInfo(); + sim_info_map_t::iterator iter = gWorldMap->mSimInfoMap.find(handle); + if (iter != gWorldMap->mSimInfoMap.end()) + { + LLSimInfo* oldinfo = iter->second; + for (S32 image=0; image<MAP_SIM_IMAGE_TYPES; ++image) + { + siminfo->mMapImageID[image] = oldinfo->mMapImageID[image]; + } + delete oldinfo; + } + gWorldMap->mSimInfoMap[handle] = siminfo; + + siminfo->mHandle = handle; + siminfo->mName.assign( name ); + siminfo->mAccess = access; + siminfo->mRegionFlags = region_flags; + siminfo->mWaterHeight = (F32) water_height; + siminfo->mMapImageID[agent_flags] = image_id; + siminfo->mCurrentImage = gImageList.getImage(siminfo->mMapImageID[gWorldMap->mCurrentMap], MIPMAP_TRUE, FALSE); + siminfo->mCurrentImage->bindTexture(0); + siminfo->mCurrentImage->setClamp(TRUE, TRUE); + + if (siminfo->mMapImageID[2].notNull()) + { + siminfo->mOverlayImage = gImageList.getImage(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE); + } + else + { + siminfo->mOverlayImage = NULL; + } + + if (gWorldMap->mIsTrackingUnknownLocation && + gWorldMap->mUnknownLocation.mdV[0] >= x_meters && + gWorldMap->mUnknownLocation.mdV[0] < x_meters + 256 && + gWorldMap->mUnknownLocation.mdV[1] >= y_meters && + gWorldMap->mUnknownLocation.mdV[1] < y_meters + 256) + { + if (siminfo->mAccess == SIM_ACCESS_DOWN) + { + // We were tracking this location, but it doesn't exist + gWorldMap->mInvalidLocation = true; + } + else + { + // We were tracking this location, and it does exist + bool is_tracking_dbl = gWorldMap->mIsTrackingDoubleClick == TRUE; + gFloaterWorldMap->trackLocation(gWorldMap->mUnknownLocation); + if (is_tracking_dbl) + { + LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); + gAgent.teleportViaLocation( pos_global ); + } + } + } + } + } + if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); + gFloaterWorldMap->updateSims(found_null_sim); +} + +// public static +void LLWorldMap::processMapItemReply(LLMessageSystem* msg, void**) +{ + U32 type; + msg->getU32Fast(_PREHASH_RequestData, _PREHASH_ItemType, type); + + S32 num_blocks = msg->getNumberOfBlocks("Data"); + + for (S32 block=0; block<num_blocks; ++block) + { + U32 X, Y; + char name[MAX_STRING]; + S32 extra, extra2; + LLUUID uuid; + msg->getU32Fast(_PREHASH_Data, _PREHASH_X, X, block); + msg->getU32Fast(_PREHASH_Data, _PREHASH_Y, Y, block); + msg->getStringFast(_PREHASH_Data, _PREHASH_Name, MAX_STRING, name, block); + msg->getUUIDFast(_PREHASH_Data, _PREHASH_ID, uuid, block); + msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra, extra, block); + msg->getS32Fast(_PREHASH_Data, _PREHASH_Extra2, extra2, block); + + F32 world_x = (F32)X; + X /= REGION_WIDTH_UNITS; + F32 world_y = (F32)Y; + Y /= REGION_WIDTH_UNITS; + + LLItemInfo new_item(world_x, world_y, name, uuid, extra, extra2); + LLSimInfo* siminfo = gWorldMap->simInfoFromHandle(new_item.mRegionHandle); + + switch (type) + { + case MAP_ITEM_TELEHUB: // telehubs + { + // Telehub color, store in extra as 4 U8's + U8 *color = (U8 *)&new_item.mExtra; + + F32 red = fmod((F32)X * 0.11f, 1.f) * 0.8f; + F32 green = fmod((F32)Y * 0.11f, 1.f) * 0.8f; + F32 blue = fmod(1.5f * (F32)(X + Y) * 0.11f, 1.f) * 0.8f; + F32 add_amt = (X % 2) ? 0.15f : -0.15f; + add_amt += (Y % 2) ? -0.15f : 0.15f; + color[0] = U8((red + add_amt) * 255); + color[1] = U8((green + add_amt) * 255); + color[2] = U8((blue + add_amt) * 255); + color[3] = 255; + + // extra2 specifies whether this is an infohub or a telehub. + if (extra2) + { + gWorldMap->mInfohubs.push_back(new_item); + } + else + { + gWorldMap->mTelehubs.push_back(new_item); + } + + break; + } + case MAP_ITEM_PG_EVENT: // events + case MAP_ITEM_MATURE_EVENT: + { + char buffer[32]; + struct tm* timep; + // Convert to Pacific, based on server's opinion of whether + // it's daylight savings time there. + timep = utc_to_pacific_time(extra, gPacificDaylightTime); + + S32 display_hour = timep->tm_hour % 12; + if (display_hour == 0) display_hour = 12; + + sprintf(buffer, "%d:%02d %s", + display_hour, + timep->tm_min, + (timep->tm_hour < 12 ? "AM" : "PM") ); + new_item.mToolTip.assign( buffer ); + + // HACK: store Z in extra2 + new_item.mPosGlobal.mdV[VZ] = (F64)extra2; + if (type == MAP_ITEM_PG_EVENT) + { + gWorldMap->mPGEvents.push_back(new_item); + } + else + { + gWorldMap->mMatureEvents.push_back(new_item); + } + break; + } + case MAP_ITEM_POPULAR: // popular + { + new_item.mPosGlobal.mdV[VZ] = (F64)extra2; + gWorldMap->mPopular.push_back(new_item); + break; + } + case MAP_ITEM_LAND_FOR_SALE: // land for sale + { + new_item.mToolTip = llformat("%d sq. m. L$%d", new_item.mExtra, new_item.mExtra2); + gWorldMap->mLandForSale.push_back(new_item); + break; + } + case MAP_ITEM_CLASSIFIED: // classifieds + { + // HACK: Z-height is in Extra2 field. + new_item.mPosGlobal.mdV[VZ] = (F64)extra2; + gWorldMap->mClassifieds.push_back(new_item); + break; + } + case MAP_ITEM_AGENT_COUNT: // agent counts + { + // We only ever receive one per region, i.e. this update superceeds any others + gWorldMap->mNumAgents[new_item.mRegionHandle] = new_item.mExtra; + break; + } + case MAP_ITEM_AGENT_LOCATIONS: // agent locations + { + if (!siminfo) + { + llinfos << "siminfo missing for " << new_item.mPosGlobal.mdV[0] << ", " << new_item.mPosGlobal.mdV[1] << llendl; + break; + } +// llinfos << "New Location " << new_item.mName << llendl; + + item_info_list_t& agentcounts = gWorldMap->mAgentLocationsMap[new_item.mRegionHandle]; + + // Find the last item in the list with a different name and erase them + item_info_list_t::iterator lastiter; + for (lastiter = agentcounts.begin(); lastiter!=agentcounts.end(); ++lastiter) + { + const LLItemInfo& info = *lastiter; + if (info.mName == new_item.mName) + { + break; + } + } + if (lastiter != agentcounts.begin()) + { + agentcounts.erase(agentcounts.begin(), lastiter); + } + // Now append the new location + if (new_item.mExtra > 0) + { + agentcounts.push_back(new_item); + } + break; + } + default: + break; + }; + } +} + +void LLWorldMap::dump() +{ + for (sim_info_map_t::iterator it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + U64 handle = (*it).first; + LLSimInfo* info = (*it).second; + + U32 x_pos, y_pos; + from_region_handle(handle, &x_pos, &y_pos); + + llinfos << x_pos << "," << y_pos + << " " << info->mName.c_str() + << " " << (S32)info->mAccess + << " " << std::hex << info->mRegionFlags << std::dec + << " " << info->mWaterHeight + //<< " " << info->mTelehubName + //<< " " << info->mTelehubPosition + << llendl; + + if (info->mCurrentImage) + { + llinfos << "image discard " << (S32)info->mCurrentImage->getDiscardLevel() + << " fullwidth " << info->mCurrentImage->getWidth(0) + << " fullheight " << info->mCurrentImage->getHeight(0) + << " maxvirt " << info->mCurrentImage->mMaxVirtualSize + << " maxdisc " << (S32)info->mCurrentImage->getMaxDiscardLevel() + << llendl; + } + } +} + + +BOOL LLWorldMap::extendAABB(U32 min_x, U32 min_y, U32 max_x, U32 max_y) +{ + BOOL rv = FALSE; + if (min_x < mMinX) + { + rv = TRUE; + mMinX = min_x; + } + if (min_y < mMinY) + { + rv = TRUE; + mMinY = min_y; + } + if (max_x > mMaxX) + { + rv = TRUE; + mMaxX = max_x; + } + if (max_y > mMaxY) + { + rv = TRUE; + mMaxY = max_y; + } + lldebugs << "World map aabb: (" << mMinX << ", " << mMinY << "), (" + << mMaxX << ", " << mMaxY << ")" << llendl; + return rv; +} + + +U32 LLWorldMap::getWorldWidth() const +{ + return mMaxX - mMinX; +} + + +U32 LLWorldMap::getWorldHeight() const +{ + return mMaxY - mMinY; +} + +BOOL LLWorldMap::coveredByTelehub(LLSimInfo* infop) +{ + /*if (!mTelehubCoverageMap) + { + return FALSE; + } + U32 x_pos, y_pos; + from_region_handle(infop->mHandle, &x_pos, &y_pos); + x_pos /= REGION_WIDTH_UNITS; + y_pos /= REGION_WIDTH_UNITS; + + S32 index = x_pos - (mMinX / REGION_WIDTH_UNITS - 1) + (mNeighborMapWidth * (y_pos - (mMinY / REGION_WIDTH_UNITS - 1))); + return mTelehubCoverageMap[index] != 0; */ + return FALSE; +} + +void LLWorldMap::updateTelehubCoverage() +{ + /*S32 neighbor_width = getWorldWidth() / REGION_WIDTH_UNITS + 2; + S32 neighbor_height = getWorldHeight() / REGION_WIDTH_UNITS + 2; + if (neighbor_width > mNeighborMapWidth || neighbor_height > mNeighborMapHeight) + { + mNeighborMapWidth = neighbor_width; + mNeighborMapHeight = neighbor_height; + delete mNeighborMap; + delete mTelehubCoverageMap; + + mNeighborMap = new U8[mNeighborMapWidth * mNeighborMapHeight]; + mTelehubCoverageMap = new U8[mNeighborMapWidth * mNeighborMapHeight]; + } + + memset(mNeighborMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8)); + memset(mTelehubCoverageMap, 0, mNeighborMapWidth * mNeighborMapHeight * sizeof(U8)); + + // leave 1 sim border + S32 min_x = (mMinX / REGION_WIDTH_UNITS) - 1; + S32 min_y = (mMinY / REGION_WIDTH_UNITS) - 1; + + std::map<U64, LLSimInfo*>::const_iterator it; + for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + U64 handle = (*it).first; + //LLSimInfo* info = (*it).second; + + U32 x_pos, y_pos; + from_region_handle(handle, &x_pos, &y_pos); + x_pos /= REGION_WIDTH_UNITS; + y_pos /= REGION_WIDTH_UNITS; + x_pos -= min_x; + y_pos -= min_y; + + S32 index = x_pos + (mNeighborMapWidth * y_pos); + mNeighborMap[index - 1]++; + mNeighborMap[index + 1]++; + mNeighborMap[index - mNeighborMapWidth]++; + mNeighborMap[index + mNeighborMapWidth]++; + } + + for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + U64 handle = (*it).first; + LLSimInfo* info = (*it).second; + + U32 x_pos, y_pos; + from_region_handle(handle, &x_pos, &y_pos); + x_pos /= REGION_WIDTH_UNITS; + y_pos /= REGION_WIDTH_UNITS; + x_pos -= min_x; + y_pos -= min_y; + + S32 index = x_pos + (mNeighborMapWidth * y_pos); + + if (!info->mTelehubName.empty() && mNeighborMap[index]) + { + S32 x_start = llmax(0, S32(x_pos - 5)); + S32 x_span = llmin(mNeighborMapWidth - 1, (S32)(x_pos + 5)) - x_start + 1; + S32 y_start = llmax(0, (S32)y_pos - 5); + S32 y_end = llmin(mNeighborMapHeight - 1, (S32)(y_pos + 5)); + for (S32 y_index = y_start; y_index <= y_end; y_index++) + { + memset(&mTelehubCoverageMap[x_start + y_index * mNeighborMapWidth], 0xff, sizeof(U8) * x_span); + } + } + } + + for (it = mSimInfoMap.begin(); it != mSimInfoMap.end(); ++it) + { + U64 handle = (*it).first; + //LLSimInfo* info = (*it).second; + + U32 x_pos, y_pos; + from_region_handle(handle, &x_pos, &y_pos); + x_pos /= REGION_WIDTH_UNITS; + y_pos /= REGION_WIDTH_UNITS; + + S32 index = x_pos - min_x + (mNeighborMapWidth * (y_pos - min_y)); + mTelehubCoverageMap[index] *= mNeighborMap[index]; + }*/ +} |