summary refs log tree commit diff
path: root/src/World/World.hpp
blob: ef8b7afe2f1597fcb24a691700bb57fcd13ad032 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#pragma once

#include <unordered_map>
#include <unordered_set>
#include <optional>
#include "Generation/Generator.hpp"
#include "ChunkIndex.hpp"
#include "../GFX/Binder.hpp"
#include "../Compute/Queue.hpp"

namespace MC::World {

class World {
public:
    World() : m_queue(8) {}

    enum class ChunkStatus {
        Empty,
        WaitingForGeneration,
        NeedsMesh,
        Done
    };

    struct ChunkData {
        ChunkIndex index;
        ChunkStatus status;
        std::optional<Chunk> chunk = {};

        std::optional<GFX::Mesh> land_mesh_data = {};
        std::optional<GFX::Mesh> water_mesh_data = {};

        std::optional<GFX::BindableMesh> land_mesh = {};
        std::optional<GFX::BindableMesh> water_mesh = {};
    };

    std::vector<ChunkData*> get_visible_chunks(Vector<3> position);
    Chunk* get_chunk_for_position(Vector<3> position);

    Real get_average_chunk_time() const;
private:
    std::vector<ChunkIndex> get_visible_chunk_indices(Vector<3> position) const;
    void load_finished_chunks_from_queue();
    void request_generation(ChunkIndex index, Real priority);
    void try_to_create_mesh_for_chunk(ChunkData& data);

    void log_chunk_time(U64 chunk_time_ms);

    ChunkData& get(ChunkIndex index);

    static U64 timestamp();

    U8 m_view_distance_radius = 10;

    struct GenerationResult {
        Chunk chunk;
        U64 generation_duration;
    };
    Compute::Queue<GenerationResult, ChunkIndex> m_queue;
    Generation::Generator m_generator;

    std::unordered_map<ChunkIndex, ChunkData> m_chunks;

    struct Statistics {
        UInt chunk_time_sample_count;
        Real average_chunk_time_ms;
    };
    Statistics m_statistics{0, 0.0f};
};

}