std::forward_list<TileID> tileCover(int8_t z, const mbgl::box &bounds, int8_t actualZ) { int32_t tiles = 1 << z; std::forward_list<mbgl::TileID> t; auto scanLine = [&](int32_t x0, int32_t x1, int32_t y) { int32_t x; if (y >= 0 && y <= tiles) { for (x = x0; x < x1; x++) { t.emplace_front(actualZ, x, y, z); } } }; mbgl::vec2<double> tl = { bounds.tl.column, bounds.tl.row }; mbgl::vec2<double> tr = { bounds.tr.column, bounds.tr.row }; mbgl::vec2<double> br = { bounds.br.column, bounds.br.row }; mbgl::vec2<double> bl = { bounds.bl.column, bounds.bl.row }; // Divide the screen up in two triangles and scan each of them: // \---+ // | \ | // +---\. scanTriangle(tl, tr, br, 0, tiles, scanLine); scanTriangle(br, bl, tl, 0, tiles, scanLine); t.sort(); t.unique(); return t; }
void View::updateTiles() { m_visibleTiles.clear(); // Bounds of view trapezoid in world space (i.e. view frustum projected onto z = 0 plane) glm::vec2 viewBL = { 0.f, m_vpHeight }; // bottom left glm::vec2 viewBR = { m_vpWidth, m_vpHeight }; // bottom right glm::vec2 viewTR = { m_vpWidth, 0.f }; // top right glm::vec2 viewTL = { 0.f, 0.f }; // top left screenToGroundPlane(viewBL.x, viewBL.y); screenToGroundPlane(viewBR.x, viewBR.y); screenToGroundPlane(viewTR.x, viewTR.y); screenToGroundPlane(viewTL.x, viewTL.y); // Transformation from world space to tile space double hc = MapProjection::HALF_CIRCUMFERENCE; double invTileSize = double(1 << int(m_zoom)) / (hc * 2); glm::dvec2 tileSpaceOrigin(-hc, hc); glm::dvec2 tileSpaceAxes(invTileSize, -invTileSize); // Bounds of view trapezoid in tile space glm::dvec2 a = (glm::dvec2(viewBL.x + m_pos.x, viewBL.y + m_pos.y) - tileSpaceOrigin) * tileSpaceAxes; glm::dvec2 b = (glm::dvec2(viewBR.x + m_pos.x, viewBR.y + m_pos.y) - tileSpaceOrigin) * tileSpaceAxes; glm::dvec2 c = (glm::dvec2(viewTR.x + m_pos.x, viewTR.y + m_pos.y) - tileSpaceOrigin) * tileSpaceAxes; glm::dvec2 d = (glm::dvec2(viewTL.x + m_pos.x, viewTL.y + m_pos.y) - tileSpaceOrigin) * tileSpaceAxes; // Rasterize view trapezoid into tiles int maxTileIndex = 1 << int(m_zoom); scanTriangle(a, b, c, 0, maxTileIndex, int(m_zoom), m_visibleTiles); scanTriangle(c, d, a, 0, maxTileIndex, int(m_zoom), m_visibleTiles); }
void ScanBox::scan( double x, double y, double scale, int zoom, float box[] ) { m_nZoom = zoom; // this does not modify 'box' parameter box = transScale(x, y, scale, zoom, box); // clip result to min/max as steep angles // cause overshooting in x direction. float max = FLT_MIN; float min = FLT_MAX; for (int i = 0; i < 8; i += 2) { float xx = box[i]; if (xx > max) max = xx; if (xx < min) min = xx; } max = (float) ceil(max); min = (float) floor(min); if (min == max) max++; xmin = (int) min; xmax = (int) max; // top-left -> top-right ab.set(box[0], box[1], box[2], box[3]); // top-right -> bottom-right bc.set(box[2], box[3], box[4], box[5]); // bottom-right -> bottom-left ca.set(box[4], box[5], box[0], box[1]); scanTriangle(); // top-left -> bottom-right ab.set(box[0], box[1], box[4], box[5]); // bottom-right -> bottom-left bc.set(box[4], box[5], box[6], box[7]); // bottom-left -> top-left ca.set(box[6], box[7], box[0], box[1]); scanTriangle(); }
void displayPerspFaceAdd(PixelImage* image, ObjScene* scene) { if (image == 0 || scene == 0 || scene->object == 0) return; image->clear(scene->getC1()); Matrix4 tr = scene->modelTr; tr *= viewTrans(scene->camera); Matrix4 persptr = perspTrans(scene->camera, image->getWidth(), image->getHeight()); Vector3 v0, v1, v2; double ne = -scene->camera.near; for (int f=0 ; f<scene->object->getFaceNum() ; ++f) { v0 = scene->object->getTriangle0(f); v1 = scene->object->getTriangle1(f); v2 = scene->object->getTriangle2(f); v0 *= tr; v1 *= tr; v2 *= tr; if ((v0.z <= ne) && (v1.z <= ne) && (v2.z <= ne)) { v0 *= persptr; v1 *= persptr; v2 *= persptr; scanTriangle(image, v0, v1, v2, scene->getC2()); /*if (scene->renderContour()) { DoubleColor cx = {1, 0, 0, 1}; Vector2 aaa(v0.x+xm/2, ym/2-v0.y); Vector2 bbb(v1.x+xm/2, ym/2-v1.y); Vector2 ccc(v2.x+xm/2, ym/2-v2.y); d2d::Line lx; lx.beg = bbb; lx.end = ccc; lx.col = cx; d2d::Line ly; ly.beg = aaa; ly.end = bbb; ly.col = cx; d2d::Line lz; lz.beg = aaa; lz.end = ccc; lz.col = cx; d2d::lineDotsAdapt(image, &lx, 1.0); d2d::lineDotsAdapt(image, &ly, 1.0); d2d::lineDotsAdapt(image, &lz, 1.0); } */ } } if (scene->renderGizmo()) { displayGizmo(image, tr); } }