Blocklight and skylight now compressed
This commit is contained in:
parent
3201d1bf16
commit
a42d1f8517
108
src/Chunk.cpp
108
src/Chunk.cpp
@ -250,8 +250,14 @@ void cChunk::GetAllData(cChunkDataCallback & a_Callback)
|
|||||||
a_Callback.BlockMeta (Metas.data());
|
a_Callback.BlockMeta (Metas.data());
|
||||||
|
|
||||||
a_Callback.LightIsValid (m_IsLightValid);
|
a_Callback.LightIsValid (m_IsLightValid);
|
||||||
a_Callback.BlockLight (m_BlockLight);
|
|
||||||
a_Callback.BlockSkyLight(m_BlockSkyLight);
|
std::vector<NIBBLETYPE> BlockLights = m_BlockLight;
|
||||||
|
BlockLights.resize(NumBlocks / 2);
|
||||||
|
a_Callback.BlockLight (BlockLights.data());
|
||||||
|
|
||||||
|
std::vector<NIBBLETYPE> BlockSkyLights = m_BlockSkyLight;
|
||||||
|
BlockSkyLights.resize(NumBlocks / 2, 0xff);
|
||||||
|
a_Callback.BlockSkyLight(BlockSkyLights.data());
|
||||||
|
|
||||||
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end(); ++itr)
|
||||||
{
|
{
|
||||||
@ -285,47 +291,66 @@ void cChunk::SetAllData(
|
|||||||
memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap));
|
memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Blocktype compression
|
{
|
||||||
bool FoundNonAir = false;
|
|
||||||
int IdxWhereNonEmptyStarts = 0;
|
int IdxWhereNonEmptyStarts = 0;
|
||||||
m_BlockTypes.clear();
|
{ // Blocktype compression
|
||||||
|
bool FoundNonAir = false;
|
||||||
|
m_BlockTypes.clear();
|
||||||
|
|
||||||
for (int Idx = NumBlocks - 1; Idx >= 0; Idx--)
|
for (int Idx = NumBlocks - 1; Idx >= 0; Idx--)
|
||||||
{
|
|
||||||
if (a_BlockTypes[Idx] != E_BLOCK_AIR)
|
|
||||||
{
|
{
|
||||||
FoundNonAir = true;
|
if (a_BlockTypes[Idx] != E_BLOCK_AIR)
|
||||||
IdxWhereNonEmptyStarts = Idx;
|
{
|
||||||
break;
|
FoundNonAir = true;
|
||||||
|
IdxWhereNonEmptyStarts = Idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
m_BlockTypes.insert(m_BlockTypes.end(), &a_BlockTypes[0], &a_BlockTypes[IdxWhereNonEmptyStarts + 1]);
|
||||||
}
|
}
|
||||||
m_BlockTypes.insert(m_BlockTypes.end(), &a_BlockTypes[0], &a_BlockTypes[IdxWhereNonEmptyStarts + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // Blockmeta compression
|
{ // Blockmeta compression
|
||||||
|
m_BlockMeta.clear();
|
||||||
|
m_BlockMeta.insert(m_BlockMeta.end(), &a_BlockMeta[0], &a_BlockMeta[(IdxWhereNonEmptyStarts + 1) / 2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a_BlockLight != NULL)
|
||||||
|
{
|
||||||
|
// Compress blocklight
|
||||||
bool FoundNonEmpty = false;
|
bool FoundNonEmpty = false;
|
||||||
int IdxWhereNonEmptyStarts = 0;
|
int IdxWhereNonEmptyStarts = 0;
|
||||||
m_BlockMeta.clear();
|
m_BlockLight.clear();
|
||||||
|
|
||||||
for (int Idx = (NumBlocks / 2) - 1; Idx >= 0; Idx--)
|
for (int Idx = (NumBlocks / 2) - 1; Idx >= 0; Idx--)
|
||||||
{
|
{
|
||||||
if (a_BlockMeta[Idx] != 0)
|
if (a_BlockLight[Idx] != 0)
|
||||||
{
|
{
|
||||||
FoundNonEmpty = true;
|
FoundNonEmpty = true;
|
||||||
IdxWhereNonEmptyStarts = Idx;
|
IdxWhereNonEmptyStarts = Idx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_BlockMeta.insert(m_BlockMeta.end(), &a_BlockMeta[0], &a_BlockMeta[IdxWhereNonEmptyStarts + 1]);
|
m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[IdxWhereNonEmptyStarts + 1]);
|
||||||
}
|
|
||||||
|
|
||||||
if (a_BlockLight != NULL)
|
|
||||||
{
|
|
||||||
memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_BlockSkyLight != NULL)
|
if (a_BlockSkyLight != NULL)
|
||||||
{
|
{
|
||||||
memcpy(m_BlockSkyLight, a_BlockSkyLight, sizeof(m_BlockSkyLight));
|
// Compress skylight
|
||||||
|
bool FoundNonEmpty = false;
|
||||||
|
int IdxWhereNonEmptyStarts = 0;
|
||||||
|
m_BlockSkyLight.clear();
|
||||||
|
|
||||||
|
for (int Idx = (NumBlocks / 2) - 1; Idx >= 0; Idx--)
|
||||||
|
{
|
||||||
|
if (a_BlockSkyLight[Idx] != 0xff)
|
||||||
|
{
|
||||||
|
FoundNonEmpty = true;
|
||||||
|
IdxWhereNonEmptyStarts = Idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_BlockSkyLight[0], &a_BlockSkyLight[IdxWhereNonEmptyStarts + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL);
|
m_IsLightValid = (a_BlockLight != NULL) && (a_BlockSkyLight != NULL);
|
||||||
@ -371,8 +396,41 @@ void cChunk::SetLight(
|
|||||||
{
|
{
|
||||||
// TODO: We might get cases of wrong lighting when a chunk changes in the middle of a lighting calculation.
|
// TODO: We might get cases of wrong lighting when a chunk changes in the middle of a lighting calculation.
|
||||||
// Postponing until we see how bad it is :)
|
// Postponing until we see how bad it is :)
|
||||||
memcpy(m_BlockLight, a_BlockLight, sizeof(m_BlockLight));
|
|
||||||
memcpy(m_BlockSkyLight, a_SkyLight, sizeof(m_BlockSkyLight));
|
{ // Compress blocklight
|
||||||
|
bool FoundNonEmpty = false;
|
||||||
|
int IdxWhereNonEmptyStarts = 0;
|
||||||
|
m_BlockLight.clear();
|
||||||
|
|
||||||
|
for (int Idx = (NumBlocks / 2) - 1; Idx >= 0; Idx--)
|
||||||
|
{
|
||||||
|
if (a_BlockLight[Idx] != 0)
|
||||||
|
{
|
||||||
|
FoundNonEmpty = true;
|
||||||
|
IdxWhereNonEmptyStarts = Idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[IdxWhereNonEmptyStarts + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Compress skylight
|
||||||
|
bool FoundNonEmpty = false;
|
||||||
|
int IdxWhereNonEmptyStarts = 0;
|
||||||
|
m_BlockSkyLight.clear();
|
||||||
|
|
||||||
|
for (int Idx = (NumBlocks / 2) - 1; Idx >= 0; Idx--)
|
||||||
|
{
|
||||||
|
if (a_SkyLight[Idx] != 0xff)
|
||||||
|
{
|
||||||
|
FoundNonEmpty = true;
|
||||||
|
IdxWhereNonEmptyStarts = Idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_SkyLight[0], &a_SkyLight[IdxWhereNonEmptyStarts + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
m_IsLightValid = true;
|
m_IsLightValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,9 +326,9 @@ public:
|
|||||||
inline void SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_BlockIdx, a_Meta); }
|
inline void SetMeta(int a_BlockIdx, NIBBLETYPE a_Meta) { cChunkDef::SetNibble(m_BlockMeta, a_BlockIdx, a_Meta); }
|
||||||
|
|
||||||
inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); }
|
inline NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockLight, a_RelX, a_RelY, a_RelZ); }
|
||||||
inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ); }
|
inline NIBBLETYPE GetSkyLight (int a_RelX, int a_RelY, int a_RelZ) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_RelX, a_RelY, a_RelZ, true); }
|
||||||
inline NIBBLETYPE GetBlockLight(int a_Idx) const {return cChunkDef::GetNibble(m_BlockLight, a_Idx); }
|
inline NIBBLETYPE GetBlockLight(int a_Idx) const {return cChunkDef::GetNibble(m_BlockLight, a_Idx); }
|
||||||
inline NIBBLETYPE GetSkyLight (int a_Idx) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_Idx); }
|
inline NIBBLETYPE GetSkyLight (int a_Idx) const {return cChunkDef::GetNibble(m_BlockSkyLight, a_Idx, true); }
|
||||||
|
|
||||||
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
/** Same as GetBlock(), but relative coords needn't be in this chunk (uses m_Neighbor-s or m_ChunkMap in such a case); returns true on success */
|
||||||
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
bool UnboundedRelGetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta) const;
|
||||||
@ -423,8 +423,8 @@ private:
|
|||||||
// TODO: Make these pointers and don't allocate what isn't needed
|
// TODO: Make these pointers and don't allocate what isn't needed
|
||||||
std::vector<BLOCKTYPE> m_BlockTypes;
|
std::vector<BLOCKTYPE> m_BlockTypes;
|
||||||
std::vector<NIBBLETYPE> m_BlockMeta;
|
std::vector<NIBBLETYPE> m_BlockMeta;
|
||||||
NIBBLETYPE m_BlockLight [cChunkDef::NumBlocks / 2];
|
std::vector<NIBBLETYPE> m_BlockLight;
|
||||||
NIBBLETYPE m_BlockSkyLight[cChunkDef::NumBlocks / 2];
|
std::vector<NIBBLETYPE> m_BlockSkyLight;
|
||||||
|
|
||||||
cChunkDef::HeightMap m_HeightMap;
|
cChunkDef::HeightMap m_HeightMap;
|
||||||
cChunkDef::BiomeMap m_BiomeMap;
|
cChunkDef::BiomeMap m_BiomeMap;
|
||||||
|
@ -232,13 +232,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NIBBLETYPE GetNibble(const std::vector<NIBBLETYPE> & a_Buffer, int a_BlockIdx)
|
static NIBBLETYPE GetNibble(const std::vector<NIBBLETYPE> & a_Buffer, int a_BlockIdx, bool a_IsSkyLightNibble = false)
|
||||||
{
|
{
|
||||||
if ((a_BlockIdx > -1) && (a_BlockIdx < NumBlocks))
|
if ((a_BlockIdx > -1) && (a_BlockIdx < NumBlocks))
|
||||||
{
|
{
|
||||||
if (a_Buffer.empty() || (a_BlockIdx / 2 > a_Buffer.size() - 1))
|
if (a_Buffer.empty() || (a_BlockIdx / 2 > a_Buffer.size() - 1))
|
||||||
{
|
{
|
||||||
return 0;
|
return (a_IsSkyLightNibble ? 0xff : 0);
|
||||||
}
|
}
|
||||||
return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f;
|
return (a_Buffer[a_BlockIdx / 2] >> ((a_BlockIdx & 1) * 4)) & 0x0f;
|
||||||
}
|
}
|
||||||
@ -259,14 +259,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NIBBLETYPE GetNibble(const std::vector<NIBBLETYPE> & a_Buffer, int x, int y, int z)
|
static NIBBLETYPE GetNibble(const std::vector<NIBBLETYPE> & a_Buffer, int x, int y, int z, bool a_IsSkyLightNibble = false)
|
||||||
{
|
{
|
||||||
if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1))
|
if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1))
|
||||||
{
|
{
|
||||||
int Index = MakeIndexNoCheck(x, y, z);
|
int Index = MakeIndexNoCheck(x, y, z);
|
||||||
if (a_Buffer.empty() || (Index / 2 > a_Buffer.size() - 1))
|
if (a_Buffer.empty() || (Index / 2 > a_Buffer.size() - 1))
|
||||||
{
|
{
|
||||||
return 0;
|
return (a_IsSkyLightNibble ? 0xff : 0);
|
||||||
}
|
}
|
||||||
return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
|
return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user