1
0

Maybe speed improvements?

* Use a single index to determine from when to begin copying data
* Use heightmap to determine first nonair block
This commit is contained in:
Tiger Wang 2014-04-07 20:57:14 +01:00
parent 74c4789c6f
commit f13cf1a021
2 changed files with 29 additions and 48 deletions

View File

@ -291,74 +291,55 @@ void cChunk::SetAllData(
memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap)); memcpy(m_HeightMap, a_HeightMap, sizeof(m_HeightMap));
} }
if (a_HeightMap == NULL)
{ {
int IdxWhereNonEmptyStarts = 0; CalculateHeightmap(a_BlockTypes);
{ // Blocktype compression }
bool FoundNonAir = false;
m_BlockTypes.clear();
for (int Idx = NumBlocks - 1; Idx >= 0; Idx--) int IdxWhereNonEmptyStarts = 0;
{ // Blocktype compression
unsigned char Highest = 0;
int X = 0, Z = 0;
m_BlockTypes.clear();
for (int x = 0; x < Width; x++)
{
for (int z = 0; z < Width; z++)
{ {
if (a_BlockTypes[Idx] != E_BLOCK_AIR) unsigned char Height = m_HeightMap[x + z * Width];
if (Height > Highest)
{ {
FoundNonAir = true; Highest = Height;
IdxWhereNonEmptyStarts = Idx; X = x; Z = z;
break;
} }
} }
m_BlockTypes.insert(m_BlockTypes.end(), &a_BlockTypes[0], &a_BlockTypes[IdxWhereNonEmptyStarts + 1]);
} }
{ // Blockmeta compression IdxWhereNonEmptyStarts = MakeIndexNoCheck(X, Highest + 1, Z);
m_BlockMeta.clear();
m_BlockMeta.insert(m_BlockMeta.end(), &a_BlockMeta[0], &a_BlockMeta[(IdxWhereNonEmptyStarts + 1) / 2]); m_BlockTypes.insert(m_BlockTypes.end(), &a_BlockTypes[0], &a_BlockTypes[IdxWhereNonEmptyStarts]);
} }
{ // Blockmeta compression
m_BlockMeta.clear();
m_BlockMeta.insert(m_BlockMeta.end(), &a_BlockMeta[0], &a_BlockMeta[IdxWhereNonEmptyStarts / 2]);
} }
if (a_BlockLight != NULL) if (a_BlockLight != NULL)
{ {
// Compress blocklight // Compress blocklight
bool FoundNonEmpty = false;
int IdxWhereNonEmptyStarts = 0;
m_BlockLight.clear(); m_BlockLight.clear();
m_BlockLight.insert(m_BlockLight.end(), &a_BlockLight[0], &a_BlockLight[IdxWhereNonEmptyStarts / 2]);
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]);
} }
if (a_BlockSkyLight != NULL) if (a_BlockSkyLight != NULL)
{ {
// Compress skylight // Compress skylight
bool FoundNonEmpty = false;
int IdxWhereNonEmptyStarts = 0;
m_BlockSkyLight.clear(); m_BlockSkyLight.clear();
m_BlockSkyLight.insert(m_BlockSkyLight.end(), &a_BlockSkyLight[0], &a_BlockSkyLight[IdxWhereNonEmptyStarts / 2]);
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);
if (a_HeightMap == NULL)
{
CalculateHeightmap();
}
// Clear the block entities present - either the loader / saver has better, or we'll create empty ones: // Clear the block entities present - either the loader / saver has better, or we'll create empty ones:
for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr) for (cBlockEntityList::iterator itr = m_BlockEntities.begin(); itr != m_BlockEntities.end(); ++itr)
@ -1483,7 +1464,7 @@ void cChunk::WakeUpSimulators(void)
void cChunk::CalculateHeightmap() void cChunk::CalculateHeightmap(const BLOCKTYPE * a_BlockTypes)
{ {
for (int x = 0; x < Width; x++) for (int x = 0; x < Width; x++)
{ {
@ -1492,7 +1473,7 @@ void cChunk::CalculateHeightmap()
for (int y = Height - 1; y > -1; y--) for (int y = Height - 1; y > -1; y--)
{ {
int index = MakeIndex( x, y, z ); int index = MakeIndex( x, y, z );
if (GetBlock(index) != E_BLOCK_AIR) if (a_BlockTypes[index] != E_BLOCK_AIR)
{ {
m_HeightMap[x + z * Width] = (unsigned char)y; m_HeightMap[x + z * Width] = (unsigned char)y;
break; break;

View File

@ -267,7 +267,7 @@ public:
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); // [x, y, z] in world block coords
void CalculateLighting(); // Recalculate right now void CalculateLighting(); // Recalculate right now
void CalculateHeightmap(); void CalculateHeightmap(const BLOCKTYPE * a_BlockTypes);
// Broadcast various packets to all clients of this chunk: // Broadcast various packets to all clients of this chunk:
// (Please keep these alpha-sorted) // (Please keep these alpha-sorted)