add heightmap write-only property 'noiseSeed'
This commit is contained in:
parent
510c45ffe9
commit
e560236a8c
@ -7,15 +7,18 @@ layers = {
|
||||
{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 vmap = Heightmap(w, h)
|
||||
umap.noiseSeed = seed
|
||||
vmap.noiseSeed = seed
|
||||
umap:noise({x+521, y+73}, 0.05, 1, 20.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+95, y+246}, 0.15, 3, 35.8)
|
||||
|
||||
local map = Heightmap(w, h)
|
||||
map.noiseSeed = seed
|
||||
map:noise({x, y}, 0.02, 7, 0.2)
|
||||
map:noise({x, y}, 0.06, 8, 0.4, umap, vmap)
|
||||
map:mul(0.5)
|
||||
@ -23,6 +26,7 @@ function generate_heightmap(x, y, w, h)
|
||||
map:pow(2.0)
|
||||
|
||||
local rivermap = Heightmap(w, h)
|
||||
rivermap.noiseSeed = seed
|
||||
rivermap:noise({x+21, y+12}, 0.1, 4)
|
||||
rivermap:abs()
|
||||
rivermap:mul(2.0)
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
#include "lua_commons.hpp"
|
||||
#include "maths/Heightmap.hpp"
|
||||
|
||||
struct fnl_state;
|
||||
|
||||
namespace lua {
|
||||
class Userdata {
|
||||
public:
|
||||
@ -33,9 +35,9 @@ namespace lua {
|
||||
|
||||
class LuaHeightmap : public Userdata {
|
||||
std::shared_ptr<Heightmap> map;
|
||||
std::unique_ptr<fnl_state> noise;
|
||||
public:
|
||||
LuaHeightmap(uint width, uint height)
|
||||
: map(std::make_shared<Heightmap>(width, height)) {}
|
||||
LuaHeightmap(uint width, uint height);
|
||||
|
||||
virtual ~LuaHeightmap();
|
||||
|
||||
@ -63,6 +65,12 @@ namespace lua {
|
||||
return map;
|
||||
}
|
||||
|
||||
fnl_state* getNoise() {
|
||||
return noise.get();
|
||||
}
|
||||
|
||||
void setSeed(int64_t seed);
|
||||
|
||||
static int createMetatable(lua::State*);
|
||||
inline static std::string TYPENAME = "Heightmap";
|
||||
};
|
||||
|
||||
@ -15,9 +15,16 @@
|
||||
|
||||
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) {
|
||||
@ -51,6 +58,7 @@ static int l_noise(lua::State* L) {
|
||||
uint w = heightmap->getWidth();
|
||||
uint h = heightmap->getHeight();
|
||||
auto heights = heightmap->getValues();
|
||||
auto noise = heightmap->getNoise();
|
||||
|
||||
auto offset = tovec<2>(L, 2);
|
||||
|
||||
@ -86,7 +94,7 @@ static int l_noise(lua::State* L) {
|
||||
v += shiftMapY->getValues()[i];
|
||||
}
|
||||
|
||||
value += fnlGetNoise2D(&noise, u, v) /
|
||||
value += fnlGetNoise2D(noise, u, v) /
|
||||
static_cast<float>(1 << c) * multiplier;
|
||||
heights[i] = value;
|
||||
}
|
||||
@ -185,6 +193,20 @@ static int l_meta_index(lua::State* L) {
|
||||
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) {
|
||||
auto map = touserdata<LuaHeightmap>(L, 1);
|
||||
if (map == nullptr) {
|
||||
@ -202,11 +224,13 @@ static int l_meta_tostring(lua::State* L) {
|
||||
}
|
||||
|
||||
int LuaHeightmap::createMetatable(lua::State* L) {
|
||||
createtable(L, 0, 2);
|
||||
createtable(L, 0, 3);
|
||||
pushcfunction(L, lua::wrap<l_meta_tostring>);
|
||||
setfield(L, "__tostring");
|
||||
pushcfunction(L, lua::wrap<l_meta_index>);
|
||||
setfield(L, "__index");
|
||||
pushcfunction(L, lua::wrap<l_meta_newindex>);
|
||||
setfield(L, "__newindex");
|
||||
|
||||
createtable(L, 0, 1);
|
||||
pushcfunction(L, lua::wrap<l_meta_meta_call>);
|
||||
|
||||
@ -703,14 +703,15 @@ public:
|
||||
{}
|
||||
|
||||
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 {
|
||||
auto L = lua::get_main_thread();
|
||||
lua::pushenv(L, *env);
|
||||
if (lua::getfield(L, "generate_heightmap")) {
|
||||
lua::pushivec_stack(L, offset);
|
||||
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();
|
||||
lua::pop(L, 2);
|
||||
return map;
|
||||
|
||||
@ -23,7 +23,7 @@ public:
|
||||
virtual ~GeneratorScript() = default;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@ -15,10 +15,12 @@ WorldGenerator::WorldGenerator(
|
||||
}
|
||||
|
||||
#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);
|
||||
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();
|
||||
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 x = 0; x < CHUNK_W; x++) {
|
||||
// generate water
|
||||
int height = values[z * CHUNK_W + x] * CHUNK_H;
|
||||
for (uint y = height+1; y <= seaLevel; y++) {
|
||||
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 layerExtension = 0;
|
||||
for (const auto& layer : layers) {
|
||||
// skip layer if can't be generated under sea level
|
||||
if (y < seaLevel && !layer.below_sea_level) {
|
||||
layerExtension = std::max(0, layer.height);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint layerHeight = layer.height;
|
||||
if (layerHeight == -1) {
|
||||
// resizeable layer
|
||||
layerHeight = y - lastLayersHeight + 1;
|
||||
} else {
|
||||
layerHeight += layerExtension;
|
||||
|
||||
@ -18,7 +18,7 @@ public:
|
||||
);
|
||||
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";
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user