From e8aa03f8df037f60e4f9e6a34ac05f21bfe3c2cd Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Wed, 20 Mar 2013 20:45:52 +0000 Subject: DelayedFluidSimulator: optimized block storage for large amounts of blocks. Speeds up chunk generation by 15 %. Expected to speed up fluid simulation, unmeasured. git-svn-id: http://mc-server.googlecode.com/svn/trunk@1293 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Simulator/DelayedFluidSimulator.cpp | 61 ++++++++++++++++++++++-------- source/Simulator/DelayedFluidSimulator.h | 21 ++++++++-- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/source/Simulator/DelayedFluidSimulator.cpp b/source/Simulator/DelayedFluidSimulator.cpp index 25179d55a..b69718977 100644 --- a/source/Simulator/DelayedFluidSimulator.cpp +++ b/source/Simulator/DelayedFluidSimulator.cpp @@ -14,11 +14,37 @@ +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cDelayedFluidSimulatorChunkData::cSlot + +bool cDelayedFluidSimulatorChunkData::cSlot::Add(int a_RelX, int a_RelY, int a_RelZ) +{ + ASSERT(a_RelZ >= 0); + ASSERT(a_RelZ < ARRAYCOUNT(m_Blocks)); + + cCoordWithIntVector & Blocks = m_Blocks[a_RelZ]; + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY, a_RelZ); + for (cCoordWithIntVector::const_iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr) + { + if (itr->Data == Index) + { + // Already present + return false; + } + } // for itr - Blocks[] + Blocks.push_back(cCoordWithInt(a_RelX, a_RelY, a_RelZ, Index)); + return true; +} + + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cDelayedFluidSimulatorChunkData: cDelayedFluidSimulatorChunkData::cDelayedFluidSimulatorChunkData(int a_TickDelay) : - m_Slots(new cCoordWithIntVector[a_TickDelay]) + m_Slots(new cSlot[a_TickDelay]) { } @@ -75,20 +101,15 @@ 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(); cDelayedFluidSimulatorChunkData * ChunkData = (cDelayedFluidSimulatorChunkData *)ChunkDataRaw; - cCoordWithIntVector & Blocks = ChunkData->m_Slots[m_AddSlotNum]; + cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_AddSlotNum]; - // Check for duplicates: - int Index = cChunkDef::MakeIndexNoCheck(RelX, a_BlockY, RelZ); - for (cCoordWithIntVector::iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr) + // Add, if not already present: + if (!Slot.Add(RelX, a_BlockY, RelZ)) { - if ((itr->Data == Index)) - { - return; - } + return; } ++m_TotalBlocks; - Blocks.push_back(cCoordWithInt(RelX, a_BlockY, RelZ, Index)); } @@ -113,15 +134,23 @@ void cDelayedFluidSimulator::SimulateChunk(float a_Dt, int a_ChunkX, int a_Chunk { void * ChunkDataRaw = (m_FluidBlock == E_BLOCK_WATER) ? a_Chunk->GetWaterSimulatorData() : a_Chunk->GetLavaSimulatorData(); cDelayedFluidSimulatorChunkData * ChunkData = (cDelayedFluidSimulatorChunkData *)ChunkDataRaw; - cCoordWithIntVector & Blocks = ChunkData->m_Slots[m_SimSlotNum]; + cDelayedFluidSimulatorChunkData::cSlot & Slot = ChunkData->m_Slots[m_SimSlotNum]; - // Simulate the blocks in the scheduled slot: - for (cCoordWithIntVector::iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr) + // Simulate all the blocks in the scheduled slot: + for (int i = 0; i < ARRAYCOUNT(Slot.m_Blocks); i++) { - SimulateBlock(a_Chunk, itr->x, itr->y, itr->z); + cCoordWithIntVector & Blocks = Slot.m_Blocks[i]; + if (Blocks.empty()) + { + continue; + } + for (cCoordWithIntVector::iterator itr = Blocks.begin(), end = Blocks.end(); itr != end; ++itr) + { + SimulateBlock(a_Chunk, itr->x, itr->y, itr->z); + } + m_TotalBlocks -= Blocks.size(); + Blocks.clear(); } - m_TotalBlocks -= Blocks.size(); - Blocks.clear(); } diff --git a/source/Simulator/DelayedFluidSimulator.h b/source/Simulator/DelayedFluidSimulator.h index 5f8c6e073..6f7433877 100644 --- a/source/Simulator/DelayedFluidSimulator.h +++ b/source/Simulator/DelayedFluidSimulator.h @@ -19,13 +19,26 @@ class cDelayedFluidSimulatorChunkData : public cFluidSimulatorData { public: + class cSlot + { + public: + /// Returns true if the specified block is stored + bool HasBlock(int a_RelX, int a_RelY, int a_RelZ); + + /// Adds the specified block unless already present; returns true if added, false if the block was already present + bool Add(int a_RelX, int a_RelY, int a_RelZ); + + /** Array of block containers, each item stores blocks for one Z coord + Int param is the block index (for faster duplicate comparison in Add()) + */ + cCoordWithIntVector m_Blocks[16]; + } ; + cDelayedFluidSimulatorChunkData(int a_TickDelay); virtual ~cDelayedFluidSimulatorChunkData(); - /** 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; + /// Slots, one for each delay tick, each containing the blocks to simulate + cSlot * m_Slots; } ; -- cgit v1.2.3