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},
|
{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)
|
||||||
|
|||||||
@ -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";
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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>);
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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";
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user