refactor blocks layers
This commit is contained in:
@@ -42,11 +42,11 @@ end
|
|||||||
|
|
||||||
function generate_heightmap(x, y, w, h, seed)
|
function generate_heightmap(x, y, w, h, seed)
|
||||||
-- blocks per dot
|
-- blocks per dot
|
||||||
-- 8 - linear interpolation is visible, but not so much (Minecraft)
|
-- 8 - linear interpolation is visible, but not so much
|
||||||
-- 4 - high quality, but slower
|
-- 4 - high quality, but slower
|
||||||
-- 2 - you really don't need it
|
-- 2 - you really don't need it
|
||||||
-- 1 - please have mercy on your CPU
|
-- 1 - please have mercy on your CPU
|
||||||
local bpd = 8
|
local bpd = 4
|
||||||
local map = _generate_heightmap(
|
local map = _generate_heightmap(
|
||||||
math.floor(x/bpd), math.floor(y/bpd),
|
math.floor(x/bpd), math.floor(y/bpd),
|
||||||
math.floor(w/bpd)+1, math.floor(h/bpd)+1, seed, bpd)
|
math.floor(w/bpd)+1, math.floor(h/bpd)+1, seed, bpd)
|
||||||
|
|||||||
@@ -687,24 +687,18 @@ void scripting::load_entity_component(
|
|||||||
|
|
||||||
class LuaGeneratorScript : public GeneratorScript {
|
class LuaGeneratorScript : public GeneratorScript {
|
||||||
scriptenv env;
|
scriptenv env;
|
||||||
std::vector<BlocksLayer> layers;
|
BlocksLayers groundLayers;
|
||||||
std::vector<BlocksLayer> seaLayers;
|
BlocksLayers seaLayers;
|
||||||
uint lastLayersHeight;
|
|
||||||
uint lastSeaLayersHeight;
|
|
||||||
uint seaLevel;
|
uint seaLevel;
|
||||||
public:
|
public:
|
||||||
LuaGeneratorScript(
|
LuaGeneratorScript(
|
||||||
scriptenv env,
|
scriptenv env,
|
||||||
std::vector<BlocksLayer> layers,
|
BlocksLayers groundLayers,
|
||||||
std::vector<BlocksLayer> seaLayers,
|
BlocksLayers seaLayers,
|
||||||
uint lastLayersHeight,
|
|
||||||
uint lastSeaLayersHeight,
|
|
||||||
uint seaLevel)
|
uint seaLevel)
|
||||||
: env(std::move(env)),
|
: env(std::move(env)),
|
||||||
layers(std::move(layers)),
|
groundLayers(std::move(groundLayers)),
|
||||||
seaLayers(std::move(seaLayers)),
|
seaLayers(std::move(seaLayers)),
|
||||||
lastLayersHeight(lastLayersHeight),
|
|
||||||
lastSeaLayersHeight(lastSeaLayersHeight),
|
|
||||||
seaLevel(seaLevel)
|
seaLevel(seaLevel)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -728,30 +722,22 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void prepare(const Content* content) override {
|
void prepare(const Content* content) override {
|
||||||
for (auto& layer : layers) {
|
for (auto& layer : groundLayers.layers) {
|
||||||
layer.rt.id = content->blocks.require(layer.block).rt.id;
|
layer.rt.id = content->blocks.require(layer.block).rt.id;
|
||||||
}
|
}
|
||||||
for (auto& layer : seaLayers) {
|
for (auto& layer : seaLayers.layers) {
|
||||||
layer.rt.id = content->blocks.require(layer.block).rt.id;
|
layer.rt.id = content->blocks.require(layer.block).rt.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<BlocksLayer>& getLayers() const override {
|
const BlocksLayers& getGroundLayers() const override {
|
||||||
return layers;
|
return groundLayers;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<BlocksLayer>& getSeaLayers() const override {
|
const BlocksLayers& getSeaLayers() const override {
|
||||||
return seaLayers;
|
return seaLayers;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint getLastLayersHeight() const override {
|
|
||||||
return lastLayersHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint getLastSeaLayersHeight() const override {
|
|
||||||
return lastSeaLayersHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint getSeaLevel() const override {
|
uint getSeaLevel() const override {
|
||||||
return seaLevel;
|
return seaLevel;
|
||||||
}
|
}
|
||||||
@@ -784,6 +770,32 @@ static BlocksLayer load_layer(
|
|||||||
return BlocksLayer {name, height, belowSeaLevel, {}};
|
return BlocksLayer {name, height, belowSeaLevel, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BlocksLayers load_layers(
|
||||||
|
lua::State* L, const std::string& fieldname
|
||||||
|
) {
|
||||||
|
uint lastLayersHeight = 0;
|
||||||
|
bool hasResizeableLayer = false;
|
||||||
|
std::vector<BlocksLayer> layers;
|
||||||
|
|
||||||
|
if (lua::getfield(L, fieldname)) {
|
||||||
|
int len = lua::objlen(L, -1);
|
||||||
|
for (int i = 1; i <= len; i++) {
|
||||||
|
lua::rawgeti(L, i);
|
||||||
|
try {
|
||||||
|
layers.push_back(
|
||||||
|
load_layer(L, -1, lastLayersHeight, hasResizeableLayer));
|
||||||
|
} catch (const std::runtime_error& err) {
|
||||||
|
lua::pop(L, 2);
|
||||||
|
throw std::runtime_error(
|
||||||
|
fieldname+" #"+std::to_string(i)+": "+err.what());
|
||||||
|
}
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
lua::pop(L);
|
||||||
|
}
|
||||||
|
return BlocksLayers {std::move(layers), lastLayersHeight};
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<GeneratorScript> scripting::load_generator(
|
std::unique_ptr<GeneratorScript> scripting::load_generator(
|
||||||
const fs::path& file
|
const fs::path& file
|
||||||
) {
|
) {
|
||||||
@@ -800,50 +812,25 @@ std::unique_ptr<GeneratorScript> scripting::load_generator(
|
|||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint lastLayersHeight = 0;
|
uint lastGroundLayersHeight = 0;
|
||||||
uint lastSeaLayersHeight = 0;
|
uint lastSeaLayersHeight = 0;
|
||||||
bool hasResizeableLayer = false;
|
bool hasResizeableGroundLayer = false;
|
||||||
bool hasResizeableSeaLayer = false;
|
bool hasResizeableSeaLayer = false;
|
||||||
|
|
||||||
std::vector<BlocksLayer> layers;
|
BlocksLayers groundLayers;
|
||||||
std::vector<BlocksLayer> seaLayers;
|
BlocksLayers seaLayers;
|
||||||
if (lua::getfield(L, "layers")) {
|
try {
|
||||||
int len = lua::objlen(L, -1);
|
groundLayers = load_layers(L, "layers");
|
||||||
for (int i = 1; i <= len; i++) {
|
seaLayers = load_layers(L, "sea_layers");
|
||||||
lua::rawgeti(L, i);
|
} catch (const std::runtime_error& err) {
|
||||||
try {
|
|
||||||
layers.push_back(
|
|
||||||
load_layer(L, -1, lastLayersHeight, hasResizeableLayer));
|
|
||||||
} catch (const std::runtime_error& err) {
|
|
||||||
lua::pop(L, 2);
|
|
||||||
throw std::runtime_error(
|
|
||||||
"layer #"+std::to_string(i)+": "+err.what());
|
|
||||||
}
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
if (lua::getfield(L, "sea_layers")) {
|
|
||||||
int len = lua::objlen(L, -1);
|
|
||||||
for (int i = 1; i <= len; i++) {
|
|
||||||
lua::rawgeti(L, i);
|
|
||||||
try {
|
|
||||||
seaLayers.push_back(
|
|
||||||
load_layer(L, -1, lastSeaLayersHeight, hasResizeableSeaLayer));
|
|
||||||
} catch (const std::runtime_error& err) {
|
|
||||||
lua::pop(L, 2);
|
|
||||||
throw std::runtime_error(
|
|
||||||
"sea layer #"+std::to_string(i)+": "+err.what());
|
|
||||||
}
|
|
||||||
lua::pop(L);
|
|
||||||
}
|
|
||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
|
throw std::runtime_error(file.u8string()+": "+err.what());
|
||||||
}
|
}
|
||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
return std::make_unique<LuaGeneratorScript>(
|
return std::make_unique<LuaGeneratorScript>(
|
||||||
std::move(env),
|
std::move(env),
|
||||||
std::move(layers), std::move(seaLayers),
|
std::move(groundLayers),
|
||||||
lastLayersHeight, lastSeaLayersHeight,
|
std::move(seaLayers),
|
||||||
seaLevel);
|
seaLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ struct BlocksLayer {
|
|||||||
} rt;
|
} rt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BlocksLayers {
|
||||||
|
std::vector<BlocksLayer> layers;
|
||||||
|
uint lastLayersHeight;
|
||||||
|
};
|
||||||
|
|
||||||
class GeneratorScript {
|
class GeneratorScript {
|
||||||
public:
|
public:
|
||||||
virtual ~GeneratorScript() = default;
|
virtual ~GeneratorScript() = default;
|
||||||
@@ -25,12 +30,8 @@ public:
|
|||||||
virtual std::shared_ptr<Heightmap> generateHeightmap(
|
virtual std::shared_ptr<Heightmap> generateHeightmap(
|
||||||
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed) = 0;
|
const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed) = 0;
|
||||||
|
|
||||||
virtual const std::vector<BlocksLayer>& getLayers() const = 0;
|
virtual const BlocksLayers& getGroundLayers() const = 0;
|
||||||
virtual const std::vector<BlocksLayer>& getSeaLayers() const = 0;
|
virtual const BlocksLayers& getSeaLayers() const = 0;
|
||||||
|
|
||||||
/// @brief Total height of all layers after resizeable one
|
|
||||||
virtual uint getLastLayersHeight() const = 0;
|
|
||||||
virtual uint getLastSeaLayersHeight() const = 0;
|
|
||||||
|
|
||||||
virtual uint getSeaLevel() const = 0;
|
virtual uint getSeaLevel() const = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -9,31 +9,32 @@
|
|||||||
#include "voxels/voxel.hpp"
|
#include "voxels/voxel.hpp"
|
||||||
#include "world/generator/GeneratorDef.hpp"
|
#include "world/generator/GeneratorDef.hpp"
|
||||||
|
|
||||||
WorldGenerator::WorldGenerator(
|
WorldGenerator::WorldGenerator(const GeneratorDef& def, const Content* content)
|
||||||
const GeneratorDef& def,
|
: def(def), content(content) {
|
||||||
const Content* content
|
|
||||||
) : def(def), content(content) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void generate_pole(
|
static inline void generate_pole(
|
||||||
const std::vector<BlocksLayer>& layers,
|
const BlocksLayers& layers,
|
||||||
int height, int bottom, int seaLevel, int lastLayersHeight,
|
int height,
|
||||||
|
int bottom,
|
||||||
|
int seaLevel,
|
||||||
voxel* voxels,
|
voxel* voxels,
|
||||||
int x, int z
|
int x,
|
||||||
|
int z
|
||||||
) {
|
) {
|
||||||
uint y = height;
|
uint y = height;
|
||||||
uint layerExtension = 0;
|
uint layerExtension = 0;
|
||||||
for (const auto& layer : layers) {
|
for (const auto& layer : layers.layers) {
|
||||||
// skip layer if can't be generated under sea level
|
// skip layer if can't be generated under sea level
|
||||||
if (y < seaLevel && !layer.below_sea_level) {
|
if (y < seaLevel && !layer.below_sea_level) {
|
||||||
layerExtension = std::max(0, layer.height);
|
layerExtension = std::max(0, layer.height);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int layerHeight = layer.height;
|
int layerHeight = layer.height;
|
||||||
if (layerHeight == -1) {
|
if (layerHeight == -1) {
|
||||||
// resizeable layer
|
// resizeable layer
|
||||||
layerHeight = y - lastLayersHeight - bottom + 1;
|
layerHeight = y - layers.lastLayersHeight - bottom + 1;
|
||||||
} else {
|
} else {
|
||||||
layerHeight += layerExtension;
|
layerHeight += layerExtension;
|
||||||
}
|
}
|
||||||
@@ -52,15 +53,12 @@ void WorldGenerator::generate(
|
|||||||
) {
|
) {
|
||||||
timeutil::ScopeLogTimer log(555);
|
timeutil::ScopeLogTimer log(555);
|
||||||
auto heightmap = def.script->generateHeightmap(
|
auto heightmap = def.script->generateHeightmap(
|
||||||
{chunkX*CHUNK_W, chunkZ*CHUNK_D}, {CHUNK_W, CHUNK_D}, seed
|
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed
|
||||||
);
|
);
|
||||||
auto values = heightmap->getValues();
|
auto values = heightmap->getValues();
|
||||||
const auto& layers = def.script->getLayers();
|
const auto& groundLayers = def.script->getGroundLayers();
|
||||||
const auto& seaLayers = def.script->getSeaLayers();
|
const auto& seaLayers = def.script->getSeaLayers();
|
||||||
|
|
||||||
uint lastLayersHeight = def.script->getLastLayersHeight();
|
|
||||||
uint lastSeaLayersHeight = def.script->getLastSeaLayersHeight();
|
|
||||||
|
|
||||||
uint seaLevel = def.script->getSeaLevel();
|
uint seaLevel = def.script->getSeaLevel();
|
||||||
|
|
||||||
std::memset(voxels, 0, sizeof(voxel) * CHUNK_VOL);
|
std::memset(voxels, 0, sizeof(voxel) * CHUNK_VOL);
|
||||||
@@ -70,8 +68,8 @@ void WorldGenerator::generate(
|
|||||||
int height = values[z * CHUNK_W + x] * CHUNK_H;
|
int height = values[z * CHUNK_W + x] * CHUNK_H;
|
||||||
height = std::max(0, height);
|
height = std::max(0, height);
|
||||||
|
|
||||||
generate_pole(seaLayers, seaLevel, height, seaLevel, lastSeaLayersHeight, voxels, x, z);
|
generate_pole(seaLayers, seaLevel, height, seaLevel, voxels, x, z);
|
||||||
generate_pole(layers, height, 0, seaLevel, lastLayersHeight, voxels, x, z);
|
generate_pole(groundLayers, height, 0, seaLevel, voxels, x, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user