From 25a24c0cdf1467df51c41d0b24e2ab6318ba1850 Mon Sep 17 00:00:00 2001 From: number Zero Date: Thu, 23 Feb 2017 16:04:39 +0300 Subject: [PATCH] Minimap: Optimise --- src/minimap.cpp | 122 ++++++++++++++++++--------------------------- src/minimap.h | 7 +-- src/util/numeric.h | 10 ++++ 3 files changed, 59 insertions(+), 80 deletions(-) diff --git a/src/minimap.cpp b/src/minimap.cpp index a2e501751..cfc2c34b0 100644 --- a/src/minimap.cpp +++ b/src/minimap.cpp @@ -120,89 +120,63 @@ void MinimapUpdateThread::doUpdate() } if (data->map_invalidated && data->mode != MINIMAP_MODE_OFF) { - getMap(data->pos, data->map_size, data->scan_height, data->is_radar); + getMap(data->pos, data->map_size, data->scan_height); data->map_invalidated = false; } } -MinimapPixel *MinimapUpdateThread::getMinimapPixel(v3s16 pos, - s16 scan_height, s16 *pixel_height) +void MinimapUpdateThread::getMap(v3s16 pos, s16 size, s16 height) { - s16 height = scan_height - MAP_BLOCKSIZE; - v3s16 blockpos_max, blockpos_min, relpos; - - getNodeBlockPosWithOffset( - v3s16(pos.X, pos.Y - scan_height / 2, pos.Z), - blockpos_min, relpos); - getNodeBlockPosWithOffset( - v3s16(pos.X, pos.Y + scan_height / 2, pos.Z), - blockpos_max, relpos); - - for (s16 i = blockpos_max.Y; i > blockpos_min.Y - 1; i--) { - std::map::iterator it = - m_blocks_cache.find(v3s16(blockpos_max.X, i, blockpos_max.Z)); - if (it != m_blocks_cache.end()) { - MinimapMapblock *mmblock = it->second; - MinimapPixel *pixel = &mmblock->data[relpos.Z * MAP_BLOCKSIZE + relpos.X]; - if (pixel->n.param0 != CONTENT_AIR) { - *pixel_height = height + pixel->height; - return pixel; - } - } - - height -= MAP_BLOCKSIZE; + v3s16 region(size, 0, size); + v3s16 pos_min(pos.X - size / 2, pos.Y - height / 2, pos.Z - size / 2); + v3s16 pos_max(pos_min.X + size - 1, pos.Y + height / 2, pos_min.Z + size - 1); + v3s16 blockpos_min = getNodeBlockPos(pos_min); + v3s16 blockpos_max = getNodeBlockPos(pos_max); + +// clear the map + for (int z = 0; z < size; z++) + for (int x = 0; x < size; x++) { + MinimapPixel &mmpixel = data->minimap_scan[x + z * size]; + mmpixel.air_count = 0; + mmpixel.height = 0; + mmpixel.n = MapNode(CONTENT_AIR); } - return NULL; -} - -s16 MinimapUpdateThread::getAirCount(v3s16 pos, s16 height) -{ - s16 air_count = 0; - v3s16 blockpos_max, blockpos_min, relpos; - - getNodeBlockPosWithOffset( - v3s16(pos.X, pos.Y - height / 2, pos.Z), - blockpos_min, relpos); - getNodeBlockPosWithOffset( - v3s16(pos.X, pos.Y + height / 2, pos.Z), - blockpos_max, relpos); - - for (s16 i = blockpos_max.Y; i > blockpos_min.Y - 1; i--) { - std::map::iterator it = - m_blocks_cache.find(v3s16(blockpos_max.X, i, blockpos_max.Z)); - if (it != m_blocks_cache.end()) { - MinimapMapblock *mmblock = it->second; - MinimapPixel *pixel = &mmblock->data[relpos.Z * MAP_BLOCKSIZE + relpos.X]; - air_count += pixel->air_count; - } - } - - return air_count; -} - -void MinimapUpdateThread::getMap(v3s16 pos, s16 size, s16 height, bool is_radar) -{ - v3s16 p = v3s16(pos.X - size / 2, pos.Y, pos.Z - size / 2); - - for (s16 x = 0; x < size; x++) - for (s16 z = 0; z < size; z++) { - MapNode n(CONTENT_AIR); - MinimapPixel *mmpixel = &data->minimap_scan[x + z * size]; - - if (!is_radar) { - s16 pixel_height = 0; - MinimapPixel *cached_pixel = - getMinimapPixel(v3s16(p.X + x, p.Y, p.Z + z), height, &pixel_height); - if (cached_pixel) { - n = cached_pixel->n; - mmpixel->height = pixel_height; +// draw the map + v3s16 blockpos; + for (blockpos.Z = blockpos_min.Z; blockpos.Z <= blockpos_max.Z; ++blockpos.Z) + for (blockpos.Y = blockpos_min.Y; blockpos.Y <= blockpos_max.Y; ++blockpos.Y) + for (blockpos.X = blockpos_min.X; blockpos.X <= blockpos_max.X; ++blockpos.X) { + std::map::const_iterator pblock = + m_blocks_cache.find(blockpos); + if (pblock == m_blocks_cache.end()) + continue; + const MinimapMapblock &block = *pblock->second; + + v3s16 block_node_min(blockpos * MAP_BLOCKSIZE); + v3s16 block_node_max(block_node_min + MAP_BLOCKSIZE - 1); + // clip + v3s16 range_min = componentwise_max(block_node_min, pos_min); + v3s16 range_max = componentwise_min(block_node_max, pos_max); + + v3s16 pos; + pos.Y = range_min.Y; + for (pos.Z = range_min.Z; pos.Z <= range_max.Z; ++pos.Z) + for (pos.X = range_min.X; pos.X <= range_max.X; ++pos.X) { + v3s16 inblock_pos = pos - block_node_min; + const MinimapPixel &in_pixel = + block.data[inblock_pos.Z * MAP_BLOCKSIZE + inblock_pos.X]; + + v3s16 inmap_pos = pos - pos_min; + MinimapPixel &out_pixel = + data->minimap_scan[inmap_pos.X + inmap_pos.Z * size]; + + out_pixel.air_count += in_pixel.air_count; + if (in_pixel.n.param0 != CONTENT_AIR) { + out_pixel.n = in_pixel.n; + out_pixel.height = inmap_pos.Y + in_pixel.height; } - } else { - mmpixel->air_count = getAirCount(v3s16(p.X + x, p.Y, p.Z + z), height); } - - mmpixel->n = n; } } diff --git a/src/minimap.h b/src/minimap.h index 81ed0e49f..60b80d833 100644 --- a/src/minimap.h +++ b/src/minimap.h @@ -96,13 +96,8 @@ public: MinimapUpdateThread() : UpdateThread("Minimap") {} virtual ~MinimapUpdateThread(); - void getMap(v3s16 pos, s16 size, s16 height, bool radar); - MinimapPixel *getMinimapPixel(v3s16 pos, s16 height, s16 *pixel_height); - s16 getAirCount(v3s16 pos, s16 height); - video::SColor getColorFromId(u16 id); - + void getMap(v3s16 pos, s16 size, s16 height); void enqueueBlock(v3s16 pos, MinimapMapblock *data); - bool pushBlockUpdate(v3s16 pos, MinimapMapblock *data); bool popBlockUpdate(QueuedMinimapUpdate *update); diff --git a/src/util/numeric.h b/src/util/numeric.h index 4cdc254c3..760657171 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -149,6 +149,16 @@ inline void sortBoxVerticies(v3s16 &p1, v3s16 &p2) { SWAP(s16, p1.Z, p2.Z); } +inline v3s16 componentwise_min(const v3s16 &a, const v3s16 &b) +{ + return v3s16(MYMIN(a.X, b.X), MYMIN(a.Y, b.Y), MYMIN(a.Z, b.Z)); +} + +inline v3s16 componentwise_max(const v3s16 &a, const v3s16 &b) +{ + return v3s16(MYMAX(a.X, b.X), MYMAX(a.Y, b.Y), MYMAX(a.Z, b.Z)); +} + /** Returns \p f wrapped to the range [-360, 360] * -- 2.25.1