]> git.localhorst.tv Git - blank.git/blobdiff - src/world/Generator.cpp
try to cleanly destruct world
[blank.git] / src / world / Generator.cpp
index f15a25245dc0d89413671fdcc3a4407c09e413b5..466139b8943a4fadc1187736e6b29509d462642b 100644 (file)
@@ -23,9 +23,10 @@ std::vector<Candidate> candidates;
 
 }
 
-Generator::Generator(const Config &config, const BlockTypeRegistry &types) noexcept
+Generator::Generator(const Config &config) noexcept
 : config(config)
-, types(types)
+, types()
+, min_solidity(2.0f)
 , solidity_noise(config.seed ^ config.solidity.seed_mask)
 , humidity_noise(config.seed ^ config.humidity.seed_mask)
 , temperature_noise(config.seed ^ config.temperature.seed_mask)
@@ -34,49 +35,57 @@ Generator::Generator(const Config &config, const BlockTypeRegistry &types) noexc
 
 }
 
-void Generator::Scan() {
-       size_t count = 0;
-       for (size_t i = 0, end = types.Size(); i < end; ++i) {
-               if (types[i].generate) ++count;
+void Generator::LoadTypes(const BlockTypeRegistry &reg) {
+       types.clear();
+       min_solidity = 2.0f;
+       for (const BlockType &type : reg) {
+               if (type.generate) {
+                       types.push_back(&type);
+                       if (type.min_solidity < min_solidity) {
+                               min_solidity = type.min_solidity;
+                       }
+               }
        }
-       candidates.reserve(count);
+       candidates.reserve(types.size());
 }
 
 void Generator::operator ()(Chunk &chunk) const noexcept {
-       Chunk::Pos pos(chunk.Position());
-       glm::vec3 coords(pos * Chunk::Extent());
-       for (int z = 0; z < Chunk::depth; ++z) {
-               for (int y = 0; y < Chunk::height; ++y) {
-                       for (int x = 0; x < Chunk::width; ++x) {
-                               Block::Pos block_pos(x, y, z);
-                               chunk.SetBlock(block_pos, Generate(coords + block_pos));
+       ExactLocation::Coarse pos(chunk.Position());
+       ExactLocation::Fine coords(pos * ExactLocation::Extent());
+       for (int z = 0; z < Chunk::side; ++z) {
+               for (int y = 0; y < Chunk::side; ++y) {
+                       for (int x = 0; x < Chunk::side; ++x) {
+                               ExactLocation::Fine block_pos(x, y, z);
+                               chunk.SetBlock(RoughLocation::Fine(x, y, z), Generate(coords + ExactLocation::Fine(x, y, z)));
                        }
                }
        }
+       chunk.SetGenerated();
 }
 
 Block Generator::Generate(const glm::vec3 &pos) const noexcept {
        float solidity = GetValue(solidity_noise, pos, config.solidity);
+       if (solidity < min_solidity) {
+               return Block(0);
+       }
        float humidity = GetValue(humidity_noise, pos, config.humidity);
        float temperature = GetValue(temperature_noise, pos, config.temperature);
        float richness = GetValue(richness_noise, pos, config.richness);
 
        candidates.clear();
        float total = 0.0f;
-       for (size_t i = 0, end = types.Size(); i < end; ++i) {
-               const BlockType &type = types[i];
-               if (!type.generate) continue;
-               if (solidity < type.min_solidity || solidity > type.max_solidity) continue;
-               if (humidity < type.min_humidity || humidity > type.max_humidity) continue;
-               if (temperature < type.min_temperature || temperature > type.max_temperature) continue;
-               if (richness < type.min_richness || richness > type.max_richness) continue;
-               float solidity_match = 4.0f - ((solidity - type.mid_solidity) * (solidity - type.mid_solidity));
-               float humidity_match = 4.0f - ((humidity - type.mid_humidity) * (humidity - type.mid_humidity));
-               float temperature_match = 4.0f - ((temperature - type.mid_temperature) * (temperature - type.mid_temperature));
-               float richness_match = 4.0f - ((richness - type.mid_richness) * (richness - type.mid_richness));
-               float chance = (solidity_match + humidity_match + temperature_match + richness_match) * type.commonness;
+       for (const BlockType *type : types) {
+               if (solidity < type->min_solidity || solidity > type->max_solidity) continue;
+               if (humidity < type->min_humidity || humidity > type->max_humidity) continue;
+               if (temperature < type->min_temperature || temperature > type->max_temperature) continue;
+               if (richness < type->min_richness || richness > type->max_richness) continue;
+               float solidity_match = 4.0f - ((solidity - type->mid_solidity) * (solidity - type->mid_solidity));
+               float humidity_match = 4.0f - ((humidity - type->mid_humidity) * (humidity - type->mid_humidity));
+               float temperature_match = 4.0f - ((temperature - type->mid_temperature) * (temperature - type->mid_temperature));
+               float richness_match = 4.0f - ((richness - type->mid_richness) * (richness - type->mid_richness));
+               float chance = (solidity_match + humidity_match + temperature_match + richness_match) * type->commonness;
                total += chance;
-               candidates.emplace_back(&type, total);
+               candidates.emplace_back(type, total);
        }
        if (candidates.empty()) {
                return Block(0);