implement inter-chunk structure generation
This commit is contained in:
parent
03ba7c9539
commit
a413c5d09e
@ -68,10 +68,13 @@ end
|
|||||||
|
|
||||||
function place_structures(x, z, w, d, seed)
|
function place_structures(x, z, w, d, seed)
|
||||||
local placements = {}
|
local placements = {}
|
||||||
local px = math.random() * w
|
local hmap = generate_heightmap(x, z, w, d, seed)
|
||||||
local py = 200;
|
for i=0,math.floor(math.random()*3)+5 do
|
||||||
local pz = math.random() * d
|
local px = math.random() * w
|
||||||
table.insert(placements, {0, {px, py, pz}})
|
local pz = math.random() * d
|
||||||
|
local py = hmap:at(px, pz) * 256
|
||||||
|
table.insert(placements, {0, {px-8, py, pz-8}})
|
||||||
|
end
|
||||||
return placements
|
return placements
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,15 @@ static int l_dump(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_at(lua::State* L) {
|
||||||
|
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
|
||||||
|
int x = lua::tointeger(L, 2);
|
||||||
|
int y = lua::tointeger(L, 3);
|
||||||
|
return lua::pushnumber(L, heightmap->getHeightmap()->get(x, y));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
template<fnl_noise_type noise_type>
|
template<fnl_noise_type noise_type>
|
||||||
static int l_noise(lua::State* L) {
|
static int l_noise(lua::State* L) {
|
||||||
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
|
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
|
||||||
@ -208,6 +217,7 @@ static std::unordered_map<std::string, lua_CFunction> methods {
|
|||||||
{"abs", lua::wrap<l_unaryop_func<util::abs>>},
|
{"abs", lua::wrap<l_unaryop_func<util::abs>>},
|
||||||
{"resize", lua::wrap<l_resize>},
|
{"resize", lua::wrap<l_resize>},
|
||||||
{"crop", lua::wrap<l_crop>},
|
{"crop", lua::wrap<l_crop>},
|
||||||
|
{"at", lua::wrap<l_at>},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int l_meta_meta_call(lua::State* L) {
|
static int l_meta_meta_call(lua::State* L) {
|
||||||
|
|||||||
@ -121,6 +121,7 @@ public:
|
|||||||
|
|
||||||
lua::rawgeti(L, 2);
|
lua::rawgeti(L, 2);
|
||||||
glm::ivec3 pos = lua::tovec3(L, -1);
|
glm::ivec3 pos = lua::tovec3(L, -1);
|
||||||
|
lua::pop(L);
|
||||||
|
|
||||||
lua::pop(L);
|
lua::pop(L);
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <queue>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
template <class T>
|
template <class T>
|
||||||
bool contains(const std::vector<T>& vec, const T& value) {
|
inline bool contains(const std::vector<T>& vec, const T& value) {
|
||||||
return std::find(vec.begin(), vec.end(), value) != vec.end();
|
return std::find(vec.begin(), vec.end(), value) != vec.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline void concat(std::vector<T>& a, const std::vector<T>& b) {
|
||||||
|
a.reserve(a.size() + b.size());
|
||||||
|
a.insert(a.end(), b.begin(), b.end());
|
||||||
|
}
|
||||||
|
|
||||||
std::string to_string(const std::vector<std::string>& vec);
|
std::string to_string(const std::vector<std::string>& vec);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "GeneratorDef.hpp"
|
#include "GeneratorDef.hpp"
|
||||||
#include "VoxelStructure.hpp"
|
#include "VoxelStructure.hpp"
|
||||||
#include "util/timeutil.hpp"
|
#include "util/timeutil.hpp"
|
||||||
|
#include "util/listutil.hpp"
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
|
|
||||||
static debug::Logger logger("world-generator");
|
static debug::Logger logger("world-generator");
|
||||||
@ -132,15 +133,49 @@ std::unique_ptr<ChunkPrototype> WorldGenerator::generatePrototype(
|
|||||||
return std::make_unique<ChunkPrototype>();
|
return std::make_unique<ChunkPrototype>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline AABB gen_chunk_aabb(int chunkX, int chunkZ) {
|
||||||
|
return AABB({chunkX * CHUNK_W, 0, chunkZ * CHUNK_D},
|
||||||
|
{(chunkX + 1)*CHUNK_W, 256, (chunkZ + 1) * CHUNK_D});
|
||||||
|
}
|
||||||
|
|
||||||
void WorldGenerator::generateStructures(
|
void WorldGenerator::generateStructures(
|
||||||
ChunkPrototype& prototype, int chunkX, int chunkZ
|
ChunkPrototype& prototype, int chunkX, int chunkZ
|
||||||
) {
|
) {
|
||||||
if (prototype.level >= ChunkPrototypeLevel::STRUCTURES) {
|
if (prototype.level >= ChunkPrototypeLevel::STRUCTURES) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
prototype.structures = def.script->placeStructures(
|
util::concat(prototype.structures, def.script->placeStructures(
|
||||||
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed
|
{chunkX * CHUNK_W, chunkZ * CHUNK_D}, {CHUNK_W, CHUNK_D}, seed
|
||||||
);
|
));
|
||||||
|
for (const auto& placement : prototype.structures) {
|
||||||
|
const auto& offset = placement.position;
|
||||||
|
if (placement.structure < 0 || placement.structure >= structures.size()) {
|
||||||
|
logger.error() << "invalid structure index " << placement.structure;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& structure = *structures[placement.structure];
|
||||||
|
auto position = glm::ivec3(chunkX * CHUNK_W, 0, chunkZ * CHUNK_D)+offset;
|
||||||
|
auto size = structure.getSize() + glm::ivec3(0, CHUNK_H, 0);
|
||||||
|
AABB aabb(position, position + size);
|
||||||
|
for (int lcz = -1; lcz <= 1; lcz++) {
|
||||||
|
for (int lcx = -1; lcx <= 1; lcx++) {
|
||||||
|
if (lcx == 0 && lcz == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& otherPrototype = requirePrototype(
|
||||||
|
chunkX + lcx, chunkZ + lcz
|
||||||
|
);
|
||||||
|
auto chunkAABB = gen_chunk_aabb(chunkX + lcx, chunkZ + lcz);
|
||||||
|
if (chunkAABB.intersect(aabb)) {
|
||||||
|
otherPrototype.structures.emplace_back(
|
||||||
|
placement.structure,
|
||||||
|
placement.position -
|
||||||
|
glm::ivec3(lcx * CHUNK_W, 0, lcz * CHUNK_D)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
prototype.level = ChunkPrototypeLevel::STRUCTURES;
|
prototype.level = ChunkPrototypeLevel::STRUCTURES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +259,7 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) {
|
|||||||
for (const auto& placement : prototype.structures) {
|
for (const auto& placement : prototype.structures) {
|
||||||
if (placement.structure < 0 || placement.structure >= structures.size()) {
|
if (placement.structure < 0 || placement.structure >= structures.size()) {
|
||||||
logger.error() << "invalid structure index " << placement.structure;
|
logger.error() << "invalid structure index " << placement.structure;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
auto& structure = *structures[placement.structure];
|
auto& structure = *structures[placement.structure];
|
||||||
auto& structVoxels = structure.getRuntimeVoxels();
|
auto& structVoxels = structure.getRuntimeVoxels();
|
||||||
@ -244,8 +280,11 @@ void WorldGenerator::generate(voxel* voxels, int chunkX, int chunkZ) {
|
|||||||
if (sx < 0 || sx >= CHUNK_W) {
|
if (sx < 0 || sx >= CHUNK_W) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
voxels[vox_index(sx, sy, sz)] =
|
const auto& structVoxel =
|
||||||
structVoxels[vox_index(x, y, z, size.x, size.z)];
|
structVoxels[vox_index(x, y, z, size.x, size.z)];
|
||||||
|
if (structVoxel.id) {
|
||||||
|
voxels[vox_index(sx, sy, sz)] = structVoxel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user