add heightmap write-only property 'noiseSeed'

This commit is contained in:
MihailRis 2024-08-17 20:17:52 +03:00
parent 510c45ffe9
commit e560236a8c
7 changed files with 56 additions and 13 deletions

View File

@ -7,15 +7,18 @@ layers = {
{block="base:bazalt", height=1}, {block="base:bazalt", height=1},
} }
function generate_heightmap(x, y, w, h) function generate_heightmap(x, y, w, h, seed)
local umap = Heightmap(w, h) local umap = Heightmap(w, h)
local vmap = Heightmap(w, h) local vmap = Heightmap(w, h)
umap.noiseSeed = seed
vmap.noiseSeed = seed
umap:noise({x+521, y+73}, 0.05, 1, 20.8) umap:noise({x+521, y+73}, 0.05, 1, 20.8)
umap:noise({x+51, y+75}, 0.05, 1, 21.8) umap:noise({x+51, y+75}, 0.05, 1, 21.8)
vmap:noise({x+521, y+70}, 0.1, 3, 35.8) vmap:noise({x+521, y+70}, 0.1, 3, 35.8)
vmap:noise({x+95, y+246}, 0.15, 3, 35.8) vmap:noise({x+95, y+246}, 0.15, 3, 35.8)
local map = Heightmap(w, h) local map = Heightmap(w, h)
map.noiseSeed = seed
map:noise({x, y}, 0.02, 7, 0.2) map:noise({x, y}, 0.02, 7, 0.2)
map:noise({x, y}, 0.06, 8, 0.4, umap, vmap) map:noise({x, y}, 0.06, 8, 0.4, umap, vmap)
map:mul(0.5) map:mul(0.5)
@ -23,6 +26,7 @@ function generate_heightmap(x, y, w, h)
map:pow(2.0) map:pow(2.0)
local rivermap = Heightmap(w, h) local rivermap = Heightmap(w, h)
rivermap.noiseSeed = seed
rivermap:noise({x+21, y+12}, 0.1, 4) rivermap:noise({x+21, y+12}, 0.1, 4)
rivermap:abs() rivermap:abs()
rivermap:mul(2.0) rivermap:mul(2.0)

View File

