Move ChunkSection guts to PalettedContainer

This commit is contained in:
Alpyne 2020-10-30 18:57:43 -07:00
parent 55fa33057f
commit e64603c6b6
4 changed files with 60 additions and 27 deletions

View File

@ -232,24 +232,24 @@ namespace Feather
// Block Count: fudge
sections.Write<int16_t>(1024);
const uint8_t bitsPerBlock = sect.bitsPerBlock;
const uint8_t bitsPerBlock = sect.blockStates.bits;
sections.Write<uint8_t>(bitsPerBlock);
const size_t dataLength = (16 * 16 * 16) * bitsPerBlock / 64;
const size_t dataLength = ChunkSection::NUM_BLOCKS * bitsPerBlock / bitsizeof(uint64);
if (bitsPerBlock <= 8)
{
// Palette
sections.WriteVarInt(sect.localPalette.Size());
sections.WriteVarInt(sect.blockStates.palette.Size());
for (size_t j = 0; j < sect.localPalette.Size(); j++)
sections.WriteVarInt(sect.localPalette.ByID(j));
for (size_t j = 0; j < sect.blockStates.palette.Size(); j++)
sections.WriteVarInt(sect.blockStates.palette.ByID(j));
}
sections.WriteVarInt(dataLength);
// Can't just copy because endian-ness!
for (size_t i = 0; i < dataLength; i++)
sections.Write<uint64_t>(sect.blockStates[i]);
sections.Write<uint64_t>(sect.blockStates.data[i]);
}
//Log::Trace("Section bits: {:#b}", sectionsBits);

View File

@ -45,7 +45,7 @@ namespace Feather
ChunkSection* section = &sections[y];
// Palette
// Section Palette
ListTag<CompoundTag> palette = sectData.GetList<CompoundTag>("Palette");
@ -74,13 +74,13 @@ namespace Feather
catch (std::out_of_range& err) {
(void)err;
int defaultId = World::GLOBAL_PALETTE.GetDefaultID();
section->localPalette.AddMapping(i, defaultId);
section->blockStates.palette.AddMapping(i, defaultId);
Log::Warn("Chunk Section Palette maps id {} to invalid block state with name '{}'", i, name);
continue;
}
// TODO: could use Add()
section->localPalette.AddMapping(i, id);
section->blockStates.palette.AddMapping(i, id);
//Log::Trace(" {} -> {} {}", i, id, name);
}
@ -94,17 +94,25 @@ namespace Feather
continue;
}
Assert(blockStates.GetLength() < ChunkSection::MaximumLongCount);
Assert(blockStates.GetLength() < section->blockStates.GetNumLongs());
for (size_t i = 0; i < blockStates.GetLength(); i++)
section->blockStates[i] = blockStates[i];
section->blockStates.data[i] = blockStates[i];
section->bitsPerBlock = (blockStates.GetLength() * 64) / (16 * 16 * 16);
section->blockStates.SetBits(Math::CeilDiv(blockStates.GetLength() * bitsizeof(int64), ChunkSection::NUM_BLOCKS));
n++;
}
}
bool Chunk::SetBlock(BlockPos& pos, BlockState& state)
{
ChunkSection& section = sections[GetSection(pos)];
return false;
}
}

View File

@ -1,27 +1,27 @@
#pragma once
#include "Common.h"
#include "Types.h"
#include "nbt/NBT.h"
#include "PalettedContainer.h"
#include "block/state/BlockState.h"
#include <cstdint>
namespace Feather
{
// 16x16x16 sections of a chunk
struct ChunkSection
{
static constexpr size_t MaximumLongCount = (16 * 16 * 16) * 14 / 64;
static constexpr size_t NUM_BLOCKS = (16 * 16 * 16);
std::array<uint64_t, MaximumLongCount> blockStates;
static constexpr size_t MAX_BITS = Math::CeilLog2(NUM_BLOCKS);
// TODO: this should eventually be Palette<BlockState>
// Palette of local indexs to indexs in the global palette
IDMapper<int> localPalette;
static constexpr size_t DEFAULT_BITS = 4;
uint8_t bitsPerBlock;
PalettedContainer<uint64, NUM_BLOCKS, MAX_BITS> blockStates;
public:
ChunkSection() : blockStates(NUM_BLOCKS, DEFAULT_BITS) {}
};
// Chunk: 16x256x16 world chunk
@ -43,5 +43,9 @@ namespace Feather
//const NBT::CompoundTag* heightmaps;
Chunk(ChunkPos& pos, std::unique_ptr<NBT::CompoundTag> tag);
inline int GetSection(BlockPos& pos) { return pos.y >> 4; }
bool SetBlock(BlockPos& pos, BlockState& state);
};
};

View File

@ -1,13 +1,34 @@
#pragma once
#include "Common.h"
#include "Palette.h"
#include <array>
namespace Feather
{
// A container that maps values from a local palette to a
template <typename T>
class PalettedContainer
template <typename T, uint MaxSize, uint MaxBits>
struct PalettedContainer
{
const Palette<T>& m_globalPalette;
//const Palette<T>& globalPalette;
static constexpr size_t NUM_LONGS = Math::CeilDiv(MaxSize * MaxBits, bitsizeof(uint64));
std::array<uint64, NUM_LONGS> data;
// TODO: this could eventually be Palette<BlockState> to avoid double lookup
// Palette of local indexs to indexs in the global palette
IDMapper<int> palette;
uint size = MaxSize;
uint8 bits = MaxBits;
public:
PalettedContainer(uint size, uint8 bits) : size(size), bits(bits), data() {}
inline void SetBits(uint8 nbits) { bits = nbits; }
inline constexpr size_t GetNumLongs() { return NUM_LONGS; }
};
}