void LLWorldMap::reloadItems(bool force) { //LL_INFOS("World Map") << "LLWorldMap::reloadItems()" << LL_ENDL; if (clearItems(force)) { LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_TELEHUB); LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_PG_EVENT); LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_MATURE_EVENT); LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_ADULT_EVENT); LLWorldMapMessage::getInstance()->sendItemRequest(MAP_ITEM_LAND_FOR_SALE); } if(!useWebMapTiles()) { if(!mMapLoaded || force) sendMapLayerRequest(); } }
// public static void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) { U32 agent_flags; msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); if ((S32)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; #ifdef IMMEDIATE_IMAGE_LOAD bool use_web_map_tiles = useWebMapTiles(); #endif BOOL adjust = FALSE; for (S32 block=0; block<num_blocks; ++block) { U16 x_regions; U16 y_regions; std::string name; U8 accesscode; 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, name, block); msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, 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; U64 handle = to_region_handle(x_meters, y_meters); if (accesscode == 255) { // This region doesn't exist if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) { // We were tracking this location, but it doesn't exist LLWorldMap::getInstance()->mInvalidLocation = TRUE; } found_null_sim = true; } else { adjust = LLWorldMap::getInstance()->extendAABB(x_meters, y_meters, x_meters+REGION_WIDTH_UNITS, y_meters+REGION_WIDTH_UNITS) || adjust; // llinfos << "Map sim " << name << " image layer " << agent_flags << " ID " << image_id.getString() << llendl; LLSimInfo* siminfo = new LLSimInfo(); sim_info_map_t::iterator iter = LLWorldMap::getInstance()->mSimInfoMap.find(handle); if (iter != LLWorldMap::getInstance()->mSimInfoMap.end()) { LLSimInfo* oldinfo = iter->second; for (S32 image=0; image<MAP_SIM_IMAGE_TYPES; ++image) { siminfo->mMapImageID[image] = oldinfo->mMapImageID[image]; } delete oldinfo; } LLWorldMap::getInstance()->mSimInfoMap[handle] = siminfo; siminfo->mHandle = handle; siminfo->msizeX = 256; siminfo->msizeY = 256; siminfo->mName.assign( name ); siminfo->mAccess = accesscode; siminfo->mRegionFlags = region_flags; siminfo->mWaterHeight = (F32) water_height; siminfo->mMapImageID[agent_flags] = image_id; #ifdef IMMEDIATE_IMAGE_LOAD if (use_web_map_tiles) { siminfo->mCurrentImage = loadObjectsTile((U32)x_regions, (U32)y_regions); } else { siminfo->mCurrentImage = gImageList.getImage(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); } gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); #endif if (siminfo->mMapImageID[2].notNull()) { #ifdef IMMEDIATE_IMAGE_LOAD siminfo->mOverlayImage = gImageList.getImage(siminfo->mMapImageID[2], MIPMAP_TRUE, FALSE); #endif } else { siminfo->mOverlayImage = NULL; } if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) { if (siminfo->mAccess == SIM_ACCESS_DOWN) { // We were tracking this location, but it doesn't exist LLWorldMap::getInstance()->mInvalidLocation = true; } else { // We were tracking this location, and it does exist bool is_tracking_dbl = LLWorldMap::getInstance()->mIsTrackingDoubleClick == TRUE; gFloaterWorldMap->trackLocation(LLWorldMap::getInstance()->mUnknownLocation); if (is_tracking_dbl) { LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); gAgent.teleportViaLocation( pos_global ); } } } } if(LLWorldMap::getInstance()->mSLURLCallback != NULL) { // Server returns definitive capitalization, SLURL might not have that. if ((LLStringUtil::compareInsensitive(LLWorldMap::getInstance()->mSLURLRegionName, name)==0) || (LLWorldMap::getInstance()->mSLURLRegionHandle == handle)) { url_callback_t callback = LLWorldMap::getInstance()->mSLURLCallback; LLWorldMap::getInstance()->mSLURLCallback = NULL; LLWorldMap::getInstance()->mSLURLRegionName.clear(); LLWorldMap::getInstance()->mSLURLRegionHandle = 0; callback(handle, LLWorldMap::getInstance()->mSLURL, image_id, LLWorldMap::getInstance()->mSLURLTeleport); } } if(gAgent.mLureShow) { if((x_regions == gAgent.mLureGlobalX) && (y_regions == gAgent.mLureGlobalY)) { gAgent.onFoundLureDestination(); } } } if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); gFloaterWorldMap->updateSims(found_null_sim); }
// public static void LLWorldMap::processMapBlockReply(LLMessageSystem* msg, void**) { U32 agent_flags; msg->getU32Fast(_PREHASH_AgentData, _PREHASH_Flags, agent_flags); if ((S32)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; #ifdef IMMEDIATE_IMAGE_LOAD bool use_web_map_tiles = useWebMapTiles(); #endif BOOL adjust = FALSE; for (S32 block=0; block<num_blocks; ++block) { U16 x_regions; U16 y_regions; U16 x_size = 256; U16 y_size = 256; std::string name; U8 accesscode; 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, name, block); msg->getU8Fast(_PREHASH_Data, _PREHASH_Access, accesscode, 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); if(msg->getNumberOfBlocksFast(_PREHASH_Size) > 0) { msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeX, x_size, block); msg->getU16Fast(_PREHASH_Size, _PREHASH_SizeY, y_size, block); } if(x_size == 0 || (x_size % 16) != 0|| (y_size % 16) != 0) { x_size = 256; y_size = 256; } U32 x_meters = x_regions * REGION_WIDTH_UNITS; U32 y_meters = y_regions * REGION_WIDTH_UNITS; U64 handle = to_region_handle(x_meters, y_meters); if (accesscode == 255) { // This region doesn't exist if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) { // We were tracking this location, but it doesn't exist LLWorldMap::getInstance()->mInvalidLocation = TRUE; } found_null_sim = true; } else { adjust = LLWorldMap::getInstance()->extendAABB(x_meters, y_meters, x_meters+REGION_WIDTH_UNITS, y_meters+REGION_WIDTH_UNITS) || adjust; //LL_INFOS("World Map") << "Map sim : " << name << ", ID : " << image_id.getString() << LL_ENDL; // Insert the region in the region map of the world map // Loading the LLSimInfo object with what we got and insert it in the map LLSimInfo* siminfo = LLWorldMap::getInstance()->simInfoFromHandle(handle); if (siminfo == NULL) { siminfo = LLWorldMap::getInstance()->createSimInfoFromHandle(handle); } siminfo->setName( name ); siminfo->setAccess( accesscode ); siminfo->setRegionFlags( region_flags ); siminfo->setWaterHeight((F32) water_height); siminfo->setMapImageID( image_id, agent_flags ); siminfo->setSize( x_size, y_size ); #ifdef IMMEDIATE_IMAGE_LOAD if (use_web_map_tiles) { siminfo->mCurrentImage = loadObjectsTile((U32)x_regions, (U32)y_regions); } else { siminfo->mCurrentImage = LLViewerTextureManager::getFetchedTexture(siminfo->mMapImageID[LLWorldMap::getInstance()->mCurrentMap], MIPMAP_TRUE, FALSE); } gGL.getTexUnit(0)->bind(siminfo->mCurrentImage.get()); siminfo->mCurrentImage->setAddressMode(LLTexUnit::TAM_CLAMP); #endif if (siminfo->mMapImageID[2].notNull()) { #ifdef IMMEDIATE_IMAGE_LOAD siminfo->mOverlayImage = LLViewerTextureManager::getFetchedTextureURL(siminfo->mMapImageID[2]); #endif } else { siminfo->mOverlayImage = NULL; } if (LLWorldMap::getInstance()->mIsTrackingUnknownLocation && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] >= x_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[0] < x_meters + 256 && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] >= y_meters && LLWorldMap::getInstance()->mUnknownLocation.mdV[1] < y_meters + 256) { if (siminfo->isDown()) { // We were tracking this location, but it doesn't exist LLWorldMap::getInstance()->mInvalidLocation = true; } else { // We were tracking this location, and it does exist bool is_tracking_dbl = LLWorldMap::getInstance()->mIsTrackingDoubleClick == TRUE; gFloaterWorldMap->trackLocation(LLWorldMap::getInstance()->mUnknownLocation); if (is_tracking_dbl) { LLVector3d pos_global = LLTracker::getTrackedPositionGlobal(); gAgent.teleportViaLocation( pos_global ); } } } } if(LLWorldMap::getInstance()->mSLURLCallback != NULL) { // Server returns definitive capitalization, SLURL might not have that. if ((LLStringUtil::compareInsensitive(LLWorldMap::getInstance()->mSLURLRegionName, name)==0) || (LLWorldMap::getInstance()->mSLURLRegionHandle == handle)) { url_callback_t callback = LLWorldMap::getInstance()->mSLURLCallback; LLWorldMap::getInstance()->mSLURLCallback = NULL; LLWorldMap::getInstance()->mSLURLRegionName.clear(); LLWorldMap::getInstance()->mSLURLRegionHandle = 0; callback(handle, LLWorldMap::getInstance()->mSLURL, image_id, LLWorldMap::getInstance()->mSLURLTeleport); } } if( gAgent.mPendingLure && (U16)(gAgent.mPendingLure->mPosGlobal.mdV[0] / REGION_WIDTH_UNITS) == x_regions && (U16)(gAgent.mPendingLure->mPosGlobal.mdV[1] / REGION_WIDTH_UNITS) == y_regions ) { gAgent.onFoundLureDestination(); } } if(adjust) gFloaterWorldMap->adjustZoomSliderBounds(); gFloaterWorldMap->updateSims(found_null_sim); }
// Load all regions in a given rectangle (in region grid coordinates, i.e. world / 256 meters) void LLWorldMap::updateRegions(S32 x0, S32 y0, S32 x1, S32 y1) { // Convert those boundaries to the corresponding (MAP_BLOCK_SIZE x MAP_BLOCK_SIZE) block coordinates U32 global_x0 = x0 / MAP_BLOCK_SIZE; U32 global_x1 = x1 / MAP_BLOCK_SIZE; U32 global_y0 = y0 / MAP_BLOCK_SIZE; U32 global_y1 = y1 / MAP_BLOCK_SIZE; //Singu note: There's a bunch of extra logic here, as opensim grids support sim coordinates that extend beyond the range // used on the official grid. We basically just extend what LL had here by nesting the mMapBlockLoaded array in a 'dynamic' grid, // essentially making that array a 'block' itself. An std::map was used to conserve memory, as we selectively only allocate desired // blocks, and although lookups aren't blazingly fast with that container, it isn't likeley to accumulate very many entries. //MapBlockRequest uses U16 for coordinate components. // In order not to exceed U16_MAX values, MAP_BLOCK_RES*MAP_BLOCK_SIZE*(i or j) can't exceed U16_MAX(65535) U32 max_range = (U16_MAX+1)/MAP_BLOCK_RES/MAP_BLOCK_SIZE - 1; //Desired coordinate ranges in our 'dynamic' grid of 512x512 grids of 4x4 sim blocks. U32 map_block_x0 = global_x0 / MAP_BLOCK_RES; U32 map_block_x1 = llmin(global_x1 / MAP_BLOCK_RES, max_range); U32 map_block_y0 = global_y0 / MAP_BLOCK_RES; U32 map_block_y1 = llmin(global_y1 / MAP_BLOCK_RES, max_range); const bool layer_start = useWebMapTiles() ? SIM_LAYER_OVERLAY : SIM_LAYER_BEGIN; for (U32 i = map_block_x0; i <= map_block_x1; ++i) { for (U32 j = map_block_y0; j <= map_block_y1; ++j) { //Desired coordinate ranges in our 512x512 grids of 4x4 sim blocks. x0 = global_x0 - i * MAP_BLOCK_RES; x1 = llmin(global_x1 - i * (U32)MAP_BLOCK_RES, (U32)MAP_BLOCK_RES-1); y0 = global_y0 - j * MAP_BLOCK_RES; y1 = llmin(global_y1 - j * (U32)MAP_BLOCK_RES, (U32)MAP_BLOCK_RES-1); for(U32 layer = layer_start;layer<SIM_LAYER_COUNT;++layer) { std::vector<bool> &block = mMapBlockMap[layer][(i << 16) | j]; if(block.empty()) { //New block. Allocate the array and set all entries to false. (seen as mMapBlockLoaded in v3) block.resize(MAP_BLOCK_RES*MAP_BLOCK_RES,false); } // Load the region info those blocks for (S32 block_x = llmax(x0, 0); block_x <= llmin(x1, MAP_BLOCK_RES-1); ++block_x) { for (S32 block_y = llmax(y0, 0); block_y <= llmin(y1, MAP_BLOCK_RES-1); ++block_y) { S32 offset = block_x | (block_y * MAP_BLOCK_RES); // if(!mMapBlockLoaded[LLWorldMap::getInstance()->mCurrentMap][offset]) if (!block[offset]) { U16 min_x = (block_x + i * MAP_BLOCK_RES) * MAP_BLOCK_SIZE; U16 max_x = min_x + MAP_BLOCK_SIZE - 1; U16 min_y = (block_y + j * MAP_BLOCK_RES) * MAP_BLOCK_SIZE; U32 max_y = min_y + MAP_BLOCK_SIZE - 1; //LL_INFOS("World Map") << "Loading Block (" << block_x << "," << block_y << ")" << LL_ENDL; LLWorldMapMessage::getInstance()->sendMapBlockRequest(min_x, min_y, max_x, max_y, false, layerToFlags((sim_layer_type)layer)); block[offset] = true; } } } } } } }