Implement anvil chunk sparsing
This commit is contained in:
parent
3ebcf0fd5c
commit
447d929da1
@ -422,6 +422,129 @@ void cChunkData::CopySkyLight(NIBBLETYPE * a_Dest) const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunkData::FillBlockTypes(BLOCKTYPE a_Value)
|
||||||
|
{
|
||||||
|
// If needed, allocate any missing sections
|
||||||
|
if (a_Value != 0x00)
|
||||||
|
{
|
||||||
|
for (auto & Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section == nullptr)
|
||||||
|
{
|
||||||
|
Section = Allocate();
|
||||||
|
std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section != nullptr)
|
||||||
|
{
|
||||||
|
std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), a_Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunkData::FillMetas(NIBBLETYPE a_Value)
|
||||||
|
{
|
||||||
|
// If needed, allocate any missing sections
|
||||||
|
if (a_Value != 0x00)
|
||||||
|
{
|
||||||
|
for (auto & Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section == nullptr)
|
||||||
|
{
|
||||||
|
Section = Allocate();
|
||||||
|
std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NIBBLETYPE NewMeta = static_cast<NIBBLETYPE>((a_Value << 4) | a_Value);
|
||||||
|
for (auto Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section != nullptr)
|
||||||
|
{
|
||||||
|
std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), NewMeta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunkData::FillBlockLight(NIBBLETYPE a_Value)
|
||||||
|
{
|
||||||
|
// If needed, allocate any missing sections
|
||||||
|
if (a_Value != 0x00)
|
||||||
|
{
|
||||||
|
for (auto & Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section == nullptr)
|
||||||
|
{
|
||||||
|
Section = Allocate();
|
||||||
|
std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NIBBLETYPE NewLight = static_cast<NIBBLETYPE>((a_Value << 4) | a_Value);
|
||||||
|
for (auto Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section != nullptr)
|
||||||
|
{
|
||||||
|
std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), NewLight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cChunkData::FillSkyLight(NIBBLETYPE a_Value)
|
||||||
|
{
|
||||||
|
// If needed, allocate any missing sections
|
||||||
|
if (a_Value != 0x0f)
|
||||||
|
{
|
||||||
|
for (auto & Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section == nullptr)
|
||||||
|
{
|
||||||
|
Section = Allocate();
|
||||||
|
std::fill(std::begin(Section->m_BlockTypes), std::end(Section->m_BlockTypes), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockMetas), std::end(Section->m_BlockMetas), 0x00);
|
||||||
|
std::fill(std::begin(Section->m_BlockLight), std::end(Section->m_BlockLight), 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NIBBLETYPE NewSkyLight = static_cast<NIBBLETYPE>((a_Value << 4) | a_Value);
|
||||||
|
for (auto Section : m_Sections)
|
||||||
|
{
|
||||||
|
if (Section != nullptr)
|
||||||
|
{
|
||||||
|
std::fill(std::begin(Section->m_BlockSkyLight), std::end(Section->m_BlockSkyLight), NewSkyLight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src)
|
void cChunkData::SetBlockTypes(const BLOCKTYPE * a_Src)
|
||||||
{
|
{
|
||||||
ASSERT(a_Src != nullptr);
|
ASSERT(a_Src != nullptr);
|
||||||
|
@ -80,6 +80,18 @@ public:
|
|||||||
/** Copies the skylight data into the specified flat array. */
|
/** Copies the skylight data into the specified flat array. */
|
||||||
void CopySkyLight (NIBBLETYPE * a_Dest) const;
|
void CopySkyLight (NIBBLETYPE * a_Dest) const;
|
||||||
|
|
||||||
|
/** Fills the chunk with the specified block. */
|
||||||
|
void FillBlockTypes(BLOCKTYPE a_Value);
|
||||||
|
|
||||||
|
/** Fills the chunk with the specified meta value. */
|
||||||
|
void FillMetas (NIBBLETYPE a_Value);
|
||||||
|
|
||||||
|
/** Fills the chunk with the specified block light. */
|
||||||
|
void FillBlockLight(NIBBLETYPE a_Value);
|
||||||
|
|
||||||
|
/** Fills the chunk with the specified sky light. */
|
||||||
|
void FillSkyLight (NIBBLETYPE a_Value);
|
||||||
|
|
||||||
/** Copies the blocktype data from the specified flat array into the internal representation.
|
/** Copies the blocktype data from the specified flat array into the internal representation.
|
||||||
Allocates sections that are needed for the operation.
|
Allocates sections that are needed for the operation.
|
||||||
Requires that a_Src is a valid pointer. */
|
Requires that a_Src is a valid pointer. */
|
||||||
|
@ -68,11 +68,11 @@ void cNBTChunkSerializer::Finish(void)
|
|||||||
m_Writer.EndList();
|
m_Writer.EndList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If light not valid, reset it to all zeroes:
|
// If light not valid, reset it to defaults:
|
||||||
if (!m_IsLightValid)
|
if (!m_IsLightValid)
|
||||||
{
|
{
|
||||||
memset(m_BlockLight, 0, sizeof(m_BlockLight));
|
m_Data.FillBlockLight(0x00);
|
||||||
memset(m_BlockSkyLight, 0, sizeof(m_BlockSkyLight));
|
m_Data.FillSkyLight(0x0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if "Entity" and "TileEntities" lists exists. MCEdit requires this.
|
// Check if "Entity" and "TileEntities" lists exists. MCEdit requires this.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
// NBTChunkSerializer.h
|
// NBTChunkSerializer.h
|
||||||
|
|
||||||
// Declares the cNBTChunkSerializer class that is used for saving individual chunks into NBT format used by Anvil
|
// Declares the cNBTChunkSerializer class that is used for saving individual chunks into NBT format used by Anvil
|
||||||
@ -55,7 +55,7 @@ class cPainting;
|
|||||||
|
|
||||||
|
|
||||||
class cNBTChunkSerializer :
|
class cNBTChunkSerializer :
|
||||||
public cChunkDataSeparateCollector
|
public cChunkDataCopyCollector
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cChunkDef::BiomeMap m_Biomes;
|
cChunkDef::BiomeMap m_Biomes;
|
||||||
@ -73,11 +73,8 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/* From cChunkDataSeparateCollector we inherit:
|
/* From cChunkDataCopyCollector we inherit:
|
||||||
- m_BlockTypes[]
|
- cChunkData m_Data */
|
||||||
- m_BlockMetas[]
|
|
||||||
- m_BlockLight[]
|
|
||||||
- m_BlockSkyLight[] */
|
|
||||||
|
|
||||||
cFastNBTWriter & m_Writer;
|
cFastNBTWriter & m_Writer;
|
||||||
|
|
||||||
|
@ -515,23 +515,25 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_
|
|||||||
|
|
||||||
// Save blockdata:
|
// Save blockdata:
|
||||||
a_Writer.BeginList("Sections", TAG_Compound);
|
a_Writer.BeginList("Sections", TAG_Compound);
|
||||||
size_t SliceSizeBlock = cChunkDef::Width * cChunkDef::Width * 16;
|
for (size_t Y = 0; Y != cChunkData::NumSections; ++Y)
|
||||||
size_t SliceSizeNibble = SliceSizeBlock / 2;
|
|
||||||
const char * BlockTypes = reinterpret_cast<const char *>(Serializer.m_BlockTypes);
|
|
||||||
const char * BlockMetas = reinterpret_cast<const char *>(Serializer.m_BlockMetas);
|
|
||||||
#ifdef DEBUG_SKYLIGHT
|
|
||||||
const char * BlockLight = reinterpret_cast<const char *>(Serializer.m_BlockSkyLight);
|
|
||||||
#else
|
|
||||||
const char * BlockLight = reinterpret_cast<const char *>(Serializer.m_BlockLight);
|
|
||||||
#endif
|
|
||||||
const char * BlockSkyLight = reinterpret_cast<const char *>(Serializer.m_BlockSkyLight);
|
|
||||||
for (int Y = 0; Y < 16; Y++)
|
|
||||||
{
|
{
|
||||||
|
auto Section = Serializer.m_Data.GetSection(Y);
|
||||||
|
if (Section == nullptr)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
a_Writer.BeginCompound("");
|
a_Writer.BeginCompound("");
|
||||||
a_Writer.AddByteArray("Blocks", BlockTypes + static_cast<unsigned int>(Y) * SliceSizeBlock, SliceSizeBlock);
|
a_Writer.AddByteArray("Blocks", reinterpret_cast<const char *>(Section->m_BlockTypes), ARRAYCOUNT(Section->m_BlockTypes));
|
||||||
a_Writer.AddByteArray("Data", BlockMetas + static_cast<unsigned int>(Y) * SliceSizeNibble, SliceSizeNibble);
|
a_Writer.AddByteArray("Data", reinterpret_cast<const char *>(Section->m_BlockMetas), ARRAYCOUNT(Section->m_BlockMetas));
|
||||||
a_Writer.AddByteArray("SkyLight", BlockSkyLight + static_cast<unsigned int>(Y) * SliceSizeNibble, SliceSizeNibble);
|
|
||||||
a_Writer.AddByteArray("BlockLight", BlockLight + static_cast<unsigned int>(Y) * SliceSizeNibble, SliceSizeNibble);
|
#ifdef DEBUG_SKYLIGHT
|
||||||
|
a_Writer.AddByteArray("BlockLight", reinterpret_cast<const char *>(Section->m_BlockSkyLight), ARRAYCOUNT(Section->m_BlockSkyLight));
|
||||||
|
#else
|
||||||
|
a_Writer.AddByteArray("BlockLight", reinterpret_cast<const char *>(Section->m_BlockLight), ARRAYCOUNT(Section->m_BlockLight));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
a_Writer.AddByteArray("SkyLight", reinterpret_cast<const char *>(Section->m_BlockSkyLight), ARRAYCOUNT(Section->m_BlockSkyLight));
|
||||||
a_Writer.AddByte("Y", static_cast<unsigned char>(Y));
|
a_Writer.AddByte("Y", static_cast<unsigned char>(Y));
|
||||||
a_Writer.EndCompound();
|
a_Writer.EndCompound();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user