diff --git a/Aircraft.cpp b/Aircraft.cpp index cc02c06..ce39ee5 100644 --- a/Aircraft.cpp +++ b/Aircraft.cpp @@ -32,6 +32,24 @@ #include "Aircraft.h" #include "AircraftLabel.h" +float Aircraft::getLastLon() { + if(lonHistory.size() > 1) { + return lonHistory.end()[-2]; + } +} + +float Aircraft::getLastLat() { + if(latHistory.size() > 1) { + return latHistory.end()[-2]; + } +} + +float Aircraft::getLastHeading() { + if(headingHistory.size() > 1) { + return headingHistory.end()[-2]; + } +} + Aircraft::Aircraft(uint32_t addr) { this->addr = addr; prev_seen = 0; diff --git a/Aircraft.h b/Aircraft.h index 30f78a6..1fe184d 100644 --- a/Aircraft.h +++ b/Aircraft.h @@ -39,6 +39,12 @@ class AircraftLabel; class Aircraft { public: + float getLastLon(); + float getLastLat(); + float getLastHeading(); + + + uint32_t addr; // ICAO address char flight[16]; // Flight number unsigned char signalLevel[8]; // Last 8 Signal Amplitudes diff --git a/AircraftLabel.cpp b/AircraftLabel.cpp index 9469c17..a03c1bb 100644 --- a/AircraftLabel.cpp +++ b/AircraftLabel.cpp @@ -334,6 +334,7 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { } labelLevel += level_rate; + isChanging = true; lastLevelChange = now(); } } else if (labelLevel > 1.2f + density_mult * calculateDensity(head, labelLevel + 1)) { @@ -343,6 +344,7 @@ void AircraftLabel::calculateForces(Aircraft *check_p) { } labelLevel -= level_rate; + isChanging = true; lastLevelChange = now(); } } @@ -392,12 +394,16 @@ void AircraftLabel::applyForces() { dy = 0; } + if(dx < 1 || dy < 1) { + isChanging = true; + } + float new_x = 0; float new_y = 0; for(int i = 0; i < buffer_length; i++) { - new_x += x_buffer[i] / static_cast(buffer_length); - new_y += y_buffer[i] / static_cast(buffer_length); + new_x += x_buffer[i] / static_cast(buffer_length); + new_y += y_buffer[i] / static_cast(buffer_length); } x_buffer[buffer_idx] = new_x + dx; @@ -633,6 +639,13 @@ void AircraftLabel::draw(SDL_Renderer *renderer, bool selected) { if(h < 0.05f) { h = 0; } + + isChanging = false; +} + + +bool AircraftLabel::getIsChanging() { + return isChanging; } AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int screen_height, TTF_Font *font) { @@ -666,6 +679,8 @@ AircraftLabel::AircraftLabel(Aircraft *p, bool metric, int screen_width, int scr labelLevel = 0; + isChanging = false; + flightLabel.setFont(font); altitudeLabel.setFont(font); speedLabel.setFont(font); diff --git a/AircraftLabel.h b/AircraftLabel.h index a6052e7..c98e3df 100644 --- a/AircraftLabel.h +++ b/AircraftLabel.h @@ -16,6 +16,7 @@ class AircraftLabel { void calculateForces(Aircraft *check_p); void applyForces(); void move(float dx, float dy); + bool getIsChanging(); void draw(SDL_Renderer *renderer, bool selected); @@ -63,11 +64,13 @@ class AircraftLabel { int screen_width; int screen_height; + bool isChanging; + std::chrono::high_resolution_clock::time_point lastLevelChange; /////////// - float label_force = 0.01f; + float label_force = 0.01f; float label_dist = 2.0f; float density_force = 0.01f; float attachment_force = 0.01f; diff --git a/View.cpp b/View.cpp index f9f0913..82231cd 100644 --- a/View.cpp +++ b/View.cpp @@ -83,6 +83,40 @@ SDL_Color setColor(uint8_t r, uint8_t g, uint8_t b) { return out; } +float lerp(float a, float b, float factor) { + if(factor > 1.0f) { + factor = 1.0f; + } + + if(factor < 0.0f) { + factor = 0.0f; + } + + return (1.0f - factor) * a + factor * b; +} + +float lerpAngle(float a, float b, float factor) { + float diff = fabs(b - a); + if (diff > 180.0f) + { + if (b > a) + { + a += 360.0f; + } + else + { + b += 360.0f; + } + } + + float value = (a + ((b - a) * factor)); + + if (value >= 0.0f && value <= 360.0f) + return value; + + return fmod(value,360.0f); +} + SDL_Color lerpColor(SDL_Color aColor, SDL_Color bColor, float factor) { if(factor > 1.0f) { factor = 1.0f; @@ -401,15 +435,15 @@ void View::drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor) x2 = x + round(bodyWidth*out[0]); y2 = y + round(bodyWidth*out[1]); - trigonRGBA (renderer, x1, y1, x2, y2, x+round(-body * vec[0]), y+round(-body*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); - trigonRGBA (renderer, x1, y1, x2, y2, x+round(body * vec[0]), y+round(body*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); + filledTrigonRGBA (renderer, x1, y1, x2, y2, x+round(-body * vec[0]), y+round(-body*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); + filledTrigonRGBA (renderer, x1, y1, x2, y2, x+round(body * vec[0]), y+round(body*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); - // x1 = x + round(-body*vec[0] - bodyWidth*out[0]); - // y1 = y + round(-body*vec[1] - bodyWidth*out[1]); - // x2 = x + round(body*vec[0] - bodyWidth*out[0]); - // y2 = y + round(body*vec[1] - bodyWidth*out[1]); + x1 = x + round(15*vec[0]); + y1 = y + round(15*vec[1]); + x2 = x + round(30*vec[0]); + y2 = y + round(30*vec[1]); - // lineRGBA(renderer,x,y,x2,y2,planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); + lineRGBA(renderer,x1,y1,x2,y2,255,255,255,SDL_ALPHA_OPAQUE); // x1 = x + round(-body*vec[0] + bodyWidth*out[0]); // y1 = y + round(-body*vec[1] + bodyWidth*out[1]); @@ -427,7 +461,7 @@ void View::drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor) x2 = x + round(wing*out[0]); y2 = y + round(wing*out[1]); - trigonRGBA(renderer, x1, y1, x2, y2, x+round(body*wingThick*vec[0]), y+round(body*wingThick*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); + filledTrigonRGBA(renderer, x1, y1, x2, y2, x+round(body*wingThick*vec[0]), y+round(body*wingThick*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); //tail x1 = x + round(-body*.75*vec[0] - tail*out[0]); @@ -435,7 +469,7 @@ void View::drawPlaneIcon(int x, int y, float heading, SDL_Color planeColor) x2 = x + round(-body*.75*vec[0] + tail*out[0]); y2 = y + round(-body*.75*vec[1] + tail*out[1]); - trigonRGBA (renderer, x1, y1, x2, y2, x+round(-body*tailThick*vec[0]), y+round(-body*tailThick*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); + filledTrigonRGBA (renderer, x1, y1, x2, y2, x+round(-body*tailThick*vec[0]), y+round(-body*tailThick*vec[1]),planeColor.r,planeColor.g,planeColor.b,SDL_ALPHA_OPAQUE); } void View::drawTrails(int left, int top, int right, int bottom) { @@ -754,9 +788,7 @@ void View::moveLabels(float dx, float dy) { } -float View::resolveLabelConflicts() { - float maxV = 0.0f; - +void View::resolveLabelConflicts() { Aircraft *p = appData->aircraftList.head; while(p) { @@ -783,12 +815,14 @@ float View::resolveLabelConflicts() { if(p->label) { p->label->applyForces(); + + // if(p->label->getIsChanging()) { + // highFramerate = true; + // } } p = p->next; } - - return maxV; } void View::drawPlanes() { @@ -819,6 +853,7 @@ void View::drawPlanes() { float age_ms = elapsed(p->created); if(age_ms < 500) { + //highFramerate = true; float ratio = age_ms / 500.0f; float radius = (1.0f - ratio * ratio) * screen_width / 8; for(float theta = 0; theta < 2*M_PI; theta += M_PI / 4) { @@ -829,6 +864,10 @@ void View::drawPlanes() { if(MODES_ACFLAGS_HEADING_VALID) { int usex = x; int usey = y; + float useHeading = static_cast(p->track); + + p->x = usex; + p->y = usey; planeColor = lerpColor(style.planeColor, style.planeGoneColor, elapsed_s(p->msSeen) / DISPLAY_ACTIVE); @@ -836,19 +875,23 @@ void View::drawPlanes() { planeColor = style.selectedColor; } + if(outOfBounds(x,y)) { drawPlaneOffMap(x, y, &(p->x), &(p->y), planeColor); } else { - drawPlaneIcon(usex, usey, p->track, planeColor); + if(elapsed(p->msSeenLatLon) < 500) { + //highFramerate = true; + circleRGBA(renderer, p->x, p->y, elapsed(p->msSeenLatLon) * screen_width / (8192), 127,127, 127, 255 - (uint8_t)(255.0 * elapsed(p->msSeenLatLon) / 500.0)); + + pxFromLonLat(&dx, &dy, p->getLastLon(), p->getLastLat()); + screenCoords(&x, &y, dx, dy); - p->x = usex; - p->y = usey; - } - - - //show latlon ping - if(elapsed(p->msSeenLatLon) < 500) { - circleRGBA(renderer, p->x, p->y, elapsed(p->msSeenLatLon) * screen_width / (8192), 127,127, 127, 255 - (uint8_t)(255.0 * elapsed(p->msSeenLatLon) / 500.0)); + usex = lerp(x,usex,elapsed(p->msSeenLatLon) / 500.0); + usey = lerp(y,usey,elapsed(p->msSeenLatLon) / 500.0); + useHeading = lerpAngle(p->getLastHeading(),useHeading,elapsed(p->msSeenLatLon) / 500.0); + } + + drawPlaneIcon(usex, usey, useHeading, planeColor); } drawPlaneText(p); @@ -877,6 +920,8 @@ void View::animateCenterAbsolute(float x, float y) { mapTargetMaxDist = 0.25 * maxDist; mapMoved = 1; + highFramerate = true; + } void View::moveCenterAbsolute(float x, float y) { @@ -898,6 +943,7 @@ void View::moveCenterAbsolute(float x, float y) { mapTargetLat = 0; mapMoved = 1; + highFramerate = true; } void View::moveCenterRelative(float dx, float dy) { @@ -923,6 +969,7 @@ void View::moveCenterRelative(float dx, float dy) { mapTargetLat = 0; mapMoved = 1; + highFramerate = true; } void View::zoomMapToTarget() { @@ -931,6 +978,7 @@ void View::zoomMapToTarget() { maxDist += 0.1 * (mapTargetMaxDist - maxDist); mapAnimating = 1; mapMoved = 1; + highFramerate = true; } else { mapTargetMaxDist = 0; } @@ -945,6 +993,7 @@ void View::moveMapToTarget() { mapAnimating = 1; mapMoved = 1; + highFramerate = true; } else { mapTargetLon = 0; mapTargetLat = 0; @@ -970,6 +1019,7 @@ void View::moveMapToTarget() { void View::drawClick() { if(clickx && clicky) { + highFramerate = true; int radius = .25 * elapsed(clickTime); int alpha = 128 - static_cast(0.5 * elapsed(clickTime)); @@ -1052,6 +1102,7 @@ void View::registerMouseMove(int x, int y) { // latLonFromScreenCoords(&(mouse->lat), &(mouse->lon), x, screen_height-y); // mouse->live = 1; // } + highFramerate = true; } // @@ -1059,7 +1110,19 @@ void View::registerMouseMove(int x, int y) { // void View::draw() { - drawStartTime = now(); + + int targetFrameTime = 15; + + // if(highFramerate) { + // targetFrameTime = 15; + // } + // highFramerate = false; + + // if (elapsed(lastFrameTime) < targetFrameTime) { + // SDL_Delay(static_cast(targetFrameTime - elapsed(lastFrameTime))); + // } + + SDL_Delay(targetFrameTime); moveMapToTarget(); zoomMapToTarget(); @@ -1080,18 +1143,27 @@ void View::draw() { //drawMouse(); drawClick(); - // if(fps) { - // char fps[60] = " "; - // snprintf(fps,40," %d lines @ %.1ffps", lineCount, 1000.0 / elapsed(lastFrameTime)); + if(fps) { + char fps[60] = " "; + snprintf(fps,40,"%.1f", 1000.0 / elapsed(lastFrameTime)); - // drawStringBG(fps, 0,0, mapFont, style.subLabelColor, style.backgroundColor); - // } + + int left = 5; + int top = 5; + drawStatusBox(&left, &top, "fps", fps, style.white); + } + SDL_Delay(33); + SDL_RenderPresent(renderer); - if (elapsed(drawStartTime) < FRAMETIME) { - std::this_thread::sleep_for(fmilliseconds{FRAMETIME} - (now() - drawStartTime)); - } + + + + //if (elapsed(lastFrameTime) < targetFrameTime) { + //std::this_thread::sleep_for(fmilliseconds{targetFrameTime - elapsed(lastFrameTime)}); + //std::this_thread::sleep_for(fmilliseconds{100.0f}); + //} lastFrameTime = now(); } @@ -1108,6 +1180,8 @@ View::View(AppData *appData){ fullscreen = 0; screen_index = 0; + highFramerate = false; + centerLon = 0; centerLat = 0; diff --git a/View.h b/View.h index 0034dc8..216c0b1 100644 --- a/View.h +++ b/View.h @@ -108,7 +108,7 @@ class View { void drawGeography(); void drawSignalMarks(Aircraft *p, int x, int y); void drawPlaneText(Aircraft *p); - float resolveLabelConflicts(); + void resolveLabelConflicts(); void drawPlanes(); void animateCenterAbsolute(float x, float y); void moveCenterAbsolute(float x, float y); @@ -147,6 +147,8 @@ class View { int mapRedraw; int mapAnimating; + bool highFramerate; + float currentLon; float currentLat; std::chrono::high_resolution_clock::time_point lastFrameTime; diff --git a/run_viz1090.sh b/run_viz1090.sh index 2baecc8..756060e 100755 --- a/run_viz1090.sh +++ b/run_viz1090.sh @@ -1,2 +1,2 @@ #!/bin/bash -./viz1090 --screensize 640 360 --fullscreen --server adsb --lat 47.6 --lon -122.3 +./viz1090 --screensize 1920 1080 --fullscreen --server adsb --lat 47.6 --lon -122.3