3#include <tess/core/shape.h>
4#include <tess/storage/residency.h>
5#include <tess/storage/world.h>
21 std::uint32_t dirty_flags = 0;
22 std::uint32_t chunk_version = 0;
27[[nodiscard]]
constexpr auto axis_end(std::int64_t origin,
28 std::uint64_t extent)
noexcept
33 return box_axis_end(origin, extent);
39template <
typename World>
40void emit_chunk_render_deltas(
const World& world, ChunkKey chunk_key,
41 std::uint32_t dirty_mask,
42 std::vector<RenderTileDelta>& out) {
43 using Shape =
typename World::shape_type;
47 const auto observed = world.observe_dirty(chunk_key, dirty_mask);
48 const auto flags = observed.flags;
52 const auto& dirty_bounds = observed.bounds;
57 using Traits = ShapeTraits<Shape>;
58 const auto chunk = chunk_coord<Shape>(chunk_key);
59 const auto chunk_begin_x =
60 static_cast<std::int64_t
>(chunk.x * Traits::chunk.x);
61 const auto chunk_begin_y =
62 static_cast<std::int64_t
>(chunk.y * Traits::chunk.y);
63 const auto chunk_begin_z =
64 static_cast<std::int64_t
>(chunk.z * Traits::chunk.z);
65 const auto begin_x = std::max(dirty_bounds.origin.x, chunk_begin_x);
66 const auto begin_y = std::max(dirty_bounds.origin.y, chunk_begin_y);
67 const auto begin_z = std::max(dirty_bounds.origin.z, chunk_begin_z);
69 std::min(detail::axis_end(dirty_bounds.origin.x, dirty_bounds.extent.x),
70 chunk_begin_x +
static_cast<std::int64_t
>(Traits::chunk.x));
72 std::min(detail::axis_end(dirty_bounds.origin.y, dirty_bounds.extent.y),
73 chunk_begin_y +
static_cast<std::int64_t
>(Traits::chunk.y));
75 std::min(detail::axis_end(dirty_bounds.origin.z, dirty_bounds.extent.z),
76 chunk_begin_z +
static_cast<std::int64_t
>(Traits::chunk.z));
77 for (
auto z = begin_z; z < end_z; ++z) {
78 for (
auto y = begin_y; y < end_y; ++y) {
79 for (
auto x = begin_x; x < end_x; ++x) {
80 const auto coord = Coord3{x, y, z};
81 out.push_back(RenderTileDelta{
84 local_tile_id<Shape>(local_coord<Shape>(coord)),
99template <
typename World>
100void collect_render_tile_deltas(
const World& world, std::uint32_t dirty_mask,
101 std::vector<RenderTileDelta>& out) {
102 if (dirty_mask == 0) {
109 if constexpr (std::is_same_v<
typename World::residency_type,
111 for (std::uint64_t key = 0; key < World::chunk_count; ++key) {
112 detail::emit_chunk_render_deltas(world,
ChunkKey{key}, dirty_mask, out);
115 for (
const auto chunk_key : world.resident_chunk_keys()) {
116 detail::emit_chunk_render_deltas(world, chunk_key, dirty_mask, out);
122template <
typename World>
123[[nodiscard]]
auto render_tile_deltas(
const World& world,
124 std::uint32_t dirty_mask)
125 -> std::vector<RenderTileDelta> {
126 std::vector<RenderTileDelta> deltas;
127 collect_render_tile_deltas(world, dirty_mask, deltas);
132template <
typename World>
133void clear_render_delta_dirty(
World& world, std::uint32_t dirty_mask)
noexcept {
134 if (dirty_mask == 0) {
137 if constexpr (std::is_same_v<
typename World::residency_type,
139 for (std::uint64_t key = 0; key < World::chunk_count; ++key) {
140 world.clear_dirty(
ChunkKey{key}, dirty_mask);
145 for (
const auto chunk_key : world.resident_chunk_keys()) {
146 world.clear_dirty(chunk_key, dirty_mask);
Identifies one dirty tile for a renderer to reread from the world.
Definition render_delta.h:17