add VoxelStructure lua usertype
This commit is contained in:
parent
bf9f81a98c
commit
88b0f8e3d6
BIN
res/generators/default.files/tree0.vox
Normal file
BIN
res/generators/default.files/tree0.vox
Normal file
Binary file not shown.
@ -1,3 +1,4 @@
|
|||||||
-- use for engine development tests
|
-- use for engine development tests
|
||||||
-- must be empty in release
|
-- must be empty in release
|
||||||
-- must not be modified by content-packs
|
-- must not be modified by content-packs
|
||||||
|
print(generation.load_structure("core:generators/default.files/tree0.vox"))
|
||||||
|
|||||||
@ -158,7 +158,7 @@ static int l_file_write_bytes(lua::State* L) {
|
|||||||
|
|
||||||
fs::path path = resolve_path(lua::require_string(L, pathIndex));
|
fs::path path = resolve_path(lua::require_string(L, pathIndex));
|
||||||
|
|
||||||
if (auto bytearray = lua::touserdata<lua::Bytearray>(L, -1)) {
|
if (auto bytearray = lua::touserdata<lua::LuaBytearray>(L, -1)) {
|
||||||
auto& bytes = bytearray->data();
|
auto& bytes = bytearray->data();
|
||||||
return lua::pushboolean(
|
return lua::pushboolean(
|
||||||
L, files::write_bytes(path, bytes.data(), bytes.size())
|
L, files::write_bytes(path, bytes.data(), bytes.size())
|
||||||
|
|||||||
@ -5,6 +5,8 @@
|
|||||||
#include "coders/binary_json.hpp"
|
#include "coders/binary_json.hpp"
|
||||||
#include "world/Level.hpp"
|
#include "world/Level.hpp"
|
||||||
#include "world/generator/VoxelStructure.hpp"
|
#include "world/generator/VoxelStructure.hpp"
|
||||||
|
#include "engine.hpp"
|
||||||
|
#include "lua_custom_types.hpp"
|
||||||
|
|
||||||
using namespace scripting;
|
using namespace scripting;
|
||||||
|
|
||||||
@ -25,6 +27,21 @@ static int l_save_structure(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_load_structure(lua::State* L) {
|
||||||
|
auto paths = engine->getPaths();
|
||||||
|
auto filename = lua::require_string(L, 1);
|
||||||
|
auto path = paths->resolve(filename);
|
||||||
|
if (!std::filesystem::exists(path)) {
|
||||||
|
throw std::runtime_error("file "+path.u8string()+" does not exist");
|
||||||
|
}
|
||||||
|
auto map = files::read_binary_json(path);
|
||||||
|
|
||||||
|
auto structure = std::make_shared<VoxelStructure>();
|
||||||
|
structure->deserialize(map);
|
||||||
|
return lua::newuserdata<lua::LuaVoxelStructure>(L, std::move(structure));
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg generationlib[] = {
|
const luaL_Reg generationlib[] = {
|
||||||
{"save_structure", lua::wrap<l_save_structure>},
|
{"save_structure", lua::wrap<l_save_structure>},
|
||||||
|
{"load_structure", lua::wrap<l_load_structure>},
|
||||||
{NULL, NULL}};
|
{NULL, NULL}};
|
||||||
|
|||||||
@ -4,9 +4,10 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "lua_commons.hpp"
|
#include "lua_commons.hpp"
|
||||||
#include "maths/Heightmap.hpp"
|
|
||||||
|
|
||||||
struct fnl_state;
|
struct fnl_state;
|
||||||
|
class Heightmap;
|
||||||
|
class VoxelStructure;
|
||||||
|
|
||||||
namespace lua {
|
namespace lua {
|
||||||
class Userdata {
|
class Userdata {
|
||||||
@ -15,12 +16,12 @@ namespace lua {
|
|||||||
virtual const std::string& getTypeName() const = 0;
|
virtual const std::string& getTypeName() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Bytearray : public Userdata {
|
class LuaBytearray : public Userdata {
|
||||||
std::vector<ubyte> buffer;
|
std::vector<ubyte> buffer;
|
||||||
public:
|
public:
|
||||||
Bytearray(size_t capacity);
|
LuaBytearray(size_t capacity);
|
||||||
Bytearray(std::vector<ubyte> buffer);
|
LuaBytearray(std::vector<ubyte> buffer);
|
||||||
virtual ~Bytearray();
|
virtual ~LuaBytearray();
|
||||||
|
|
||||||
const std::string& getTypeName() const override {
|
const std::string& getTypeName() const override {
|
||||||
return TYPENAME;
|
return TYPENAME;
|
||||||
@ -32,6 +33,7 @@ namespace lua {
|
|||||||
static int createMetatable(lua::State*);
|
static int createMetatable(lua::State*);
|
||||||
inline static std::string TYPENAME = "Bytearray";
|
inline static std::string TYPENAME = "Bytearray";
|
||||||
};
|
};
|
||||||
|
static_assert(!std::is_abstract<LuaBytearray>());
|
||||||
|
|
||||||
class LuaHeightmap : public Userdata {
|
class LuaHeightmap : public Userdata {
|
||||||
std::shared_ptr<Heightmap> map;
|
std::shared_ptr<Heightmap> map;
|
||||||
@ -41,21 +43,13 @@ namespace lua {
|
|||||||
|
|
||||||
virtual ~LuaHeightmap();
|
virtual ~LuaHeightmap();
|
||||||
|
|
||||||
uint getWidth() const {
|
uint getWidth() const;
|
||||||
return map->getWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint getHeight() const {
|
uint getHeight() const;
|
||||||
return map->getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
float* getValues() {
|
float* getValues();
|
||||||
return map->getValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
const float* getValues() const {
|
const float* getValues() const;
|
||||||
return map->getValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& getTypeName() const override {
|
const std::string& getTypeName() const override {
|
||||||
return TYPENAME;
|
return TYPENAME;
|
||||||
@ -74,4 +68,25 @@ namespace lua {
|
|||||||
static int createMetatable(lua::State*);
|
static int createMetatable(lua::State*);
|
||||||
inline static std::string TYPENAME = "Heightmap";
|
inline static std::string TYPENAME = "Heightmap";
|
||||||
};
|
};
|
||||||
|
static_assert(!std::is_abstract<LuaHeightmap>());
|
||||||
|
|
||||||
|
class LuaVoxelStructure : public Userdata {
|
||||||
|
std::shared_ptr<VoxelStructure> structure;
|
||||||
|
public:
|
||||||
|
LuaVoxelStructure(std::shared_ptr<VoxelStructure> structure);
|
||||||
|
|
||||||
|
virtual ~LuaVoxelStructure();
|
||||||
|
|
||||||
|
std::shared_ptr<VoxelStructure> getStructure() const {
|
||||||
|
return structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& getTypeName() const override {
|
||||||
|
return TYPENAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int createMetatable(lua::State*);
|
||||||
|
inline static std::string TYPENAME = "VoxelStructure";
|
||||||
|
};
|
||||||
|
static_assert(!std::is_abstract<LuaVoxelStructure>());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -96,8 +96,9 @@ void lua::initialize() {
|
|||||||
|
|
||||||
initialize_libs_extends(L);
|
initialize_libs_extends(L);
|
||||||
|
|
||||||
newusertype<Bytearray, Bytearray::createMetatable>(L, "Bytearray");
|
newusertype<LuaBytearray>(L);
|
||||||
newusertype<LuaHeightmap, LuaHeightmap::createMetatable>(L, "Heightmap");
|
newusertype<LuaHeightmap>(L);
|
||||||
|
newusertype<LuaVoxelStructure>(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua::finalize() {
|
void lua::finalize() {
|
||||||
|
|||||||
@ -248,10 +248,12 @@ namespace lua {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T, lua_CFunction func>
|
template <class T>
|
||||||
inline void newusertype(lua::State* L, const std::string& name) {
|
inline std::enable_if_t<std::is_base_of_v<Userdata, T>>
|
||||||
|
newusertype(lua::State* L) {
|
||||||
|
const std::string& name = T::TYPENAME;
|
||||||
usertypeNames[typeid(T)] = name;
|
usertypeNames[typeid(T)] = name;
|
||||||
func(L);
|
T::createMetatable(L);
|
||||||
|
|
||||||
pushcfunction(L, userdata_destructor);
|
pushcfunction(L, userdata_destructor);
|
||||||
setfield(L, "__gc");
|
setfield(L, "__gc");
|
||||||
|
|||||||
@ -1,23 +1,23 @@
|
|||||||
#include "lua_custom_types.hpp"
|
#include "../lua_custom_types.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "lua_util.hpp"
|
#include "../lua_util.hpp"
|
||||||
|
|
||||||
using namespace lua;
|
using namespace lua;
|
||||||
|
|
||||||
Bytearray::Bytearray(size_t capacity) : buffer(capacity) {
|
LuaBytearray::LuaBytearray(size_t capacity) : buffer(capacity) {
|
||||||
buffer.resize(capacity);
|
buffer.resize(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bytearray::Bytearray(std::vector<ubyte> buffer) : buffer(std::move(buffer)) {
|
LuaBytearray::LuaBytearray(std::vector<ubyte> buffer) : buffer(std::move(buffer)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Bytearray::~Bytearray() {
|
LuaBytearray::~LuaBytearray() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_append(lua::State* L) {
|
static int l_append(lua::State* L) {
|
||||||
if (auto buffer = touserdata<Bytearray>(L, 1)) {
|
if (auto buffer = touserdata<LuaBytearray>(L, 1)) {
|
||||||
auto value = tointeger(L, 2);
|
auto value = tointeger(L, 2);
|
||||||
buffer->data().push_back(static_cast<ubyte>(value));
|
buffer->data().push_back(static_cast<ubyte>(value));
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ static int l_append(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_insert(lua::State* L) {
|
static int l_insert(lua::State* L) {
|
||||||
auto buffer = touserdata<Bytearray>(L, 1);
|
auto buffer = touserdata<LuaBytearray>(L, 1);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ static int l_insert(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_remove(lua::State* L) {
|
static int l_remove(lua::State* L) {
|
||||||
auto buffer = touserdata<Bytearray>(L, 1);
|
auto buffer = touserdata<LuaBytearray>(L, 1);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -69,17 +69,17 @@ static int l_meta_meta_call(lua::State* L) {
|
|||||||
buffer[i] = static_cast<ubyte>(tointeger(L, -1));
|
buffer[i] = static_cast<ubyte>(tointeger(L, -1));
|
||||||
pop(L);
|
pop(L);
|
||||||
}
|
}
|
||||||
return newuserdata<Bytearray>(L, std::move(buffer));
|
return newuserdata<LuaBytearray>(L, std::move(buffer));
|
||||||
}
|
}
|
||||||
auto size = tointeger(L, 2);
|
auto size = tointeger(L, 2);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
throw std::runtime_error("size can not be less than 0");
|
throw std::runtime_error("size can not be less than 0");
|
||||||
}
|
}
|
||||||
return newuserdata<Bytearray>(L, static_cast<size_t>(size));
|
return newuserdata<LuaBytearray>(L, static_cast<size_t>(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_meta_index(lua::State* L) {
|
static int l_meta_index(lua::State* L) {
|
||||||
auto buffer = touserdata<Bytearray>(L, 1);
|
auto buffer = touserdata<LuaBytearray>(L, 1);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ static int l_meta_index(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_meta_newindex(lua::State* L) {
|
static int l_meta_newindex(lua::State* L) {
|
||||||
auto buffer = touserdata<Bytearray>(L, 1);
|
auto buffer = touserdata<LuaBytearray>(L, 1);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -116,14 +116,14 @@ static int l_meta_newindex(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_meta_len(lua::State* L) {
|
static int l_meta_len(lua::State* L) {
|
||||||
if (auto buffer = touserdata<Bytearray>(L, 1)) {
|
if (auto buffer = touserdata<LuaBytearray>(L, 1)) {
|
||||||
return pushinteger(L, buffer->data().size());
|
return pushinteger(L, buffer->data().size());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int l_meta_tostring(lua::State* L) {
|
static int l_meta_tostring(lua::State* L) {
|
||||||
auto buffer = touserdata<Bytearray>(L, 1);
|
auto buffer = touserdata<LuaBytearray>(L, 1);
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -147,8 +147,8 @@ static int l_meta_tostring(lua::State* L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int l_meta_add(lua::State* L) {
|
static int l_meta_add(lua::State* L) {
|
||||||
auto bufferA = touserdata<Bytearray>(L, 1);
|
auto bufferA = touserdata<LuaBytearray>(L, 1);
|
||||||
auto bufferB = touserdata<Bytearray>(L, 2);
|
auto bufferB = touserdata<LuaBytearray>(L, 2);
|
||||||
if (bufferA == nullptr || bufferB == nullptr) {
|
if (bufferA == nullptr || bufferB == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -159,10 +159,10 @@ static int l_meta_add(lua::State* L) {
|
|||||||
ab.reserve(dataA.size() + dataB.size());
|
ab.reserve(dataA.size() + dataB.size());
|
||||||
ab.insert(ab.end(), dataA.begin(), dataA.end());
|
ab.insert(ab.end(), dataA.begin(), dataA.end());
|
||||||
ab.insert(ab.end(), dataB.begin(), dataB.end());
|
ab.insert(ab.end(), dataB.begin(), dataB.end());
|
||||||
return newuserdata<Bytearray>(L, std::move(ab));
|
return newuserdata<LuaBytearray>(L, std::move(ab));
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bytearray::createMetatable(lua::State* L) {
|
int LuaBytearray::createMetatable(lua::State* L) {
|
||||||
createtable(L, 0, 6);
|
createtable(L, 0, 6);
|
||||||
pushcfunction(L, lua::wrap<l_meta_index>);
|
pushcfunction(L, lua::wrap<l_meta_index>);
|
||||||
setfield(L, "__index");
|
setfield(L, "__index");
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "lua_custom_types.hpp"
|
#include "../lua_custom_types.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -11,7 +11,8 @@
|
|||||||
#include "coders/png.hpp"
|
#include "coders/png.hpp"
|
||||||
#include "files/util.hpp"
|
#include "files/util.hpp"
|
||||||
#include "graphics/core/ImageData.hpp"
|
#include "graphics/core/ImageData.hpp"
|
||||||
#include "lua_util.hpp"
|
#include "maths/Heightmap.hpp"
|
||||||
|
#include "../lua_util.hpp"
|
||||||
|
|
||||||
using namespace lua;
|
using namespace lua;
|
||||||
|
|
||||||
@ -27,6 +28,22 @@ void LuaHeightmap::setSeed(int64_t seed) {
|
|||||||
noise->seed = seed;
|
noise->seed = seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint LuaHeightmap::getWidth() const {
|
||||||
|
return map->getWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint LuaHeightmap::getHeight() const {
|
||||||
|
return map->getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
float* LuaHeightmap::getValues() {
|
||||||
|
return map->getValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
const float* LuaHeightmap::getValues() const {
|
||||||
|
return map->getValues();
|
||||||
|
}
|
||||||
|
|
||||||
static int l_dump(lua::State* L) {
|
static int l_dump(lua::State* L) {
|
||||||
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
|
if (auto heightmap = touserdata<LuaHeightmap>(L, 1)) {
|
||||||
auto filename = require_string(L, 2);
|
auto filename = require_string(L, 2);
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
#include "../lua_custom_types.hpp"
|
||||||
|
|
||||||
|
#include "../lua_util.hpp"
|
||||||
|
|
||||||
|
#include "world/generator/VoxelStructure.hpp"
|
||||||
|
#include "util/stringutil.hpp"
|
||||||
|
|
||||||
|
using namespace lua;
|
||||||
|
|
||||||
|
LuaVoxelStructure::LuaVoxelStructure(std::shared_ptr<VoxelStructure> structure)
|
||||||
|
: structure(std::move(structure)) {}
|
||||||
|
|
||||||
|
LuaVoxelStructure::~LuaVoxelStructure() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_meta_tostring(lua::State* L) {
|
||||||
|
return pushstring(L, "VoxelStructure(0x" + util::tohex(
|
||||||
|
reinterpret_cast<uint64_t>(topointer(L, 1)))+")");
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaVoxelStructure::createMetatable(lua::State* L) {
|
||||||
|
createtable(L, 0, 1);
|
||||||
|
pushcfunction(L, lua::wrap<l_meta_tostring>);
|
||||||
|
setfield(L, "__tostring");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
#include "maths/Heightmap.hpp"
|
||||||
|
|
||||||
enum class InterpolationType {
|
enum class InterpolationType {
|
||||||
NEAREST,
|
NEAREST,
|
||||||
|
|||||||
@ -312,13 +312,17 @@ std::string util::base64_encode(const ubyte* data, size_t size) {
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string util::mangleid(uint64_t value) {
|
std::string util::tohex(uint64_t value) {
|
||||||
// todo: use base64
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::hex << value;
|
ss << std::hex << value;
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string util::mangleid(uint64_t value) {
|
||||||
|
// todo: use base64
|
||||||
|
return tohex(value);
|
||||||
|
}
|
||||||
|
|
||||||
util::Buffer<ubyte> util::base64_decode(const char* str, size_t size) {
|
util::Buffer<ubyte> util::base64_decode(const char* str, size_t size) {
|
||||||
util::Buffer<ubyte> bytes((size / 4) * 3);
|
util::Buffer<ubyte> bytes((size / 4) * 3);
|
||||||
ubyte* dst = bytes.data();
|
ubyte* dst = bytes.data();
|
||||||
|
|||||||
@ -60,6 +60,8 @@ namespace util {
|
|||||||
util::Buffer<ubyte> base64_decode(const char* str, size_t size);
|
util::Buffer<ubyte> base64_decode(const char* str, size_t size);
|
||||||
util::Buffer<ubyte> base64_decode(const std::string& str);
|
util::Buffer<ubyte> base64_decode(const std::string& str);
|
||||||
|
|
||||||
|
std::string tohex(uint64_t value);
|
||||||
|
|
||||||
std::string mangleid(uint64_t value);
|
std::string mangleid(uint64_t value);
|
||||||
|
|
||||||
int replaceAll(
|
int replaceAll(
|
||||||
|
|||||||
@ -66,11 +66,23 @@ dv::value VoxelStructure::serialize() const {
|
|||||||
void VoxelStructure::deserialize(const dv::value& src) {
|
void VoxelStructure::deserialize(const dv::value& src) {
|
||||||
size = glm::ivec3();
|
size = glm::ivec3();
|
||||||
dv::get_vec(src, "size", size);
|
dv::get_vec(src, "size", size);
|
||||||
voxels.resize(size.x*size.y*size.z);
|
|
||||||
|
auto volume = size.x*size.y*size.z;
|
||||||
|
voxels.resize(volume);
|
||||||
|
|
||||||
const auto& voxelsArr = src["voxels"];
|
const auto& voxelsArr = src["voxels"];
|
||||||
for (size_t i = 0; i < size.x*size.y*size.z; i++) {
|
for (size_t i = 0; i < volume; i++) {
|
||||||
voxels[i].id = voxelsArr[i * 2].asInteger();
|
voxels[i].id = voxelsArr[i * 2].asInteger();
|
||||||
voxels[i].state = int2blockstate(voxelsArr[i * 2 + 1].asInteger());
|
voxels[i].state = int2blockstate(voxelsArr[i * 2 + 1].asInteger());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelStructure::prepare(const Content& content) {
|
||||||
|
auto volume = size.x*size.y*size.z;
|
||||||
|
voxelsRuntime.resize(volume);
|
||||||
|
for (size_t i = 0; i < volume; i++) {
|
||||||
|
const auto& name = blockNames[voxels[i].id];
|
||||||
|
voxelsRuntime[i].id = content.blocks.require(name).rt.id;
|
||||||
|
voxelsRuntime[i].state = voxels[i].state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ inline constexpr int STRUCTURE_FORMAT_VERSION = 1;
|
|||||||
class Level;
|
class Level;
|
||||||
class Content;
|
class Content;
|
||||||
|
|
||||||
struct VoxelStructure : public Serializable {
|
class VoxelStructure : public Serializable {
|
||||||
glm::ivec3 size;
|
glm::ivec3 size;
|
||||||
|
|
||||||
/// @brief Structure voxels indexed different to world content
|
/// @brief Structure voxels indexed different to world content
|
||||||
@ -19,6 +19,9 @@ struct VoxelStructure : public Serializable {
|
|||||||
/// @brief Block names are used for indexing
|
/// @brief Block names are used for indexing
|
||||||
std::vector<std::string> blockNames;
|
std::vector<std::string> blockNames;
|
||||||
|
|
||||||
|
/// @brief Structure voxels built on prepare(...) call
|
||||||
|
std::vector<voxel> voxelsRuntime;
|
||||||
|
public:
|
||||||
VoxelStructure() : size() {}
|
VoxelStructure() : size() {}
|
||||||
|
|
||||||
VoxelStructure(
|
VoxelStructure(
|
||||||
@ -33,6 +36,18 @@ struct VoxelStructure : public Serializable {
|
|||||||
dv::value serialize() const override;
|
dv::value serialize() const override;
|
||||||
void deserialize(const dv::value& src) override;
|
void deserialize(const dv::value& src) override;
|
||||||
|
|
||||||
|
/// @brief Build runtime voxel indices
|
||||||
|
/// @param content world content
|
||||||
|
void prepare(const Content& content);
|
||||||
|
|
||||||
static std::unique_ptr<VoxelStructure> create(
|
static std::unique_ptr<VoxelStructure> create(
|
||||||
Level* level, const glm::ivec3& a, const glm::ivec3& b, bool entities);
|
Level* level, const glm::ivec3& a, const glm::ivec3& b, bool entities);
|
||||||
|
|
||||||
|
const glm::ivec3& getSize() const {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<voxel>& getRuntimeVoxels() {
|
||||||
|
return voxelsRuntime;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,7 +7,8 @@
|
|||||||
#include "content/Content.hpp"
|
#include "content/Content.hpp"
|
||||||
#include "voxels/Block.hpp"
|
#include "voxels/Block.hpp"
|
||||||
#include "voxels/Chunk.hpp"
|
#include "voxels/Chunk.hpp"
|
||||||
#include "world/generator/GeneratorDef.hpp"
|
#include "GeneratorDef.hpp"
|
||||||
|
#include "VoxelStructure.hpp"
|
||||||
#include "util/timeutil.hpp"
|
#include "util/timeutil.hpp"
|
||||||
#include "debug/Logger.hpp"
|
#include "debug/Logger.hpp"
|
||||||
|
|
||||||
@ -47,6 +48,8 @@ WorldGenerator::WorldGenerator(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WorldGenerator::~WorldGenerator() {}
|
||||||
|
|
||||||
static inline void generate_pole(
|
static inline void generate_pole(
|
||||||
const BlocksLayers& layers,
|
const BlocksLayers& layers,
|
||||||
int top, int bottom,
|
int top, int bottom,
|
||||||
@ -119,8 +122,8 @@ std::unique_ptr<ChunkPrototype> WorldGenerator::generatePrototype(
|
|||||||
}
|
}
|
||||||
return std::make_unique<ChunkPrototype>(
|
return std::make_unique<ChunkPrototype>(
|
||||||
ChunkPrototypeLevel::BIOMES,
|
ChunkPrototypeLevel::BIOMES,
|
||||||
nullptr,
|
std::move(chunkBiomes),
|
||||||
std::move(chunkBiomes));
|
nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldGenerator::generateHeightmap(
|
void WorldGenerator::generateHeightmap(
|
||||||
|
|||||||
@ -14,6 +14,7 @@ class Content;
|
|||||||
struct GeneratorDef;
|
struct GeneratorDef;
|
||||||
class Heightmap;
|
class Heightmap;
|
||||||
struct Biome;
|
struct Biome;
|
||||||
|
class VoxelStructure;
|
||||||
|
|
||||||
enum class ChunkPrototypeLevel {
|
enum class ChunkPrototypeLevel {
|
||||||
BIOMES, HEIGHTMAP
|
BIOMES, HEIGHTMAP
|
||||||
@ -22,18 +23,19 @@ enum class ChunkPrototypeLevel {
|
|||||||
struct ChunkPrototype {
|
struct ChunkPrototype {
|
||||||
ChunkPrototypeLevel level;
|
ChunkPrototypeLevel level;
|
||||||
|
|
||||||
/// @brief chunk heightmap
|
|
||||||
std::shared_ptr<Heightmap> heightmap;
|
|
||||||
/// @brief chunk biomes matrix
|
/// @brief chunk biomes matrix
|
||||||
std::vector<const Biome*> biomes;
|
std::vector<const Biome*> biomes;
|
||||||
|
|
||||||
|
/// @brief chunk heightmap
|
||||||
|
std::shared_ptr<Heightmap> heightmap;
|
||||||
|
|
||||||
ChunkPrototype(
|
ChunkPrototype(
|
||||||
ChunkPrototypeLevel level,
|
ChunkPrototypeLevel level,
|
||||||
std::shared_ptr<Heightmap> heightmap,
|
std::vector<const Biome*> biomes,
|
||||||
std::vector<const Biome*> biomes
|
std::shared_ptr<Heightmap> heightmap
|
||||||
) : level(level),
|
) : level(level),
|
||||||
heightmap(std::move(heightmap)),
|
biomes(std::move(biomes)),
|
||||||
biomes(std::move(biomes)) {};
|
heightmap(std::move(heightmap)) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief High-level world generation controller
|
/// @brief High-level world generation controller
|
||||||
@ -49,6 +51,8 @@ class WorldGenerator {
|
|||||||
/// @brief Chunk prototypes loading surround map
|
/// @brief Chunk prototypes loading surround map
|
||||||
SurroundMap surroundMap;
|
SurroundMap surroundMap;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<VoxelStructure>> structures;
|
||||||
|
|
||||||
/// @brief Generate chunk prototype (see ChunkPrototype)
|
/// @brief Generate chunk prototype (see ChunkPrototype)
|
||||||
/// @param x chunk position X divided by CHUNK_W
|
/// @param x chunk position X divided by CHUNK_W
|
||||||
/// @param z chunk position Y divided by CHUNK_D
|
/// @param z chunk position Y divided by CHUNK_D
|
||||||
@ -61,15 +65,15 @@ public:
|
|||||||
const Content* content,
|
const Content* content,
|
||||||
uint64_t seed
|
uint64_t seed
|
||||||
);
|
);
|
||||||
virtual ~WorldGenerator() = default;
|
~WorldGenerator();
|
||||||
|
|
||||||
virtual void update(int centerX, int centerY, int loadDistance);
|
void update(int centerX, int centerY, int loadDistance);
|
||||||
|
|
||||||
/// @brief Generate complete chunk voxels
|
/// @brief Generate complete chunk voxels
|
||||||
/// @param voxels destinatiopn chunk voxels buffer
|
/// @param voxels destinatiopn chunk voxels buffer
|
||||||
/// @param x chunk position X divided by CHUNK_W
|
/// @param x chunk position X divided by CHUNK_W
|
||||||
/// @param z chunk position Y divided by CHUNK_D
|
/// @param z chunk position Y divided by CHUNK_D
|
||||||
virtual void generate(voxel* voxels, int x, int z);
|
void generate(voxel* voxels, int x, int z);
|
||||||
|
|
||||||
inline static std::string DEFAULT = "core:default";
|
inline static std::string DEFAULT = "core:default";
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user