- unsigned int random = 263167 * pos.x + 2097593 * pos.y + 426389 * pos.z;
- for (int index = 0; index < Chunk::size; ++index) {
- if (chunk.IsSurface(index)) {
- random = random * 666649 + 7778777;
- if ((random % 32) == 0) {
- chunk.SetBlock(index, Block(light));
- }
+}
+
+Block Generator::Generate(const glm::vec3 &pos) const noexcept {
+ float solidity = GetValue(solidity_noise, pos, config.solidity);
+ 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;
+ total += chance;
+ candidates.emplace_back(&type, total);
+ }
+ if (candidates.empty()) {
+ return Block(0);
+ }
+ float random = GetValue(random_noise, pos, config.randomness);
+ if (random < 0.0f) random += 1.0f;
+ float value = random * total;
+ // TODO: change to binary search
+ for (const Candidate &cand : candidates) {
+ if (value < cand.threshold) {
+ return Block(cand.type->id);