From 1c13313ec845d43077bd7e78538358ca4e007f8a Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 20 Mar 2023 06:29:31 +0100 Subject: sort entities by id rather than draw order --- src/chunk-render.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'src/chunk-render.cpp') diff --git a/src/chunk-render.cpp b/src/chunk-render.cpp index 7f4761e0..27a0367c 100644 --- a/src/chunk-render.cpp +++ b/src/chunk-render.cpp @@ -104,17 +104,55 @@ auto chunk::ensure_wall_mesh() noexcept -> wall_mesh_tuple return { wall_mesh, wall_indexes, count }; } -auto chunk::ensure_scenery_mesh() noexcept -> scenery_mesh_tuple +void chunk::ensure_scenery_draw_array(Array& array) { + const size_t len_ = _entities.size(); + + if (len_ <= array.size()) + return; + + size_t len; + + if (len_ > 1 << 17) + len = len_; + else + len = std::bit_ceil(len_); + + array = Array{len}; +} + +auto chunk::ensure_scenery_mesh(Array&& array) noexcept -> scenery_mesh_tuple +{ + return ensure_scenery_mesh(static_cast&>(array)); +} + +auto chunk::ensure_scenery_mesh(Array& array) noexcept -> scenery_mesh_tuple +{ + constexpr auto entity_ord_lessp = [](const auto& a, const auto& b) { + return a.ord < b.ord; + }; + fm_assert(_entities_sorted); + const auto size = _entities.size(); + + { + ensure_scenery_draw_array(array); + for (auto i = 0uz; const auto& e : _entities) + array[i++] = { e.get(), e->ordinal() }; + std::sort(array.begin(), array.begin() + size, entity_ord_lessp); + //do { Debug{} << "scenery-mesh: sorting" << size; fflush(stdout); } while (false); + } + + const auto es = ArrayView{array, size}; + if (_scenery_modified) { _scenery_modified = false; const auto count = fm_begin( size_t ret = 0; - for (const auto& e : _entities) + for (const auto& [e, ord] : es) ret += !e->is_dynamic(); return ret; ); @@ -124,7 +162,7 @@ auto chunk::ensure_scenery_mesh() noexcept -> scenery_mesh_tuple scenery_vertexes.clear(); scenery_vertexes.reserve(count); - for (const auto& e : _entities) + for (const auto& [e, ord] : es) { if (e->atlas->info().fps > 0) continue; @@ -152,7 +190,10 @@ auto chunk::ensure_scenery_mesh() noexcept -> scenery_mesh_tuple .setCount(int32_t(6 * count)); scenery_mesh = Utility::move(mesh); } - return { scenery_mesh, }; + + fm_assert(!size || es); + + return { scenery_mesh, es, size }; } } // namespace floormat -- cgit v1.2.3