diff --git a/Makefile b/Makefile index 5eae658..26c5a4b 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # sure that the variable PREFIX is defined, e.g. make PREFIX=/usr/local # -CFLAGS=-O3 -Wno-write-strings +CFLAGS=-O2 -Wno-write-strings LIBS=-lm -lSDL2 -lSDL2_ttf -lSDL2_gfx CC=g++ diff --git a/Map.cpp b/Map.cpp index 2baa43a..a710ac3 100644 --- a/Map.cpp +++ b/Map.cpp @@ -2,23 +2,26 @@ #include #include -bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) { - // printf("Inserting %d point poly\n", polygon->numPoints); +bool Map::QTInsert(QuadTree *tree, Line *line, int depth) { + // printf("Inserting %d point poly\n", line->numPoints); - //temp maxdepth for debugging - if(depth > 10) { - return false; - } - if (!(polygon->lat_min >= tree->lat_min && - polygon->lat_max <= tree->lat_max && - polygon->lon_min >= tree->lon_min && - polygon->lon_max <= tree->lon_max)) { - // printf("doesnt fit: %f > %f, %f < %f, %f < %f,%f > %f \n",polygon->lat_min, tree->lat_min, polygon->lat_max, tree->lat_max, polygon->lon_min, tree->lon_min, polygon->lon_max,tree->lon_max); + if (!(line->lat_min >= tree->lat_min && + line->lat_max <= tree->lat_max && + line->lon_min >= tree->lon_min && + line->lon_max <= tree->lon_max)) { + // printf("doesnt fit: %f > %f, %f < %f, %f < %f,%f > %f \n",line->lat_min, tree->lat_min, line->lat_max, tree->lat_max, line->lon_min, tree->lon_min, line->lon_max,tree->lon_max); return false; } + + // //temp maxdepth for debugging + // if(depth > 20) { + // tree->lines.push_back(*line); + // return true; + // } + if (tree->nw == NULL) { tree->nw = new QuadTree; @@ -28,7 +31,7 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) { tree->nw->lon_max = tree->lon_min + 0.5 * (tree->lon_max - tree->lon_min); } - if (QTInsert(tree->nw,polygon, depth++)){ + if (QTInsert(tree->nw, line, depth++)){ return true; } @@ -41,7 +44,7 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) { tree->sw->lon_max = tree->lon_max; } - if (QTInsert(tree->sw,polygon, depth++)){ + if (QTInsert(tree->sw, line, depth++)){ return true; } @@ -54,7 +57,7 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) { tree->ne->lon_max = tree->lon_min + 0.5 * (tree->lon_max - tree->lon_min); } - if (QTInsert(tree->ne,polygon, depth++)){ + if (QTInsert(tree->ne, line, depth++)){ return true; } @@ -67,52 +70,50 @@ bool Map::QTInsert(QuadTree *tree, Polygon *polygon, int depth) { tree->se->lon_max = tree->lon_max; } - if (QTInsert(tree->se,polygon, depth++)){ + if (QTInsert(tree->se, line, depth++)){ return true; } - tree->polygons.push_back(*polygon); - + tree->lines.push_back(*line); return true; } -std::vector Map::getPolysRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { - std::vector retPolys; +std::vector Map::getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { + std::vector retLines; if(tree == NULL) { - return retPolys; + return retLines; } if (tree->lat_min > screen_lat_max || screen_lat_min > tree->lat_max) { - return retPolys; + return retLines; } if (tree->lon_min > screen_lon_max || screen_lon_min > tree->lon_max) { - return retPolys; + return retLines; } + std::vector ret; + ret = getLinesRecursive(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + retLines.insert(retLines.end(), ret.begin(), ret.end()); - std::vector ret; - ret = getPolysRecursive(tree->nw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); - retPolys.insert(retPolys.end(), ret.begin(), ret.end()); + ret = getLinesRecursive(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + retLines.insert(retLines.end(), ret.begin(), ret.end()); - ret = getPolysRecursive(tree->sw, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); - retPolys.insert(retPolys.end(), ret.begin(), ret.end()); + ret = getLinesRecursive(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + retLines.insert(retLines.end(), ret.begin(), ret.end()); - ret = getPolysRecursive(tree->ne, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); - retPolys.insert(retPolys.end(), ret.begin(), ret.end()); + ret = getLinesRecursive(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + retLines.insert(retLines.end(), ret.begin(), ret.end()); - ret = getPolysRecursive(tree->se, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); - retPolys.insert(retPolys.end(), ret.begin(), ret.end()); + retLines.insert(retLines.end(), tree->lines.begin(), tree->lines.end()); - retPolys.insert(retPolys.end(), tree->polygons.begin(), tree->polygons.end()); - - return retPolys; + return retLines; } -std::vector Map::getPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { - return getPolysRecursive(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); +std::vector Map::getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { + return getLinesRecursive(&root, screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); }; Map::Map() { @@ -156,38 +157,19 @@ Map::Map() { } } - Polygon *currentPolygon = new Polygon; - for(int i = 0; i < mapPoints_count; i+=2) { + Point currentPoint; + Point nextPoint; - if(mapPoints[i] == 0) { - QTInsert(&root, currentPolygon, 0); - currentPolygon = new Polygon; - continue; - } - currentPolygon->numPoints++; + for(int i = 0; i < mapPoints_count - 2; i+=2) { + if(mapPoints[i] == 0) + continue; + currentPoint.lon = mapPoints[i]; + currentPoint.lat = mapPoints[i + 1]; - Point *currentPoint = new Point; + nextPoint.lon = mapPoints[i + 2]; + nextPoint.lat = mapPoints[i + 3]; - if(mapPoints[i] < currentPolygon->lon_min) { - currentPolygon->lon_min = mapPoints[i]; - } - - if(mapPoints[i] > currentPolygon->lon_max) { - currentPolygon->lon_max = mapPoints[i]; - } - - if(mapPoints[i+1] < currentPolygon->lat_min) { - currentPolygon->lat_min = mapPoints[i+1]; - } - - if(mapPoints[i+1] > currentPolygon->lat_max) { - currentPolygon->lat_max = mapPoints[i+1]; - } - - currentPoint->lon = mapPoints[i]; - currentPoint->lat = mapPoints[i+1]; - - currentPolygon->points.push_back(*currentPoint); + QTInsert(&root, new Line(currentPoint, nextPoint), 0); } } diff --git a/Map.h b/Map.h index 6c42333..a989754 100644 --- a/Map.h +++ b/Map.h @@ -8,23 +8,25 @@ typedef struct Point{ float lon; } Point; -typedef struct Polygon{ +typedef struct Line{ float lat_min; float lat_max; float lon_min; float lon_max; - std::vector points; - int numPoints; + Point start; + Point end; - Polygon() { - lat_min = 180.0f; - lon_min = 180.0f; - lat_max = -180.0f; - lon_max = -180.0f; - numPoints = 0; + Line(Point start, Point end) { + this->start = start; + this->end = end; + + lat_min = std::min(start.lat,end.lat); + lat_max = std::max(start.lat,end.lat); + lon_min = std::min(start.lon,end.lon); + lon_max = std::max(start.lon,end.lon); } -} Polygon; +} Line; typedef struct QuadTree{ float lat_min; @@ -32,7 +34,7 @@ typedef struct QuadTree{ float lon_min; float lon_max; - std::vector polygons; + std::vector lines; struct QuadTree *nw; struct QuadTree *sw; @@ -75,9 +77,9 @@ class Map { public: QuadTree root; - bool QTInsert(QuadTree *tree, Polygon *polygon, int depth); - std::vector getPolysRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); - std::vector getPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); + bool QTInsert(QuadTree *tree, Line *line, int depth); + std::vector getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); + std::vector getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); Map(); diff --git a/View.cpp b/View.cpp index d158029..754fa53 100644 --- a/View.cpp +++ b/View.cpp @@ -10,6 +10,7 @@ #include #include +#include static uint64_t now() { return std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count(); @@ -249,7 +250,7 @@ void View::SDL_init() { } window = SDL_CreateWindow("viz1090", SDL_WINDOWPOS_CENTERED_DISPLAY(screen_index), SDL_WINDOWPOS_CENTERED_DISPLAY(screen_index), screen_width, screen_height, flags); - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); mapTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, @@ -298,7 +299,7 @@ void View::font_init() { style.selectedColor = pink; style.planeColor = greenblue; style.planeGoneColor = grey; - style.mapInnerColor = mediumblue; + style.mapInnerColor = darkblue; style.mapOuterColor = darkblue; style.scaleBarColor = lightGrey; style.buttonColor = lightblue; @@ -637,69 +638,43 @@ void View::drawScaleBars() lineRGBA(renderer,10,10+5*screen_uiscale,10+scaleBarDist,10+5*screen_uiscale, style.scaleBarColor.r, style.scaleBarColor.g, style. scaleBarColor.b, 255); } -void View::drawPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max) { - std::vector polyList = map.getPolys(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); +void View::drawLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, int bailTime) { + std::vector lineList = map.getLines(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); - std::vector::iterator currentPolygon; + std::vector::iterator currentLine; - for (currentPolygon = polyList.begin(); currentPolygon != polyList.end(); ++currentPolygon) { + for (currentLine = lineList.begin(); currentLine != lineList.end(); ++currentLine) { int x1,y1,x2,y2; float dx,dy; - - std::vector::iterator currentPoint; - std::vector::iterator prevPoint = currentPolygon->points.begin(); - for (currentPoint = std::next(currentPolygon->points.begin()); currentPoint != currentPolygon->points.end(); ++currentPoint, ++prevPoint) { - - pxFromLonLat(&dx, &dy, prevPoint->lon, prevPoint->lat); - screenCoords(&x1, &y1, dx, dy); - - float d1 = dx* dx + dy * dy; - - pxFromLonLat(&dx, &dy, currentPoint->lon, currentPoint->lat); - screenCoords(&x2, &y2, dx, dy); - - if(outOfBounds(x1,y1) && outOfBounds(x2,y2)) { - continue; + if(bailTime) { + if (elapsed(drawStartTime) > bailTime) { + return; } + } + + pxFromLonLat(&dx, &dy, currentLine->start.lon, currentLine->start.lat); + screenCoords(&x1, &y1, dx, dy); - float d2 = dx* dx + dy * dy; + pxFromLonLat(&dx, &dy, currentLine->end.lon, currentLine->end.lat); + screenCoords(&x2, &y2, dx, dy); - float factor = 1.0 - (d1+d2) / (3* maxDist * maxDist); - - SDL_Color lineColor = lerpColor(style.mapOuterColor, style.mapInnerColor, factor); - - lineRGBA(renderer, x1, y1, x2, y2, lineColor.r, lineColor.g, lineColor.b, 255); + if(outOfBounds(x1,y1) && outOfBounds(x2,y2)) { + continue; } - ////bounding boxes - - // int x, y; - - // pxFromLonLat(&dx, &dy, currentPolygon->lon_min, currentPolygon->lat_min); - // screenCoords(&x, &y, dx, dy); - - // int top = y; - // int left = x; - - // pxFromLonLat(&dx, &dy, currentPolygon->lon_max, currentPolygon->lat_max); - // screenCoords(&x, &y, dx, dy); - - // int bottom = y; - // int right = x; - - // rectangleRGBA(renderer, left, top, right, bottom, purple.r, purple.g, purple.b, 255); + lineRGBA(renderer, x1, y1, x2, y2, style.mapInnerColor.r, style.mapInnerColor.g, style.mapInnerColor.b, 255); } } -void View::drawGeography() { +void View::drawGeography(int left, int top, int right, int bottom, int bailTime) { float screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max; - latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, 0, screen_height * -0.2); - latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, screen_width, screen_height * 1.2); + latLonFromScreenCoords(&screen_lat_min, &screen_lon_min, left, top); + latLonFromScreenCoords(&screen_lat_max, &screen_lon_max, right, bottom); - drawPolys(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max); + drawLines(screen_lat_min, screen_lat_max, screen_lon_min, screen_lon_max, bailTime); } void View::drawSignalMarks(Aircraft *p, int x, int y) { @@ -1308,27 +1283,29 @@ void View::registerMouseMove(int x, int y) { // void View::draw() { - uint64_t drawStartTime = now(); + drawStartTime = now(); moveMapToTarget(); zoomMapToTarget(); //updatePlanes(); - if(mapMoved) { + if(mapRedraw && !mapMoved) { SDL_SetRenderTarget(renderer, mapTexture); SDL_SetRenderDrawColor(renderer, style.backgroundColor.r, style.backgroundColor.g, style.backgroundColor.b, 255); SDL_RenderClear(renderer); - drawGeography(); - - drawScaleBars(); + drawGeography(0, 0, screen_width, screen_height, 0); SDL_SetRenderTarget(renderer, NULL ); - mapMoved = 0; + mapRedraw = 0; + + currentLon = centerLon; + currentLat = centerLat; + currentMaxDist = maxDist; } for(int i = 0; i < 4; i++) { @@ -1340,8 +1317,61 @@ void View::draw() { SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, mapTexture, NULL, NULL); + int shiftx = 0; + int shifty = 0; + if(mapMoved) { + float dx, dy; + int x1,y1, x2, y2; + pxFromLonLat(&dx, &dy, currentLon, currentLat); + screenCoords(&x1, &y1, dx, dy); + pxFromLonLat(&dx, &dy, centerLon, centerLat); + screenCoords(&x2, &y2, dx, dy); + + shiftx = x1-x2; + shifty = y1-y2; + + mapRedraw = 1; + + SDL_Rect dest; + + dest.x = shiftx + (screen_width / 2) * (1 - currentMaxDist / maxDist); + dest.y = shifty + (screen_height / 2) * (1 - currentMaxDist / maxDist); + dest.w = screen_width * currentMaxDist / maxDist; + dest.h = screen_height * currentMaxDist / maxDist; + + //left + if(dest.x > 0) { + drawGeography(0, 0, dest.x, screen_height, FRAMETIME / 4); + } + + //top + if(dest.y > 0) { + drawGeography(0, screen_height - dest.y, screen_width, screen_height, FRAMETIME / 4); + } + + //right + if(dest.x + dest.w < screen_width) { + drawGeography(dest.x + dest.w, 0, screen_width, screen_height, FRAMETIME / 4); + } + + //bottom + if(dest.y + dest.h < screen_height) { + drawGeography(0, 0, screen_width, screen_height - dest.y - dest.h, FRAMETIME / 4); + } + + //attempt rest before bailing + //drawGeography(dest.x, screen_height - dest.y, dest.x + dest.w, screen_height - dest.y - dest.h, 1); + + SDL_RenderCopy(renderer, mapTexture, NULL, &dest); + + mapMoved = 0; + } else { + SDL_RenderCopy(renderer, mapTexture, NULL, NULL); + } + + + drawScaleBars(); drawPlanes(); drawStatus(); drawMouse(); @@ -1353,12 +1383,11 @@ void View::draw() { SDL_RenderPresent(renderer); - lastFrameTime = now(); - - if (elapsed(drawStartTime) < FRAMETIME) { - usleep(1000 * (FRAMETIME - elapsed(drawStartTime))); + if (elapsed(drawStartTime) < FRAMETIME) { + std::this_thread::sleep_for(std::chrono::milliseconds((FRAMETIME - elapsed(drawStartTime)))); } + lastFrameTime = now(); } View::View(AppData *appData){ @@ -1374,6 +1403,9 @@ View::View(AppData *appData){ maxDist = 25.0; + mapMoved = 1; + mapRedraw = 1; + selectedAircraft = NULL; } diff --git a/View.h b/View.h index 9991b71..b2e88c2 100644 --- a/View.h +++ b/View.h @@ -78,8 +78,8 @@ class View { void drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor); void drawTrail(Aircraft *p); void drawScaleBars(); - void drawPolys(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); - void drawGeography(); + void drawLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max, int bailTime); + void drawGeography(int left, int top, int right, int bottom, int bailTime); void drawSignalMarks(Aircraft *p, int x, int y); void drawPlaneText(Aircraft *p); void drawSelectedAircraftText(Aircraft *p); @@ -107,6 +107,7 @@ class View { bool metric; float maxDist; + float currentMaxDist; float centerLon; float centerLat; @@ -116,7 +117,11 @@ class View { float mapTargetLon; int mapMoved; + int mapRedraw; + float currentLon; + float currentLat; uint64_t lastFrameTime; + uint64_t drawStartTime; Map map;