@ -6,6 +6,8 @@
#include "lua_commons.hpp" #include "lua_commons.hpp"
#include "maths/Heightmap.hpp" #include "maths/Heightmap.hpp"
struct fnl_state;
namespace lua { namespace lua {
class Userdata { class Userdata {
public: public:
@ -33,9 +35,9 @@ namespace lua {
class LuaHeightmap : public Userdata { class LuaHeightmap : public Userdata {
std::shared_ptr<Heightmap> map; std::shared_ptr<Heightmap> map;
std::unique_ptr<fnl_state> noise;
public: public:
LuaHeightmap(uint width, uint height) LuaHeightmap(uint width, uint height);
: map(std::make_shared<Heightmap>(width, height)) {}
virtual ~LuaHeightmap(); virtual ~LuaHeightmap();
@ -63,6 +65,12 @@ namespace lua {
return map; return map;
} }
fnl_state* getNoise() {
return noise.get();
}
void setSeed(int64_t seed);
static int createMetatable(lua::State*); static int createMetatable(lua::State*);
inline static std::string TYPENAME = "Heightmap"; inline static std::string TYPENAME = "Heightmap";
}; };

View File

@ -15,9 +15,16 @@
using namespace lua; using namespace lua;
static fnl_state noise = fnlCreateState(); LuaHeightmap::LuaHeightmap(uint width, uint height)
: map(std::make_shared<Heightmap>(width, height)),
noise(std::make_unique<fnl_state>(fnlCreateState()))
{}
LuaHeightmap::~LuaHeightmap() {; LuaHeightmap::~LuaHeightmap() {
}
void LuaHeightmap::setSeed(int64_t seed) {
noise->seed = seed;
} }
static int l_dump(lua::State* L) { static int l_dump(lua::State* L) {
@ -51,6 +58,7 @@ static int l_noise(lua::State* L) {
uint w = heightmap->getWidth(); uint w = heightmap->getWidth();
uint h = heightmap->getHeight(); uint h = heightmap->getHeight();
auto heights = heightmap->getValues(); auto heights = heightmap->getValues();
auto noise = heightmap->getNoise();
auto offset = tovec<2>(L, 2); auto offset = tovec<2>(L, 2);
@ -86,7 +94,7 @@ static int l_noise(lua::State* L) {
v += shiftMapY->getValues()[i]; v += shiftMapY->getValues()[i];
} }
value += fnlGetNoise2D(&noise, u, v) / value += fnlGetNoise2D(noise, u, v) /
static_cast<float>(1 << c) * multiplier; static_cast<float>(1 << c) * multiplier;
heights[i] = value; heights[i] = value;
} }
@ -185,6 +193,20 @@ static int l_meta_index(lua::State* L) {
return 0; return 0;
} }
static int l_meta_newindex(lua::State* L) {
auto map = touserdata<LuaHeightmap>(L, 1);
if (map == nullptr) {
return 0;
}
if (isstring(L, 2)) {
auto fieldname = tostring(L, 2);
if (!std::strcmp(fieldname, "noiseSeed")) {
map->setSeed(tointeger(L, 3));
}
}
return 0;
}
static int l_meta_tostring(lua::State* L) { static int l_meta_tostring(lua::State* L) {
auto map = touserdata<LuaHeightmap>(L, 1); auto map = touserdata<LuaHeightmap>(L, 1);
if (map == nullptr) { if (map == nullptr) {
@ -202,11 +224,13 @@ static int l_meta_tostring(lua::State* L) {
} }
int LuaHeightmap::createMetatable(lua::State* L) { int LuaHeightmap::createMetatable(lua::State* L) {
createtable(L, 0, 2); createtable(L, 0, 3);
pushcfunction(L, lua::wrap<l_meta_tostring>); pushcfunction(L, lua::wrap<l_meta_tostring>);
setfield(L, "__tostring"); setfield(L, "__tostring");
pushcfunction(L, lua::wrap<l_meta_index>); pushcfunction(L, lua::wrap<l_meta_index>);
setfield(L, "__index"); setfield(L, "__index");
pushcfunction(L, lua::wrap<l_meta_newindex>);
setfield(L, "__newindex");
createtable(L, 0, 1); createtable(L, 0, 1);
pushcfunction(L, lua::wrap<l_meta_meta_call>); pushcfunction(L, lua::wrap<l_meta_meta_call>);

View File

@ -703,14 +703,15 @@ public:
{} {}
std::shared_ptr<Heightmap> generateHeightmap( std::shared_ptr<Heightmap> generateHeightmap(
const glm::ivec2& offset, const glm::ivec2& size const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed
) override { ) override {
auto L = lua::get_main_thread(); auto L = lua::get_main_thread();
lua::pushenv(L, *env); lua::pushenv(L, *env);
if (lua::getfield(L, "generate_heightmap")) { if (lua::getfield(L, "generate_heightmap")) {
lua::pushivec_stack(L, offset); lua::pushivec_stack(L, offset);
lua::pushivec_stack(L, size); lua::pushivec_stack(L, size);
if (lua::call_nothrow(L, 4)) { lua::pushinteger(L, seed);
if (lua::call_nothrow(L, 5)) {
auto map = lua::touserdata<lua::LuaHeightmap>(L, -1)->getHeightmap(); auto map = lua::touserdata<lua::LuaHeightmap>(L, -1)->getHeightmap();
lua::pop(L, 2); lua::pop(L, 2);
return map; return map;

View File

@ -23,7 +23,7 @@ public:
virtual ~GeneratorScript() = default; virtual ~GeneratorScript() = default;
virtual std::shared_ptr<Heightmap> generateHeightmap( virtual std::shared_ptr<Heightmap> generateHeightmap(
const glm::ivec2& offset, const glm::ivec2& size) = 0; const glm::ivec2& offset, const glm::ivec2& size, uint64_t seed) = 0;
virtual const std::vector<BlocksLayer>& getLayers() const = 0; virtual const std::vector<BlocksLayer>& getLayers() const = 0;

View File

@ -15,10 +15,12 @@ WorldGenerator::WorldGenerator(
} }
#include "util/timeutil.hpp" #include "util/timeutil.hpp"
void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ, int seed) { void WorldGenerator::generate(
voxel* voxels, int chunkX, int chunkZ, uint64_t seed
) {
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} {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& layers = def.script->getLayers();
@ -30,6 +32,7 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ, int seed) {
for (uint z = 0; z < CHUNK_D; z++) { for (uint z = 0; z < CHUNK_D; z++) {
for (uint x = 0; x < CHUNK_W; x++) { for (uint x = 0; x < CHUNK_W; x++) {
// generate water
int height = values[z * CHUNK_W + x] * CHUNK_H; int height = values[z * CHUNK_W + x] * CHUNK_H;
for (uint y = height+1; y <= seaLevel; y++) { for (uint y = height+1; y <= seaLevel; y++) {
voxels[vox_index(x, y, z)].id = baseWater; voxels[vox_index(x, y, z)].id = baseWater;
@ -38,12 +41,15 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ, int seed) {
uint y = height; uint y = height;
uint layerExtension = 0; uint layerExtension = 0;
for (const auto& layer : layers) { for (const auto& layer : layers) {
// 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;
} }
uint layerHeight = layer.height; uint layerHeight = layer.height;
if (layerHeight == -1) { if (layerHeight == -1) {
// resizeable layer
layerHeight = y - lastLayersHeight + 1; layerHeight = y - lastLayersHeight + 1;
} else { } else {
layerHeight += layerExtension; layerHeight += layerExtension;

View File

@ -18,7 +18,7 @@ public:
); );
virtual ~WorldGenerator() = default; virtual ~WorldGenerator() = default;
virtual void generate(voxel* voxels, int x, int z, int seed); virtual void generate(voxel* voxels, int x, int z, uint64_t seed);
inline static std::string DEFAULT = "core:default"; inline static std::string DEFAULT = "core:default";
}; };