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 // Block Count: fudge
sections.Write<int16_t>(1024); sections.Write<int16_t>(1024);
const uint8_t bitsPerBlock = sect.bitsPerBlock; const uint8_t bitsPerBlock = sect.blockStates.bits;
sections.Write<uint8_t>(bitsPerBlock); 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) if (bitsPerBlock <= 8)
{ {
// Palette // Palette
sections.WriteVarInt(sect.localPalette.Size()); sections.WriteVarInt(sect.blockStates.palette.Size());
for (size_t j = 0; j < sect.localPalette.Size(); j++) for (size_t j = 0; j < sect.blockStates.palette.Size(); j++)
sections.WriteVarInt(sect.localPalette.ByID(j)); sections.WriteVarInt(sect.blockStates.palette.ByID(j));
} }
sections.WriteVarInt(dataLength); sections.WriteVarInt(dataLength);
// Can't just copy because endian-ness! // Can't just copy because endian-ness!
for (size_t i = 0; i < dataLength; i++) 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); //Log::Trace("Section bits: {:#b}", sectionsBits);

View File

@ -45,7 +45,7 @@ namespace Feather
ChunkSection* section = &sections[y]; ChunkSection* section = &sections[y];
// Palette // Section Palette
ListTag<CompoundTag> palette = sectData.GetList<CompoundTag>("Palette"); ListTag<CompoundTag> palette = sectData.GetList<CompoundTag>("Palette");
@ -74,13 +74,13 @@ namespace Feather
catch (std::out_of_range& err) { catch (std::out_of_range& err) {
(void)err; (void)err;
int defaultId = World::GLOBAL_PALETTE.GetDefaultID(); 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); Log::Warn("Chunk Section Palette maps id {} to invalid block state with name '{}'", i, name);
continue; continue;
} }
// TODO: could use Add() // TODO: could use Add()
section->localPalette.AddMapping(i, id); section->blockStates.palette.AddMapping(i, id);
//Log::Trace(" {} -> {} {}", i, id, name); //Log::Trace(" {} -> {} {}", i, id, name);
} }
@ -93,13 +93,13 @@ namespace Feather
Log::Warn("Skipping section with no block states."); Log::Warn("Skipping section with no block states.");
continue; continue;
} }
Assert(blockStates.GetLength() < ChunkSection::MaximumLongCount); Assert(blockStates.GetLength() < section->blockStates.GetNumLongs());
for (size_t i = 0; i < blockStates.GetLength(); i++) 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++; n++;
} }
@ -107,4 +107,12 @@ namespace Feather
} }
}
bool Chunk::SetBlock(BlockPos& pos, BlockState& state)
{
ChunkSection& section = sections[GetSection(pos)];
return false;
}
}

View File

@ -1,27 +1,27 @@
#pragma once #pragma once
#include "Common.h"
#include "Types.h" #include "Types.h"
#include "nbt/NBT.h" #include "nbt/NBT.h"
#include "PalettedContainer.h" #include "PalettedContainer.h"
#include "block/state/BlockState.h" #include "block/state/BlockState.h"
#include <cstdint>
namespace Feather namespace Feather
{ {
// 16x16x16 sections of a chunk // 16x16x16 sections of a chunk
struct ChunkSection 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> static constexpr size_t DEFAULT_BITS = 4;
// Palette of local indexs to indexs in the global palette
IDMapper<int> localPalette;
uint8_t bitsPerBlock; PalettedContainer<uint64, NUM_BLOCKS, MAX_BITS> blockStates;
public:
ChunkSection() : blockStates(NUM_BLOCKS, DEFAULT_BITS) {}
}; };
// Chunk: 16x256x16 world chunk // Chunk: 16x256x16 world chunk
@ -43,5 +43,9 @@ namespace Feather
//const NBT::CompoundTag* heightmaps; //const NBT::CompoundTag* heightmaps;
Chunk(ChunkPos& pos, std::unique_ptr<NBT::CompoundTag> tag); 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 #pragma once
#include "Common.h"
#include "Palette.h" #include "Palette.h"
#include <array>
namespace Feather namespace Feather
{ {
// A container that maps values from a local palette to a // A container that maps values from a local palette to a
template <typename T> template <typename T, uint MaxSize, uint MaxBits>
class PalettedContainer 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; }
}; };
} }