Voxel changed from 16 bit to 32 bit + new lua functions
This commit is contained in:
parent
460b08a006
commit
06f66ffd71
@ -11,6 +11,9 @@ const int CHUNK_W = 16;
|
|||||||
const int CHUNK_H = 256;
|
const int CHUNK_H = 256;
|
||||||
const int CHUNK_D = 16;
|
const int CHUNK_D = 16;
|
||||||
|
|
||||||
|
const uint VOXEL_USER_BITS = 8;
|
||||||
|
constexpr uint VOXEL_USER_BITS_OFFSET = sizeof(blockstate_t)*8-VOXEL_USER_BITS;
|
||||||
|
|
||||||
/* Chunk volume (count of voxels per Chunk) */
|
/* Chunk volume (count of voxels per Chunk) */
|
||||||
constexpr int CHUNK_VOL = (CHUNK_W * CHUNK_H * CHUNK_D);
|
constexpr int CHUNK_VOL = (CHUNK_W * CHUNK_H * CHUNK_D);
|
||||||
|
|
||||||
|
|||||||
@ -8,18 +8,15 @@
|
|||||||
#include "../content/ContentLUT.h"
|
#include "../content/ContentLUT.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
using std::string;
|
|
||||||
using std::unique_ptr;
|
|
||||||
using fs::path;
|
|
||||||
|
|
||||||
WorldConverter::WorldConverter(path folder,
|
WorldConverter::WorldConverter(fs::path folder,
|
||||||
const Content* content,
|
const Content* content,
|
||||||
const ContentLUT* lut)
|
const ContentLUT* lut)
|
||||||
: lut(lut), content(content) {
|
: lut(lut), content(content) {
|
||||||
DebugSettings settings;
|
DebugSettings settings;
|
||||||
wfile = new WorldFiles(folder, settings);
|
wfile = new WorldFiles(folder, settings);
|
||||||
|
|
||||||
path regionsFolder = wfile->getRegionsFolder();
|
fs::path regionsFolder = wfile->getRegionsFolder();
|
||||||
if (!fs::is_directory(regionsFolder)) {
|
if (!fs::is_directory(regionsFolder)) {
|
||||||
std::cerr << "nothing to convert" << std::endl;
|
std::cerr << "nothing to convert" << std::endl;
|
||||||
return;
|
return;
|
||||||
@ -41,13 +38,13 @@ void WorldConverter::convertNext() {
|
|||||||
if (!hasNext()) {
|
if (!hasNext()) {
|
||||||
throw std::runtime_error("no more regions to convert");
|
throw std::runtime_error("no more regions to convert");
|
||||||
}
|
}
|
||||||
path regfile = regions.front();
|
fs::path regfile = regions.front();
|
||||||
regions.pop();
|
regions.pop();
|
||||||
if (!fs::is_regular_file(regfile))
|
if (!fs::is_regular_file(regfile))
|
||||||
return;
|
return;
|
||||||
int x, y;
|
int x, z;
|
||||||
string name = regfile.stem().string();
|
std::string name = regfile.stem().string();
|
||||||
if (!WorldFiles::parseRegionFilename(name, x, y)) {
|
if (!WorldFiles::parseRegionFilename(name, x, z)) {
|
||||||
std::cerr << "could not parse name " << name << std::endl;
|
std::cerr << "could not parse name " << name << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -55,11 +52,16 @@ void WorldConverter::convertNext() {
|
|||||||
for (uint cz = 0; cz < REGION_SIZE; cz++) {
|
for (uint cz = 0; cz < REGION_SIZE; cz++) {
|
||||||
for (uint cx = 0; cx < REGION_SIZE; cx++) {
|
for (uint cx = 0; cx < REGION_SIZE; cx++) {
|
||||||
int gx = cx + x * REGION_SIZE;
|
int gx = cx + x * REGION_SIZE;
|
||||||
int gz = cz + y * REGION_SIZE;
|
int gz = cz + z * REGION_SIZE;
|
||||||
unique_ptr<ubyte[]> data (wfile->getChunk(gx, gz));
|
std::unique_ptr<ubyte[]> data (wfile->getChunk(gx, gz));
|
||||||
if (data == nullptr)
|
if (data == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
if (wfile->getVoxelRegionVersion(x, z) != REGION_FORMAT_VERSION) {
|
||||||
|
Chunk::fromOld(data.get());
|
||||||
|
}
|
||||||
|
if (lut) {
|
||||||
Chunk::convert(data.get(), lut);
|
Chunk::convert(data.get(), lut);
|
||||||
|
}
|
||||||
wfile->put(gx, gz, data.get());
|
wfile->put(gx, gz, data.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,8 +38,8 @@ regfile::regfile(fs::path filename) : file(filename) {
|
|||||||
throw std::runtime_error("invalid region file magic number");
|
throw std::runtime_error("invalid region file magic number");
|
||||||
}
|
}
|
||||||
version = header[8];
|
version = header[8];
|
||||||
if (version > 2) {
|
if (version > REGION_FORMAT_VERSION) {
|
||||||
throw std::runtime_error(
|
throw illegal_region_format(
|
||||||
"region format "+std::to_string(version)+" is not supported");
|
"region format "+std::to_string(version)+" is not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,6 +130,31 @@ ubyte* WorldFiles::decompress(const ubyte* src, size_t srclen, size_t dstlen) {
|
|||||||
return decompressed;
|
return decompressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WorldFiles::getVoxelRegionVersion(int x, int z) {
|
||||||
|
regfile* rf = getRegFile(glm::ivec3(x, z, REGION_LAYER_VOXELS), getRegionsFolder());
|
||||||
|
if (rf == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return rf->version;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WorldFiles::getVoxelRegionsVersion() {
|
||||||
|
fs::path regionsFolder = getRegionsFolder();
|
||||||
|
if (!fs::is_directory(regionsFolder)) {
|
||||||
|
return REGION_FORMAT_VERSION;
|
||||||
|
}
|
||||||
|
for (auto file : fs::directory_iterator(regionsFolder)) {
|
||||||
|
int x;
|
||||||
|
int z;
|
||||||
|
if (!parseRegionFilename(file.path().stem().string(), x, z)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
regfile* rf = getRegFile(glm::ivec3(x, z, REGION_LAYER_VOXELS), regionsFolder);
|
||||||
|
return rf->version;
|
||||||
|
}
|
||||||
|
return REGION_FORMAT_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compress and store chunk voxels data in region
|
* Compress and store chunk voxels data in region
|
||||||
* @param x chunk.x
|
* @param x chunk.x
|
||||||
@ -190,8 +215,7 @@ fs::path WorldFiles::getLightsFolder() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs::path WorldFiles::getRegionFilename(int x, int z) const {
|
fs::path WorldFiles::getRegionFilename(int x, int z) const {
|
||||||
std::string filename = std::to_string(x) + "_" + std::to_string(z) + ".bin";
|
return fs::path(std::to_string(x) + "_" + std::to_string(z) + ".bin");
|
||||||
return fs::path(filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -254,7 +278,6 @@ ubyte* WorldFiles::getData(regionsmap& regions, const fs::path& folder,
|
|||||||
int localZ = z - (regionZ * REGION_SIZE);
|
int localZ = z - (regionZ * REGION_SIZE);
|
||||||
|
|
||||||
WorldRegion* region = getOrCreateRegion(regions, regionX, regionZ);
|
WorldRegion* region = getOrCreateRegion(regions, regionX, regionZ);
|
||||||
|
|
||||||
ubyte* data = region->getChunkData(localX, localZ);
|
ubyte* data = region->getChunkData(localX, localZ);
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|||||||
@ -34,6 +34,12 @@ class Content;
|
|||||||
class ContentIndices;
|
class ContentIndices;
|
||||||
class World;
|
class World;
|
||||||
|
|
||||||
|
class illegal_region_format : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
illegal_region_format(const std::string& message)
|
||||||
|
: std::runtime_error(message) {}
|
||||||
|
};
|
||||||
|
|
||||||
class WorldRegion {
|
class WorldRegion {
|
||||||
ubyte** chunksData;
|
ubyte** chunksData;
|
||||||
uint32_t* sizes;
|
uint32_t* sizes;
|
||||||
@ -125,6 +131,9 @@ public:
|
|||||||
void put(Chunk* chunk);
|
void put(Chunk* chunk);
|
||||||
void put(int x, int z, const ubyte* voxelData);
|
void put(int x, int z, const ubyte* voxelData);
|
||||||
|
|
||||||
|
int getVoxelRegionVersion(int x, int z);
|
||||||
|
int getVoxelRegionsVersion();
|
||||||
|
|
||||||
ubyte* getChunk(int x, int z);
|
ubyte* getChunk(int x, int z);
|
||||||
light_t* getLights(int x, int z);
|
light_t* getLights(int x, int z);
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,9 @@
|
|||||||
#include "../util/stringutil.h"
|
#include "../util/stringutil.h"
|
||||||
#include "../files/engine_paths.h"
|
#include "../files/engine_paths.h"
|
||||||
#include "../files/WorldConverter.h"
|
#include "../files/WorldConverter.h"
|
||||||
|
#include "../files/WorldFiles.h"
|
||||||
#include "../world/World.h"
|
#include "../world/World.h"
|
||||||
|
#include "../world/Level.h"
|
||||||
#include "../window/Events.h"
|
#include "../window/Events.h"
|
||||||
#include "../window/Window.h"
|
#include "../window/Window.h"
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
@ -174,10 +176,20 @@ void open_world(std::string name, Engine* engine) {
|
|||||||
} else {
|
} else {
|
||||||
show_convert_request(engine, content, lut, folder);
|
show_convert_request(engine, content, lut, folder);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: remove in 0.18
|
||||||
|
int version;
|
||||||
|
{
|
||||||
|
WorldFiles wfile(folder, settings.debug);
|
||||||
|
version = wfile.getVoxelRegionsVersion();
|
||||||
|
}
|
||||||
|
if (version != REGION_FORMAT_VERSION) {
|
||||||
|
show_convert_request(engine, content, lut, folder);
|
||||||
} else {
|
} else {
|
||||||
Level* level = World::load(folder, settings, content, packs);
|
Level* level = World::load(folder, settings, content, packs);
|
||||||
engine->setScreen(std::make_shared<LevelScreen>(engine, level));
|
engine->setScreen(std::make_shared<LevelScreen>(engine, level));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Panel* create_worlds_panel(Engine* engine) {
|
Panel* create_worlds_panel(Engine* engine) {
|
||||||
|
|||||||
@ -59,6 +59,64 @@ int l_get_block(lua_State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int lua_pushivec3(lua_State* L, int x, int y, int z) {
|
||||||
|
lua_pushinteger(L, x);
|
||||||
|
lua_pushinteger(L, y);
|
||||||
|
lua_pushinteger(L, z);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l_get_block_x(lua_State* L) {
|
||||||
|
int x = lua_tointeger(L, 1);
|
||||||
|
int y = lua_tointeger(L, 2);
|
||||||
|
int z = lua_tointeger(L, 3);
|
||||||
|
voxel* vox = scripting::level->chunks->get(x, y, z);
|
||||||
|
if (vox == nullptr) {
|
||||||
|
return lua_pushivec3(L, 1, 0, 0);
|
||||||
|
}
|
||||||
|
const Block* def = scripting::level->content->indices->getBlockDef(vox->id);
|
||||||
|
if (!def->rotatable) {
|
||||||
|
return lua_pushivec3(L, 1, 0, 0);
|
||||||
|
} else {
|
||||||
|
const CoordSystem& rot = def->rotations.variants[vox->rotation()];
|
||||||
|
return lua_pushivec3(L, rot.axisX.x, rot.axisX.y, rot.axisX.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int l_get_block_y(lua_State* L) {
|
||||||
|
int x = lua_tointeger(L, 1);
|
||||||
|
int y = lua_tointeger(L, 2);
|
||||||
|
int z = lua_tointeger(L, 3);
|
||||||
|
voxel* vox = scripting::level->chunks->get(x, y, z);
|
||||||
|
if (vox == nullptr) {
|
||||||
|
return lua_pushivec3(L, 0, 1, 0);
|
||||||
|
}
|
||||||
|
const Block* def = scripting::level->content->indices->getBlockDef(vox->id);
|
||||||
|
if (!def->rotatable) {
|
||||||
|
return lua_pushivec3(L, 0, 1, 0);
|
||||||
|
} else {
|
||||||
|
const CoordSystem& rot = def->rotations.variants[vox->rotation()];
|
||||||
|
return lua_pushivec3(L, rot.axisY.x, rot.axisY.y, rot.axisY.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int l_get_block_z(lua_State* L) {
|
||||||
|
int x = lua_tointeger(L, 1);
|
||||||
|
int y = lua_tointeger(L, 2);
|
||||||
|
int z = lua_tointeger(L, 3);
|
||||||
|
voxel* vox = scripting::level->chunks->get(x, y, z);
|
||||||
|
if (vox == nullptr) {
|
||||||
|
return lua_pushivec3(L, 0, 0, 1);
|
||||||
|
}
|
||||||
|
const Block* def = scripting::level->content->indices->getBlockDef(vox->id);
|
||||||
|
if (!def->rotatable) {
|
||||||
|
return lua_pushivec3(L, 0, 0, 1);
|
||||||
|
} else {
|
||||||
|
const CoordSystem& rot = def->rotations.variants[vox->rotation()];
|
||||||
|
return lua_pushivec3(L, rot.axisZ.x, rot.axisZ.y, rot.axisZ.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int l_get_player_pos(lua_State* L) {
|
int l_get_player_pos(lua_State* L) {
|
||||||
glm::vec3 pos = scripting::level->player->hitbox->position;
|
glm::vec3 pos = scripting::level->player->hitbox->position;
|
||||||
lua_pushnumber(L, pos.x);
|
lua_pushnumber(L, pos.x);
|
||||||
@ -101,6 +159,42 @@ int l_get_block_states(lua_State* L) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int l_get_block_script_states(lua_State* L) {
|
||||||
|
int x = lua_tointeger(L, 1);
|
||||||
|
int y = lua_tointeger(L, 2);
|
||||||
|
int z = lua_tointeger(L, 3);
|
||||||
|
int offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET;
|
||||||
|
int bits = lua_tointeger(L, 5);
|
||||||
|
|
||||||
|
voxel* vox = scripting::level->chunks->get(x, y, z);
|
||||||
|
if (vox == nullptr) {
|
||||||
|
lua_pushinteger(L, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
uint mask = ((1 << bits) - 1) << offset;
|
||||||
|
uint data = (vox->states & mask) >> offset;
|
||||||
|
lua_pushinteger(L, data);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l_set_block_script_states(lua_State* L) {
|
||||||
|
int x = lua_tointeger(L, 1);
|
||||||
|
int y = lua_tointeger(L, 2);
|
||||||
|
int z = lua_tointeger(L, 3);
|
||||||
|
int offset = lua_tointeger(L, 4) + VOXEL_USER_BITS_OFFSET;
|
||||||
|
int bits = lua_tointeger(L, 5);
|
||||||
|
|
||||||
|
uint mask = (1 << bits) - 1;
|
||||||
|
int value = lua_tointeger(L, 6) & mask;
|
||||||
|
|
||||||
|
voxel* vox = scripting::level->chunks->get(x, y, z);
|
||||||
|
if (vox == nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
vox->states = (vox->states & (~mask)) | (value << offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int l_is_replaceable_at(lua_State* L) {
|
int l_is_replaceable_at(lua_State* L) {
|
||||||
int x = lua_tointeger(L, 1);
|
int x = lua_tointeger(L, 1);
|
||||||
int y = lua_tointeger(L, 2);
|
int y = lua_tointeger(L, 2);
|
||||||
@ -121,9 +215,14 @@ void apilua::create_funcs(lua_State* L) {
|
|||||||
lua_addfunc(L, l_is_replaceable_at, "is_replaceable_at");
|
lua_addfunc(L, l_is_replaceable_at, "is_replaceable_at");
|
||||||
lua_addfunc(L, l_set_block, "set_block");
|
lua_addfunc(L, l_set_block, "set_block");
|
||||||
lua_addfunc(L, l_get_block, "get_block");
|
lua_addfunc(L, l_get_block, "get_block");
|
||||||
|
lua_addfunc(L, l_get_block_x, "get_block_X");
|
||||||
|
lua_addfunc(L, l_get_block_y, "get_block_Y");
|
||||||
|
lua_addfunc(L, l_get_block_z, "get_block_Z");
|
||||||
lua_addfunc(L, l_get_player_pos, "get_player_pos");
|
lua_addfunc(L, l_get_player_pos, "get_player_pos");
|
||||||
lua_addfunc(L, l_set_player_pos, "set_player_pos");
|
lua_addfunc(L, l_set_player_pos, "set_player_pos");
|
||||||
lua_addfunc(L, l_get_player_rot, "get_player_rot");
|
lua_addfunc(L, l_get_player_rot, "get_player_rot");
|
||||||
lua_addfunc(L, l_set_player_rot, "set_player_rot");
|
lua_addfunc(L, l_set_player_rot, "set_player_rot");
|
||||||
lua_addfunc(L, l_get_block_states, "get_block_states");
|
lua_addfunc(L, l_get_block_states, "get_block_states");
|
||||||
|
lua_addfunc(L, l_get_block_script_states, "get_block_script_states");
|
||||||
|
lua_addfunc(L, l_set_block_script_states, "set_block_script_states");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,8 +53,14 @@ void scripting::initialize(EnginePaths* paths) {
|
|||||||
if (L == nullptr) {
|
if (L == nullptr) {
|
||||||
throw std::runtime_error("could not to initialize Lua");
|
throw std::runtime_error("could not to initialize Lua");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allowed standard libraries
|
||||||
luaopen_base(L);
|
luaopen_base(L);
|
||||||
luaopen_math(L);
|
luaopen_math(L);
|
||||||
|
luaopen_string(L);
|
||||||
|
luaopen_table(L);
|
||||||
|
|
||||||
|
// io-manipulations will be implemented via api functions
|
||||||
|
|
||||||
std::cout << LUA_VERSION << std::endl;
|
std::cout << LUA_VERSION << std::endl;
|
||||||
# ifdef LUAJIT_VERSION
|
# ifdef LUAJIT_VERSION
|
||||||
|
|||||||
@ -9,8 +9,8 @@ typedef unsigned int uint;
|
|||||||
// use for bytes arrays
|
// use for bytes arrays
|
||||||
typedef uint8_t ubyte;
|
typedef uint8_t ubyte;
|
||||||
|
|
||||||
typedef uint8_t blockid_t;
|
typedef uint16_t blockid_t;
|
||||||
typedef uint8_t blockstate_t;
|
typedef uint16_t blockstate_t;
|
||||||
typedef uint16_t light_t;
|
typedef uint16_t light_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
#include "Chunk.h"
|
#include "Chunk.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "voxel.h"
|
#include "voxel.h"
|
||||||
#include "../content/ContentLUT.h"
|
#include "../content/ContentLUT.h"
|
||||||
#include "../lighting/Lightmap.h"
|
#include "../lighting/Lightmap.h"
|
||||||
@ -22,7 +25,7 @@ Chunk::~Chunk(){
|
|||||||
|
|
||||||
bool Chunk::isEmpty(){
|
bool Chunk::isEmpty(){
|
||||||
int id = -1;
|
int id = -1;
|
||||||
for (int i = 0; i < CHUNK_VOL; i++){
|
for (size_t i = 0; i < CHUNK_VOL; i++){
|
||||||
if (voxels[i].id != id){
|
if (voxels[i].id != id){
|
||||||
if (id != -1)
|
if (id != -1)
|
||||||
return false;
|
return false;
|
||||||
@ -34,14 +37,14 @@ bool Chunk::isEmpty(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::updateHeights() {
|
void Chunk::updateHeights() {
|
||||||
for (int i = 0; i < CHUNK_VOL; i++) {
|
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
||||||
if (voxels[i].id != 0) {
|
if (voxels[i].id != 0) {
|
||||||
bottom = i / (CHUNK_D * CHUNK_W);
|
bottom = i / (CHUNK_D * CHUNK_W);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = CHUNK_VOL - 1; i > -1; i--) {
|
for (int i = CHUNK_VOL - 1; i >= 0; i--) {
|
||||||
if (voxels[i].id != 0) {
|
if (voxels[i].id != 0) {
|
||||||
top = i / (CHUNK_D * CHUNK_W) + 1;
|
top = i / (CHUNK_D * CHUNK_W) + 1;
|
||||||
break;
|
break;
|
||||||
@ -51,7 +54,7 @@ void Chunk::updateHeights() {
|
|||||||
|
|
||||||
Chunk* Chunk::clone() const {
|
Chunk* Chunk::clone() const {
|
||||||
Chunk* other = new Chunk(x,z);
|
Chunk* other = new Chunk(x,z);
|
||||||
for (int i = 0; i < CHUNK_VOL; i++)
|
for (size_t i = 0; i < CHUNK_VOL; i++)
|
||||||
other->voxels[i] = voxels[i];
|
other->voxels[i] = voxels[i];
|
||||||
other->lightmap->set(lightmap);
|
other->lightmap->set(lightmap);
|
||||||
return other;
|
return other;
|
||||||
@ -59,32 +62,67 @@ Chunk* Chunk::clone() const {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Current chunk format:
|
Current chunk format:
|
||||||
[voxel_ids...][voxel_states...];
|
- byte-order: big-endian
|
||||||
|
- [don't panic!] first and second bytes are separated for RLE efficiency
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
uint8_t voxel_id_first_byte[CHUNK_VOL];
|
||||||
|
uint8_t voxel_id_second_byte[CHUNK_VOL];
|
||||||
|
uint8_t voxel_states_first_byte[CHUNK_VOL];
|
||||||
|
uint8_t voxel_states_second_byte[CHUNK_VOL];
|
||||||
|
```
|
||||||
|
|
||||||
|
Total size: (CHUNK_VOL * 4) bytes
|
||||||
*/
|
*/
|
||||||
ubyte* Chunk::encode() const {
|
ubyte* Chunk::encode() const {
|
||||||
ubyte* buffer = new ubyte[CHUNK_DATA_LEN];
|
ubyte* buffer = new ubyte[CHUNK_DATA_LEN];
|
||||||
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
||||||
buffer[i] = voxels[i].id;
|
buffer[i] = voxels[i].id >> 8;
|
||||||
buffer[CHUNK_VOL + i] = voxels[i].states;
|
buffer[CHUNK_VOL+i] = voxels[i].id & 0xFF;
|
||||||
|
buffer[CHUNK_VOL*2 + i] = voxels[i].states >> 8;
|
||||||
|
buffer[CHUNK_VOL*3 + i] = voxels[i].states & 0xFF;
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@return true if all is fine
|
* @return true if all is fine
|
||||||
*/
|
**/
|
||||||
bool Chunk::decode(ubyte* data) {
|
bool Chunk::decode(ubyte* data) {
|
||||||
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
||||||
voxel& vox = voxels[i];
|
voxel& vox = voxels[i];
|
||||||
vox.id = data[i];
|
|
||||||
vox.states = data[CHUNK_VOL + i];
|
ubyte bid1 = data[i];
|
||||||
|
ubyte bid2 = data[CHUNK_VOL + i];
|
||||||
|
|
||||||
|
ubyte bst1 = data[CHUNK_VOL*2 + i];
|
||||||
|
ubyte bst2 = data[CHUNK_VOL*3 + i];
|
||||||
|
|
||||||
|
vox.id = (blockid_t(bid1) << 8) | (blockid_t(bid2));
|
||||||
|
vox.states = (blockstate_t(bst1) << 8) | (blockstate_t(bst2));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::convert(ubyte* data, const ContentLUT* lut) {
|
/*
|
||||||
|
* Convert chunk voxels data from 16 bit to 32 bit
|
||||||
|
*/
|
||||||
|
void Chunk::fromOld(ubyte* data) {
|
||||||
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
||||||
blockid_t id = data[i];
|
data[i + CHUNK_VOL*3] = data[i + CHUNK_VOL];
|
||||||
data[i] = lut->getBlockId(id);
|
data[i + CHUNK_VOL] = data[i];
|
||||||
|
data[i + CHUNK_VOL*2] = 0;
|
||||||
|
data[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chunk::convert(ubyte* data, const ContentLUT* lut) {
|
||||||
|
for (size_t i = 0; i < CHUNK_VOL; i++) {
|
||||||
|
// see encode method to understand what the hell is going on here
|
||||||
|
blockid_t id = ((blockid_t(data[i]) << 8) |
|
||||||
|
blockid_t(data[CHUNK_VOL+i]));
|
||||||
|
blockid_t replacement = lut->getBlockId(id);
|
||||||
|
data[i] = replacement >> 8;
|
||||||
|
data[CHUNK_VOL+i] = replacement & 0xFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ struct ChunkFlag{
|
|||||||
static const int UNSAVED = 0x10;
|
static const int UNSAVED = 0x10;
|
||||||
static const int LOADED_LIGHTS = 0x20;
|
static const int LOADED_LIGHTS = 0x20;
|
||||||
};
|
};
|
||||||
#define CHUNK_DATA_LEN (CHUNK_VOL*2)
|
#define CHUNK_DATA_LEN (CHUNK_VOL*4)
|
||||||
|
|
||||||
struct voxel;
|
struct voxel;
|
||||||
class Lightmap;
|
class Lightmap;
|
||||||
@ -78,6 +78,7 @@ public:
|
|||||||
ubyte* encode() const;
|
ubyte* encode() const;
|
||||||
bool decode(ubyte* data);
|
bool decode(ubyte* data);
|
||||||
|
|
||||||
|
static void fromOld(ubyte* data);
|
||||||
static void convert(ubyte* data, const ContentLUT* lut);
|
static void convert(ubyte* data, const ContentLUT* lut);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user