From 5728f9c7d09327ddc11c779b951688ea32b4b725 Mon Sep 17 00:00:00 2001 From: Matt Kimber Date: Sun, 3 Jan 2021 14:02:53 +0000 Subject: Codechange: consider vehicle co-ordinates when identifying viewport candidate as using only the hash generates false positives --- src/vehicle.cpp | 22 ++++++++++++++-------- src/vehicle_base.h | 10 +++++----- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 89cabe20d..e35842118 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1124,11 +1124,15 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) const int t = dpi->top; const int b = dpi->top + dpi->height; + /* Border size of MAX_VEHICLE_PIXEL_xy */ + const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE; + const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE; + /* The hash area to scan */ int xl, xu, yl, yu; - if (dpi->width + (MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE) < GEN_HASHX_SIZE) { - xl = GEN_HASHX(l - MAX_VEHICLE_PIXEL_X * ZOOM_LVL_BASE); + if (dpi->width + xb < GEN_HASHX_SIZE) { + xl = GEN_HASHX(l - xb); xu = GEN_HASHX(r); } else { /* scan whole hash row */ @@ -1136,8 +1140,8 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) xu = GEN_HASHX_MASK; } - if (dpi->height + (MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE) < GEN_HASHY_SIZE) { - yl = GEN_HASHY(t - MAX_VEHICLE_PIXEL_Y * ZOOM_LVL_BASE); + if (dpi->height + yb < GEN_HASHY_SIZE) { + yl = GEN_HASHY(t - yb); yu = GEN_HASHY(b); } else { /* scan whole column */ @@ -1158,9 +1162,14 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) b >= v->coord.top) { DoDrawVehicle(v); } - else { + else if (l <= v->coord.right + xb && + t <= v->coord.bottom + yb && + r >= v->coord.left - xb && + b >= v->coord.top - yb) + { /* * Indicate that this vehicle was considered for rendering in a viewport, + * is within the bounds where a sprite could be valid for rendering * and we therefore need to update sprites more frequently in case a callback * will change the bounding box to one which will cause the sprite to be * displayed. @@ -1168,9 +1177,6 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) * This reduces the chances of flicker when sprites enter the screen, if they * are part of a newgrf vehicle set which changes bounding boxes within a * single vehicle direction. - * - * TODO: this will consider too many false positives, use the bounding box - * information or something which better narrows down the candidates. */ v->sprite_cache.is_viewport_candidate = true; } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index d6a02cc0c..24facfb3e 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -186,10 +186,10 @@ struct VehicleSpriteSeq { * or calculating the viewport. */ struct MutableSpriteCache { - Direction last_direction; ///< Last direction we obtained sprites for - mutable bool is_viewport_candidate; ///< The vehicle has been in the hash for a shown viewport recently - mutable bool sprite_has_viewport_changes; ///< There have been viewport changes since the sprite was last updated - mutable VehicleSpriteSeq sprite_seq; ///< Vehicle appearance. + Direction last_direction; ///< Last direction we obtained sprites for + bool is_viewport_candidate; ///< The vehicle has been in the hash for a shown viewport recently + bool sprite_has_viewport_changes; ///< There have been viewport changes since the sprite was last updated + VehicleSpriteSeq sprite_seq; ///< Vehicle appearance. }; /** A vehicle pool for a little over 1 million vehicles. */ @@ -337,7 +337,7 @@ public: NewGRFCache grf_cache; ///< Cache of often used calculated NewGRF values VehicleCache vcache; ///< Cache of often used vehicle values. - MutableSpriteCache sprite_cache; ///< Cache of sprites and values related to recalculating them, see #MutableSpriteCache + mutable MutableSpriteCache sprite_cache; ///< Cache of sprites and values related to recalculating them, see #MutableSpriteCache Vehicle(VehicleType type = VEH_INVALID); -- cgit v1.2.3-54-g00ecf