My Project
BlockLightGridClient.h
1 #pragma once
2 
3 #include <stdint.h>
4 #include <vector>
5 #include <queue>
6 #include <mutex>
7 #include <unordered_set>
8 #include <map>
9 #include <utility>
10 #include <bitset>
11 #include <boost/circular_buffer.hpp>
12 #include <boost/thread.hpp>
13 #include <boost/shared_ptr.hpp>
14 #include <boost/enable_shared_from_this.hpp>
15 #include "util/ParaMemPool.h"
16 #include "BlockReadWriteLock.h"
17 #include "BlockLightGridBase.h"
18 
19 namespace ParaEngine
20 {
23  {
24  public:
25  typedef FixedSizedAllocator< std::pair<const uint64_t, Light> > DL_Allocator_BlockLight;
26 
27  CBlockLightGridClient(int32_t chunkCacheDim, CBlockWorld* pBlockWorld);
28  virtual ~CBlockLightGridClient();
29 
30  public:
31  virtual void OnEnterWorld();
32  virtual void OnLeaveWorld();
33  virtual void OnWorldMove(uint16_t centerChunkX, uint16_t centerChunkZ);
34  virtual void UpdateLighting();
35 
36  //get light brightness of current and 26 nearby block
37  // @param brightness: pointer to uint8_t blockBrightness[27];
38  // @param nSize: if 1, it will only get the center block.
39  // @param nLightType: -1 means Max light. 0 means emissive block light, 1 means sun light. 2 means both. where brightness[i] is block light and brightness[i+nSize] is sunlight
40  // @return : true if exist. false if there is no block at the position.
41  virtual bool GetBrightness(Uint16x3& blockId, uint8_t* brightness, int nSize = 27, int nLightType = -1);
42 
46  virtual void SetLightDirty(Uint16x3& blockId_ws, bool isSunLight, int8 nUpdateRange = 0);
47 
49  virtual void NotifyBlockHeightChanged(uint16_t blockIdX_ws, uint16_t blockIdZ_ws, ChunkMaxHeight& prevBlockHeight);
50 
52  virtual void AddDirtyColumn(uint16_t chunkX_ws, uint16_t chunkZ_ws);
53 
55  virtual int GetDirtyColumnCount();
56 
58  virtual int GetDirtyBlockCount();
59 
61  virtual void SetColumnPreloaded(uint16_t chunkX_ws, uint16_t chunkZ_ws);
62 
64  virtual void SetColumnUnloaded(uint16_t chunkX_ws, uint16_t chunkZ_ws);
65 
67  virtual void SetLightGridSize(int nSize);
68 
76  virtual int ForceAddChunkColumn(int nChunkWX, int nChunkWZ);
77 
79  virtual int GetForcedChunkColumnCount();
80  public:
82  bool IsAsyncLightCalculation() const;
83  void SetAsyncLightCalculation(bool val);
84 
86  bool IsChunkColumnLoadedWorldPos(int nWorldX, int nWorldY, int nWorldZ);
88  bool IsChunkColumnLoaded(int nChunkX, int nChunkZ);
89 
90  /* whether this light block is marked dirty. please note only call this functionin light thread, since there is no lock on this function. */
91  bool IsLightDirty(Uint16x3& blockId_ws);
92 
93  private:
94  /*
95  * @param nUpdateRange: currently only 0 and 1 are supported.
96  * @return false if block world is exiting.
97  */
98  bool RefreshLight(const Uint16x3& blockId, bool isSunLight, int32 nUpdateRange = 0, Scoped_ReadLock<BlockReadWriteLock>* Lock_= NULL, int* pnCpuYieldCount = NULL);
99 
100  void AddPointToAABB(const Uint16x3 &curBlockPos, Int32x3 &minDirtyBlockId_ws, Int32x3 &maxDirtyBlockId_ws);
101 
102  void SetChunksDirtyInAABB(Int32x3 & minDirtyBlockId_ws, Int32x3 & maxDirtyBlockId_ws);
103 
105  void EmitSunLight(uint16_t blockIdX_ws,uint16_t blockIdZ_ws, bool bInitialSet=false);
106 
108  void LightThreadProc();
109 
110  void SetLightingInChunkColumnInitialized(uint16_t chunkX_ws, uint16_t chunkBlockZ);
111 
112  void RemoveDirtyColumn(const ChunkLocation& curChunkId_ws);
113 
117  void StartLightThread();
118 
120  void DoQuickSunLightValues(int chunkX, int chunkZ);
122  void CheckDoQuickSunLightValues(int chunkX, int chunkZ);
123 
124  /* compute light value according to the nearby 6 blocks. */
125  int32 ComputeLightValue(uint16 x, uint16 y, uint16 z, bool isSunLight = false);
126  /* Returns whether a block above this one can reach to the sky (by checking the height map) */
127  bool CanBlockSeeTheSky(uint16 x, uint16 y, uint16 z);
129  int32 GetSavedLightValue(int32 x, int32 y, int32 z, bool isSunLight);
131  int32 GetBlockOpacity(int32 x, int32 y, int32 z);
132  void SetLightValue(uint16_t x, uint16_t y, uint16_t z, int nLightValue, bool isSunLight);
133 
134  public:
140  private:
141  //first cached block
142  int32_t m_minLightBlockIdX;
143  int32_t m_minLightBlockIdZ;
144  //last cached block
145  int32_t m_maxLightBlockIdX;
146  int32_t m_maxLightBlockIdZ;
147 
148  //fist cached chunk
149  int32_t m_minChunkIdX_ws;
150  int32_t m_minChunkIdZ_ws;
151  int32_t m_maxChunkIdX_ws;
152  int32_t m_maxChunkIdZ_ws;
153 
154  int32_t m_centerChunkIdX_ws;
155  int32_t m_centerChunkIdZ_ws;
156  // dirty blocks since last frame's calculation
157  uint32 m_nDirtyBlocksCount;
158 
159  // temporary array used by Relight function
160  std::vector<LightBlock> m_blocksNeedLightRecalcuation;
161 
162  std::map<uint64_t, Light, std::greater<uint64_t>, DL_Allocator_BlockLight> m_dirtyCells;
163 
164  typedef std::unordered_set<ChunkLocation, ChunkLocation::ChunkLocationHasher> ChunkLocationSet_type;
165  ChunkLocationSet_type m_dirtyColumns;
167  std::vector< std::pair<ChunkLocation, int32_t> > m_closest_chunks;
169  std::vector< ChunkLocation > m_forced_chunks;
170 
171  std::set<uint32_t> m_loaded_columns;
173  ChunkLocationSet_type m_quick_loaded_columns;
174 
176  bool m_bIsLightThreadStarted;
177 
179  std::thread m_light_thread;
180 
182  bool m_bIsAsyncLightCalculation;
183 
184  std::recursive_mutex m_mutex;
185  };
186 }
virtual int ForceAddChunkColumn(int nChunkWX, int nChunkWZ)
function to refresh the a given chunk column.
Definition: BlockLightGridClient.cpp:728
bool IsAsyncLightCalculation() const
whether to calculate light in a separate thread.
Definition: BlockLightGridClient.cpp:1249
virtual int GetDirtyBlockCount()
get the number of remaining dirty blocks
Definition: BlockLightGridClient.cpp:1281
simple scoped read lock function
Definition: BlockReadWriteLock.h:123
virtual int GetForcedChunkColumnCount()
get the number of forced column still in the queue.
Definition: BlockLightGridClient.cpp:749
different physics engine has different winding order.
Definition: EventBinding.h:32
basic block world coordinate
Definition: BlockCoordinate.h:72
virtual void AddDirtyColumn(uint16_t chunkX_ws, uint16_t chunkZ_ws)
thread safe: update all blocks in the given chunk column.
Definition: BlockLightGridClient.cpp:1166
bool IsChunkColumnLoaded(int nChunkX, int nChunkZ)
thread safe:
Definition: BlockLightGridClient.cpp:1241
bool IsChunkColumnLoadedWorldPos(int nWorldX, int nWorldY, int nWorldZ)
thread safe: check to see if the block pos&#39;s light is already or being calculated.
Definition: BlockLightGridClient.cpp:1235
virtual void NotifyBlockHeightChanged(uint16_t blockIdX_ws, uint16_t blockIdZ_ws, ChunkMaxHeight &prevBlockHeight)
thread safe:
Definition: BlockLightGridClient.cpp:315
base class for an instance of block world
Definition: BlockWorld.h:35
virtual void SetColumnUnloaded(uint16_t chunkX_ws, uint16_t chunkZ_ws)
this is called when chunk column is loaded possibly due to region unload.
Definition: BlockLightGridClient.cpp:1198
int m_max_cells_left_per_frame
max number of cells(blocks) to left un-calculated per frame.
Definition: BlockLightGridClient.h:139
virtual int GetDirtyColumnCount()
thread safe: get the number of remaining dirty column
Definition: BlockLightGridClient.cpp:1183
virtual void SetColumnPreloaded(uint16_t chunkX_ws, uint16_t chunkZ_ws)
thread safe: set the given column loaded.
Definition: BlockLightGridClient.cpp:1189
int m_max_cells_per_frame
max number of cells(blocks) to calculate per frame.
Definition: BlockLightGridClient.h:136
virtual void SetLightGridSize(int nSize)
Set the light grid chunk size.
Definition: BlockLightGridClient.cpp:1259
virtual void SetLightDirty(Uint16x3 &blockId_ws, bool isSunLight, int8 nUpdateRange=0)
only call this function from main thread when you have a write lock on block world to ensure thread s...
Definition: BlockLightGridClient.cpp:269
for block or chunk location that does not has boundary check.
Definition: BlockCoordinate.h:123
chunk column location.
Definition: BlockCoordinate.h:145
base class for block light grid.
Definition: BlockLightGridBase.h:37
block grid on client side.
Definition: BlockLightGridClient.h:22
chunk column&#39;s height map data
Definition: ChunkMaxHeight.h:6