void pixelBox(const PixelBox& box, isab::MapPlotter* plotter) { std::vector<MC2Point> points; points.push_back(box.getTopLeft()); points.push_back(box.getTopRight()); points.push_back(box.getBottomRight()); points.push_back(box.getBottomLeft()); points.push_back(box.getTopLeft()); plotter->setPenColor(255, 0, 0); plotter->setLineWidth(3); plotter->drawPolyLine(points.begin(), points.end()); }
void ExternalRenderer::drawBitmapBlock(TriStorageBlock& block, unsigned int pass, vec4x* triangleData, const MC2BoundingBox& box, OverlapDetector<MC2BoundingBox>& detector, TileMapContainer& tileMapCont, TileMapFormatDesc& formatDesc, bool skipOutlines) { if(pass == 0) { return; } for(std::vector<TriSection>::iterator sectIt = block.primitives.begin(); sectIt != block.primitives.end(); sectIt++){ TriSection& section = *sectIt; TilePrimitiveFeature& feat = *section.src; const TileFeatureArg* arg = feat.getArg( TileArgNames::coord ); const CoordArg* coordArg = static_cast<const CoordArg*>( arg ); MC2Coordinate coord = coordArg->getCoord(); if( box.contains( coord ) ) { const StringArg* bitMapName = static_cast<const StringArg*> ( feat.getArg(TileArgNames::image_name) ); if ( bitMapName == NULL ) { continue; } TextureBlock* texture = static_cast<TextureBlock*>( m_impl->mapHandler->getOrRequestBitMap( bitMapName->getValue() ) ); if ( texture != NULL ) { MC2Point position; transform(position, coord); /** * We subtract the anchor position, to position the texture * on the anchor instead of the top left corner. */ PixelBox overlapBox = texture->boundingBox; MC2Point topLeft = overlapBox.getTopLeft(); MC2Point bottomRight = overlapBox.getBottomRight(); overlapBox.set( topLeft, bottomRight ); overlapBox.move( MC2Point( position.getX(), position.getY() ) ); bool notOverlapping = true; notOverlapping = detector.addIfNotOverlapping( overlapBox ); if (notOverlapping) { drawSprite( texture, position, 0.0f, texture->centerOffset, 1.0f, 1.0f); feat.setDrawn( true ); } } } } }
void StackedSet::update() { clear(); // Since overlap should be calculated using the precision scaled dimensions // we need to precision scale the bounding box for the screen. PixelBox screenBox = m_projection.getPixelBoundingBox(); MC2Point topLeft(screenBox.getTopLeft().getX() * SCALING_CONSTANT, screenBox.getTopLeft().getY() * SCALING_CONSTANT); MC2Point bottomRight(screenBox.getBottomRight().getX() * SCALING_CONSTANT, screenBox.getBottomRight().getY() * SCALING_CONSTANT); PixelBox screenBoxScaled(topLeft, bottomRight); for( OverlayViewLayerInterface::LayerMap::iterator itr = m_layerInterface.begin(); itr != m_layerInterface.end(); itr++) { Layer& l = *itr->second; if(!l.getVisible()) { // We don't need to detect any overlaps with invisible layers. continue; } for(Layer::const_iterator itemItr = l.items_begin(); itemItr != l.items_end(); itemItr++) { OverlayItemInternal* item = *itemItr; initItem(item); if (!screenBoxScaled.overlaps(item->getPrecisionScaledPixelBox())) { // The item lies outside the screen, do NOT add it to the stacks. continue; } addToStackSet(item); } } #ifdef USE_SMOOTHING // Smooth the positions of the stacks to represent the average // of the contained items' positions. smoothPositions(); #endif #ifdef USE_SMOOTHING #ifdef USE_ITERATIVE_SMOOTHING // Since we have changed the position of the stacks, we run another // pass of overlap detection. unsigned int prevSize = 0; unsigned int iterationCap = ITERATIVE_SMOOTHING_CAP; // If the number of stacks has not changed, no stacks overlapped // so the iteration should terminate. while (prevSize != m_stacks.size() && iterationCap > 0) { StackVec tempVec = m_stacks; prevSize = m_stacks.size(); clear(); for(StackVec::iterator itr = tempVec.begin(); itr != tempVec.end(); itr++) { addToStackSet(*itr); } smoothPositions(); --iterationCap; } #endif #endif OverlayItemInternal* currClosest = NULL; if ( m_stacks.size() != 0 && m_automaticHighlightMode){ // Find out which item is closest to the center of the screen MC2Point screenCenter; m_projection.transform(screenCenter, m_projection.getCenter()); WFAPI::wf_float64 closestDistSq = 0; currClosest = *m_stacks.begin(); closestDistSq = getSquareScreenDistance(screenCenter, currClosest); for(StackedSet::StackVec::const_iterator itr = m_stacks.begin(); itr != m_stacks.end(); itr++) { WFAPI::wf_float64 currDistSq = getSquareScreenDistance(screenCenter, *itr); if (currDistSq < closestDistSq){ currClosest = *itr; closestDistSq = currDistSq; } } // If the currently closest item is further away than RADIUS pixels, // disregard it. const unsigned int RADIUS = 75; if (closestDistSq > RADIUS * RADIUS){ currClosest = NULL; closestDistSq = 0; } } updateClosest(currClosest); if (m_closest.item && automaticHighlightEnabled()){ m_closest.item->m_isHighlighted = true; // Since we don't care pixel scale the item is on, we // use 0 as the current pixel scale. const WFAPI::OverlayItemVisualSpec* highlighted = OverlayItemUtil::getCurrentVisualSpec(m_closest.item, 0); if(highlighted) { updateItemPixelBox(m_closest.item, highlighted, m_closest.item->m_adjustedPosition); } } }