Optimize Chunk packets severely.

master
Nicole Collings 2020-06-22 21:40:55 -07:00
parent d268654259
commit 48c7a38763
2 changed files with 71 additions and 59 deletions

View File

@ -47,17 +47,23 @@ const std::vector<unsigned short> &Chunk::cGetBiomes() const {
}
Packet Chunk::serialize() {
std::vector<unsigned char> lights {};
lights.resize(4096 * 4);
std::vector<unsigned short> blockLight = std::vector<unsigned short>(4096);
std::vector<unsigned char> sunLight = std::vector<unsigned char>(2048);
for (unsigned short i = 0; i < 4096; i++) {
lights[i * 4] = blocklight[i].r;
lights[i * 4 + 1] = blocklight[i].g;
lights[i * 4 + 2] = blocklight[i].b;
lights[i * 4 + 3] = getSunlight(i);
blocklight_union bl;
bl.b = this->blockLight[i];
blockLight[i] = bl.sh;
}
for (unsigned short i = 0; i < 2048; i++) {
sunlight_union sl;
sl.s = this->sunLight[i];
sunLight[i] = sl.ch;
}
Serializer s;
std::string temp = Serializer().append(pos).append(blocks).append(biomes).append(lights).data;
std::string temp = Serializer().append(pos).append(blocks).append(biomes).append(blockLight).append(sunLight).data;
s.append<std::string>(gzip::compress(temp.data(), temp.size()));
std::cout << s.data.length() << std::endl;
@ -66,40 +72,44 @@ Packet Chunk::serialize() {
}
void Chunk::deserialize(PacketView& packet) {
// pos = packet.d.read<glm::ivec3>();
std::string gzipped = packet.d.read<std::string>();
if (!gzip::is_compressed(gzipped.data(), gzipped.length())) throw "Invalid Blocks GZip Data.";
auto light = Deserializer(gzip::decompress(gzipped.data(), gzipped.length()))
std::vector<unsigned char> sunLight {};
std::vector<unsigned short> blockLight {};
Deserializer(gzip::decompress(gzipped.data(), gzipped.length()))
.read<glm::ivec3>(pos)
.read<std::vector<unsigned int>>(blocks)
.read<std::vector<unsigned short>>(biomes)
.read<std::vector<unsigned char>>();
.read<std::vector<unsigned short>>(blockLight)
.read<std::vector<unsigned char>>(sunLight);
for (unsigned int i = 0; i < 4096; i++) {
blocklight[i].r = light[i * 4];
blocklight[i].g = light[i * 4 + 1];
blocklight[i].b = light[i * 4 + 2];
setSunlight(i, light[i * 4 + 3]);
for (unsigned short i = 0; i < 4096; i++) {
blocklight_union bl;
bl.sh = blockLight[i];
this->blockLight[i] = bl.b;
}
for (unsigned short i = 0; i < 2048; i++) {
sunlight_union sl;
sl.ch = sunLight[i];
this->sunLight[i] = sl.s;
}
recalculateRenderableBlocks();
}
void Chunk::recalculateRenderableBlocks() {
shouldHaveMesh = false;
nonAirBlocks = 0;
empty = true;
for (unsigned int i = 0; i < blocks.size(); i += 2) {
unsigned int cInd = blocks[i];
unsigned int nInd = (i == blocks.size() - 2 ? 4095 : blocks[i + 2]);
unsigned int blk = blocks[i + 1];
unsigned int cInd = blocks[i];
if (blk > DefinitionAtlas::AIR) {
empty = false;
if (blocks[i + 1] > DefinitionAtlas::AIR) {
nonAirBlocks += nInd - cInd;
shouldHaveMesh = true;
}
}
shouldHaveMesh = !empty;
}

View File

@ -16,6 +16,7 @@
#include "../../util/net/PacketView.h"
class Chunk {
public:
friend class MapGen;
struct BlockLight {
@ -24,14 +25,15 @@ class Chunk {
unsigned char g: 5;
unsigned char b: 5, :1;
};
typedef union { short sh; BlockLight b; } blocklight_union;
struct Sunlight {
struct SunLight {
// 8 bits for two values - 1 char
unsigned char a: 4;
unsigned char b: 4;
};
typedef union { char ch; SunLight s; } sunlight_union;
public:
Chunk() = default;
explicit Chunk(const std::vector<unsigned int>& blocks, const std::vector<unsigned short>& biomes);
Chunk(const std::vector<unsigned int>& blocks, const std::vector<unsigned short>& biomes, glm::ivec3 pos);
@ -74,8 +76,8 @@ private:
std::vector<unsigned int> blocks {0, 0};
std::vector<unsigned short> biomes {0, 0};
std::array<Sunlight, 2048> sunlight {};
std::array<BlockLight, 4096> blocklight {};
std::array<SunLight, 2048> sunLight {};
std::array<BlockLight, 4096> blockLight {};
bool empty = true;
unsigned short nonAirBlocks = 0;
@ -84,6 +86,11 @@ private:
inline void setSunlight(unsigned int ind, unsigned char val);
};
inline unsigned int Chunk::getBlock(const glm::ivec3& pos) const {
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return DefinitionAtlas::INVALID;
return getBlock(Space::Block::index(pos));
}
inline bool Chunk::setBlock(const glm::ivec3& pos, unsigned int blk) {
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return false;
return setBlock(Space::Block::index(pos), blk);
@ -94,61 +101,56 @@ inline unsigned int Chunk::getBlock(unsigned int ind) const {
return RIE::read<unsigned int>(ind, blocks, 4096);
}
inline unsigned int Chunk::getBlock(const glm::ivec3& pos) const {
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return DefinitionAtlas::INVALID;
return getBlock(Space::Block::index(pos));
inline unsigned short Chunk::getBiome(unsigned int ind) const {
if (ind >= 4096) return BiomeAtlas::INVALID;
return RIE::read<unsigned short>(ind, biomes, 4096);
}
inline bool Chunk::setBiome(unsigned int ind, unsigned short bio) {
return RIE::write(ind, bio, biomes, 4096);
}
inline bool Chunk::setBiome(const glm::ivec3& pos, unsigned short bio) {
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return false;
return setBiome(Space::Block::index(pos), bio);
}
inline unsigned short Chunk::getBiome(unsigned int ind) const {
if (ind >= 4096) return BiomeAtlas::INVALID;
return RIE::read<unsigned short>(ind, biomes, 4096);
}
inline unsigned short Chunk::getBiome(const glm::ivec3& pos) const {
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return BiomeAtlas::INVALID;
return getBiome(Space::Block::index(pos));
}
inline bool Chunk::setBiome(const glm::ivec3& pos, unsigned short bio) {
if (pos.x > 15 || pos.x < 0 || pos.y > 15 || pos.y < 0 || pos.z > 15 || pos.z < 0) return false;
return setBiome(Space::Block::index(pos), bio);
}
inline glm::ivec4 Chunk::getLight(unsigned int ind) {
return { blocklight[ind].r, blocklight[ind].g, blocklight[ind].b, getSunlight(ind) };
return { blockLight[ind].r, blockLight[ind].g, blockLight[ind].b, getSunlight(ind) };
}
inline void Chunk::setLight(unsigned int ind, glm::ivec4 l) {
blockLight[ind].r = l.x;
blockLight[ind].g = l.y;
blockLight[ind].b = l.z;
setSunlight(ind, l.w);
}
inline unsigned char Chunk::getLight(unsigned int ind, unsigned char channel) {
return channel == 0 ? blocklight[ind].r :
channel == 1 ? blocklight[ind].g :
channel == 2 ? blocklight[ind].b :
return channel == 0 ? blockLight[ind].r :
channel == 1 ? blockLight[ind].g :
channel == 2 ? blockLight[ind].b :
getSunlight(ind);
}
inline void Chunk::setLight(unsigned int ind, unsigned char channel, unsigned char l) {
channel == 0 ? blocklight[ind].r = l :
channel == 1 ? blocklight[ind].g = l :
channel == 2 ? blocklight[ind].b = l :
(setSunlight(ind, l), 0);
}
inline void Chunk::setLight(unsigned int ind, glm::ivec4 l) {
blocklight[ind].r = l.x;
blocklight[ind].g = l.y;
blocklight[ind].b = l.z;
setSunlight(ind, l.w);
channel == 0 ? blockLight[ind].r = l :
channel == 1 ? blockLight[ind].g = l :
channel == 2 ? blockLight[ind].b = l :
(setSunlight(ind,l), 0);
}
inline unsigned char Chunk::getSunlight(unsigned int ind) {
if (ind % 2 == 0) return sunlight[ind / 2].a;
else return sunlight[ind / 2].b;
if (ind % 2 == 0) return sunLight[ind / 2].a;
else return sunLight[ind / 2].b;
}
inline void Chunk::setSunlight(unsigned int ind, unsigned char val) {
if (ind % 2 == 0) sunlight[ind / 2].a = val;
else sunlight[ind / 2].b = val;
if (ind % 2 == 0) sunLight[ind / 2].a = val;
else sunLight[ind / 2].b = val;
}