]> git.lizzy.rs Git - dragonblocks3d.git/blob - src/dragonblocks/map.cpp
e9030cb22c544db5d2eb3db2c4508bdd16c9273d
[dragonblocks3d.git] / src / dragonblocks / map.cpp
1 #include <stdexcept>
2 #include "face_dir.hpp"
3 #include "map.hpp"
4 #include "mapgen.hpp"
5
6 using namespace std;
7 using namespace glm;
8 using namespace dragonblocks;
9
10 ivec3 Map::getChunkPos(const vec3 &p)
11 {
12         return floor(p / 16.0F);
13 }
14
15 ivec3 Map::getBlockPos(const ivec3 &p)
16 {
17         return ((p % 16) + ivec3(16)) % 16;
18 }
19
20 uint16_t Map::getChunkPosHash(const ivec3 &p)
21 {
22         return (uint16_t)p.x + (uint16_t)p.y * 1000 + (uint16_t)p.z * 1000000;
23 }
24
25 const Block *Map::getBlock(const glm::ivec3 &p)
26 {
27         
28         Chunk *chunk = getChunk(Map::getChunkPos(p));
29         if (chunk)
30                 return chunk->getBlock(Map::getBlockPos(p));
31         return nullptr;
32 }
33
34 const Block *Map::getBlockRelativePos(Chunk *chunk, const glm::ivec3 &p)
35 {
36         const Block *b = nullptr;
37         try {
38                 b = chunk->getBlock(p);
39         } catch (std::out_of_range &) {
40                 b = getBlock(chunk->pos * 16 + p);
41         }
42         return b;
43 }
44
45 void Map::setBlock(const glm::ivec3 &p, BlockDef *def)
46 {
47         Chunk *chunk = getChunk(Map::getChunkPos(p));
48         if (chunk)
49                 chunk->setBlock(Map::getBlockPos(p), def);
50 }
51
52 void Map::createChunk(const glm::ivec3 &p, const Chunk::Data &data)
53 {
54         uint64_t poshash = Map::getChunkPosHash(p);
55         
56         if (chunks[poshash])
57                 return;
58
59         chunks[poshash] = new Chunk(this, p, data, mesh_gen_thread, scene);
60         
61         for (int i = 0; i < 6; i++) {
62                 if (Chunk *neighbor = getChunk(p + face_dir[i]))
63                         neighbor->addMeshUpdateTask();
64         }
65 }
66
67 void Map::createChunk(const glm::ivec3 &p)
68 {
69         if (! chunks[Map::getChunkPosHash(p)])
70                 createChunk(p, mapgen->generate(p));
71 }       
72
73 Chunk *Map::getChunk(const glm::ivec3 &p)
74 {
75         return chunks[Map::getChunkPosHash(p)];
76 }
77
78 void Map::clear()
79 {
80         for (auto it = chunks.begin(); it != chunks.end(); it++)
81                 delete it->second;
82         chunks.clear();
83 }
84
85 Map::Map(Mapgen *m, MeshGenThread *mgt, Scene *s) : mapgen(m), mesh_gen_thread(mgt), scene(s)
86 {
87 }
88
89 Map::~Map()
90 {
91         clear();
92 }