Small performance improvements in fluid simulator.
git-svn-id: http://mc-server.googlecode.com/svn/trunk@1276 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
a710fcc9a4
commit
6f883cba2d
@ -489,14 +489,7 @@ void cChunk::BroadcastPendingBlockChanges(void)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Changes.reserve(m_PendingSendBlocks.size());
|
std::swap(Changes, m_PendingSendBlocks);
|
||||||
for (std::vector<unsigned int>::iterator itr = m_PendingSendBlocks.begin(), end = m_PendingSendBlocks.end(); itr != end; ++itr)
|
|
||||||
{
|
|
||||||
unsigned int index = *itr;
|
|
||||||
Vector3i RelPos = IndexToCoordinate(index);
|
|
||||||
Changes.push_back(sSetBlock(m_PosX, m_PosZ, RelPos.x, RelPos.y, RelPos.z, GetBlock(index), GetMeta(index)));
|
|
||||||
} // for itr - m_PendingSendBlocks[]
|
|
||||||
m_PendingSendBlocks.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr)
|
for (cClientHandleList::iterator itr = m_LoadedByClient.begin(), end = m_LoadedByClient.end(); itr != end; ++itr)
|
||||||
@ -1146,9 +1139,16 @@ void cChunk::SetBlock( int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType
|
|||||||
|
|
||||||
MarkDirty();
|
MarkDirty();
|
||||||
|
|
||||||
|
// The client doesn't need to distinguish between stationary and nonstationary fluids:
|
||||||
|
if (!(
|
||||||
|
((OldBlockType == E_BLOCK_STATIONARY_WATER) && (a_BlockType == E_BLOCK_WATER)) || // Replacing stationary water with water
|
||||||
|
((OldBlockType == E_BLOCK_WATER) && (a_BlockType == E_BLOCK_STATIONARY_WATER)) || // Replacing water with stationary water
|
||||||
|
((OldBlockType == E_BLOCK_STATIONARY_LAVA) && (a_BlockType == E_BLOCK_LAVA)) || // Replacing stationary water with water
|
||||||
|
((OldBlockType == E_BLOCK_LAVA) && (a_BlockType == E_BLOCK_STATIONARY_LAVA)) // Replacing water with stationary water
|
||||||
|
))
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSBlockLists);
|
cCSLock Lock(m_CSBlockLists);
|
||||||
m_PendingSendBlocks.push_back( index );
|
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ONLY recalculate lighting if it's necessary!
|
// ONLY recalculate lighting if it's necessary!
|
||||||
@ -1276,16 +1276,16 @@ void cChunk::QueueTickBlockNeighbors(int a_RelX, int a_RelY, int a_RelZ)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cChunk::FastSetBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
|
void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockType, BLOCKTYPE a_BlockMeta)
|
||||||
{
|
{
|
||||||
ASSERT(!((a_X < 0 || a_X >= Width || a_Y < 0 || a_Y >= Height || a_Z < 0 || a_Z >= Width)));
|
ASSERT(!((a_RelX < 0) || (a_RelX >= Width) || (a_RelY < 0) || (a_RelY >= Height) || (a_RelZ < 0) || (a_RelZ >= Width)));
|
||||||
|
|
||||||
ASSERT(IsValid());
|
ASSERT(IsValid());
|
||||||
|
|
||||||
const int index = MakeIndexNoCheck( a_X, a_Y, a_Z );
|
const int index = MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ);
|
||||||
const BLOCKTYPE OldBlock = m_BlockTypes[index];
|
const BLOCKTYPE OldBlockType = cChunkDef::GetBlock(m_BlockTypes, index);
|
||||||
const BLOCKTYPE OldBlockMeta = GetNibble( m_BlockMeta, index );
|
const BLOCKTYPE OldBlockMeta = GetNibble(m_BlockMeta, index);
|
||||||
if ((OldBlock == a_BlockType) && (OldBlockMeta == a_BlockMeta))
|
if ((OldBlockType == a_BlockType) && (OldBlockMeta == a_BlockMeta))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1294,37 +1294,44 @@ void cChunk::FastSetBlock(int a_X, int a_Y, int a_Z, BLOCKTYPE a_BlockType, BLOC
|
|||||||
|
|
||||||
m_BlockTypes[index] = a_BlockType;
|
m_BlockTypes[index] = a_BlockType;
|
||||||
|
|
||||||
|
// The client doesn't need to distinguish between stationary and nonstationary fluids:
|
||||||
|
if (!(
|
||||||
|
((OldBlockType == E_BLOCK_STATIONARY_WATER) && (a_BlockType == E_BLOCK_WATER)) || // Replacing stationary water with water
|
||||||
|
((OldBlockType == E_BLOCK_WATER) && (a_BlockType == E_BLOCK_STATIONARY_WATER)) || // Replacing water with stationary water
|
||||||
|
((OldBlockType == E_BLOCK_STATIONARY_LAVA) && (a_BlockType == E_BLOCK_LAVA)) || // Replacing stationary water with water
|
||||||
|
((OldBlockType == E_BLOCK_LAVA) && (a_BlockType == E_BLOCK_STATIONARY_LAVA)) // Replacing water with stationary water
|
||||||
|
))
|
||||||
{
|
{
|
||||||
cCSLock Lock(m_CSBlockLists);
|
cCSLock Lock(m_CSBlockLists);
|
||||||
m_PendingSendBlocks.push_back( index );
|
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, a_BlockType, a_BlockMeta));
|
||||||
}
|
}
|
||||||
|
|
||||||
SetNibble( m_BlockMeta, index, a_BlockMeta );
|
SetNibble(m_BlockMeta, index, a_BlockMeta);
|
||||||
|
|
||||||
// ONLY recalculate lighting if it's necessary!
|
// ONLY recalculate lighting if it's necessary!
|
||||||
if(
|
if(
|
||||||
(g_BlockLightValue[ OldBlock ] != g_BlockLightValue[ a_BlockType ]) ||
|
(g_BlockLightValue[OldBlockType ] != g_BlockLightValue[a_BlockType]) ||
|
||||||
(g_BlockSpreadLightFalloff[ OldBlock ] != g_BlockSpreadLightFalloff[ a_BlockType ]) ||
|
(g_BlockSpreadLightFalloff[OldBlockType] != g_BlockSpreadLightFalloff[a_BlockType]) ||
|
||||||
(g_BlockTransparent[ OldBlock ] != g_BlockTransparent[ a_BlockType ] )
|
(g_BlockTransparent[OldBlockType] != g_BlockTransparent[a_BlockType])
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_IsLightValid = false;
|
m_IsLightValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update heightmap, if needed:
|
// Update heightmap, if needed:
|
||||||
if (a_Y >= m_HeightMap[a_X + a_Z * Width])
|
if (a_RelY >= m_HeightMap[a_RelX + a_RelZ * Width])
|
||||||
{
|
{
|
||||||
if (a_BlockType != E_BLOCK_AIR)
|
if (a_BlockType != E_BLOCK_AIR)
|
||||||
{
|
{
|
||||||
m_HeightMap[a_X + a_Z * Width] = (unsigned char)a_Y;
|
m_HeightMap[a_RelX + a_RelZ * Width] = (unsigned char)a_RelY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int y = a_Y - 1; y > 0; --y)
|
for (int y = a_RelY - 1; y > 0; --y)
|
||||||
{
|
{
|
||||||
if (m_BlockTypes[MakeIndexNoCheck(a_X, y, a_Z)] != E_BLOCK_AIR)
|
if (m_BlockTypes[MakeIndexNoCheck(a_RelX, y, a_RelZ)] != E_BLOCK_AIR)
|
||||||
{
|
{
|
||||||
m_HeightMap[a_X + a_Z * Width] = (unsigned char)y;
|
m_HeightMap[a_RelX + a_RelZ * Width] = (unsigned char)y;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // for y - column in m_BlockData
|
} // for y - column in m_BlockData
|
||||||
@ -1345,7 +1352,7 @@ void cChunk::SendBlockTo(int a_RelX, int a_RelY, int a_RelZ, cClientHandle * a_C
|
|||||||
if (a_Client == NULL)
|
if (a_Client == NULL)
|
||||||
{
|
{
|
||||||
// Queue the block for all clients in the chunk (will be sent in Tick())
|
// Queue the block for all clients in the chunk (will be sent in Tick())
|
||||||
m_PendingSendBlocks.push_back(index);
|
m_PendingSendBlocks.push_back(sSetBlock(m_PosX, m_PosZ, a_RelX, a_RelY, a_RelZ, GetBlock(index), GetMeta(index)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ private:
|
|||||||
|
|
||||||
cCriticalSection m_CSBlockLists;
|
cCriticalSection m_CSBlockLists;
|
||||||
std::deque< unsigned int > m_ToTickBlocks;
|
std::deque< unsigned int > m_ToTickBlocks;
|
||||||
std::vector< unsigned int > m_PendingSendBlocks;
|
sSetBlockVector m_PendingSendBlocks; ///< Blocks that have changed and need to be sent to all clients
|
||||||
|
|
||||||
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
|
// A critical section is not needed, because all chunk access is protected by its parent ChunkMap's csLayers
|
||||||
cClientHandleList m_LoadedByClient;
|
cClientHandleList m_LoadedByClient;
|
||||||
|
@ -76,18 +76,19 @@ void cDelayedFluidSimulator::AddBlock(int a_BlockX, int a_BlockY, int a_BlockZ,
|
|||||||
void * ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData();
|
void * ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData();
|
||||||
cDelayedFluidSimulatorChunkData * ChunkData = (cDelayedFluidSimulatorChunkData *)ChunkDataRaw;
|
cDelayedFluidSimulatorChunkData * ChunkData = (cDelayedFluidSimulatorChunkData *)ChunkDataRaw;
|
||||||
cCoordWithIntVector & Blocks = ChunkData->m_Slots[m_AddSlotNum];
|
cCoordWithIntVector & Blocks = ChunkData->m_Slots[m_AddSlotNum];
|
||||||
|
|
||||||
// Check for duplicates:
|
// Check for duplicates:
|
||||||
|
int Index = cChunkDef::MakeIndexNoCheck(RelX, a_BlockY, RelZ);
|
||||||
for (cCoordWithIntVector::iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr)
|
for (cCoordWithIntVector::iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr)
|
||||||
{
|
{
|
||||||
if ((itr->x == RelX) && (itr->y == a_BlockY) && (itr->z == RelZ))
|
if ((itr->Data == Index))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
++m_TotalBlocks;
|
++m_TotalBlocks;
|
||||||
Blocks.push_back(cCoordWithInt(RelX, a_BlockY, RelZ));
|
Blocks.push_back(cCoordWithInt(RelX, a_BlockY, RelZ, Index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@ public:
|
|||||||
cDelayedFluidSimulatorChunkData(int a_TickDelay);
|
cDelayedFluidSimulatorChunkData(int a_TickDelay);
|
||||||
virtual ~cDelayedFluidSimulatorChunkData();
|
virtual ~cDelayedFluidSimulatorChunkData();
|
||||||
|
|
||||||
/// Slots, one for each delay tick, each containing the blocks to simulate; relative coords. Int param not used.
|
/** Slots, one for each delay tick, each containing the blocks to simulate; relative coords.
|
||||||
|
Int param is the block index (for faster duplicate comparison in cDelayedFluidSimulator::AddBlock())
|
||||||
|
*/
|
||||||
cCoordWithIntVector * m_Slots;
|
cCoordWithIntVector * m_Slots;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user