-
Notifications
You must be signed in to change notification settings - Fork 11
/
EveryCulling.h
236 lines (193 loc) · 7.68 KB
/
EveryCulling.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
#pragma once
#include "EveryCullingCore.h"
#include "DataType/EntityGridCell.h"
#include "DataType/EntityBlockViewer.h"
#include "DataType/Math/Vector.h"
#include "DataType/Math/Matrix.h"
#ifdef EVERYCULLING_PROFILING_CULLING
#include "EveryCullingProfiler.h"
#endif
#include <array>
#include <vector>
#include <memory>
namespace culling
{
class CullingModule;
class ViewFrustumCulling;
class ScreenSpaceBoundingSphereCulling;
class MaskedSWOcclusionCulling;
class QueryOcclusionCulling;
class PreCulling;
class DistanceCulling;
struct EntityBlock;
class EveryCulling
{
private:
std::atomic<std::uint32_t> mRunningThreadCount;
size_t mCameraCount;
std::array<culling::Mat4x4, EVERYCULLING_MAX_CAMERA_COUNT> mCameraModelMatrixes;
std::array<culling::Mat4x4, EVERYCULLING_MAX_CAMERA_COUNT> mCameraViewProjectionMatrixes;
std::array<culling::Vec3, EVERYCULLING_MAX_CAMERA_COUNT> mCameraWorldPositions;
std::array<culling::Vec4, EVERYCULLING_MAX_CAMERA_COUNT> mCameraRotations;
std::array<float, EVERYCULLING_MAX_CAMERA_COUNT> mCameraFieldOfView;
std::array<float, EVERYCULLING_MAX_CAMERA_COUNT> mFarClipPlaneDistance;
std::array<float, EVERYCULLING_MAX_CAMERA_COUNT> mNearClipPlaneDistance;
bool bmIsEntityBlockPoolInitialized;
/// <summary>
/// List of EntityBlock with no entity ( maybe entity was destroyed)
/// </summary>
std::vector<EntityBlock*> mFreeEntityBlockList;
/// <summary>
/// List of EntityBlock containing Entities
/// </summary>
std::vector<EntityBlock*> mActiveEntityBlockList;
/// <summary>
/// Allocated EntityBlock Arrays
/// This objects will be released at destructor
/// </summary>
std::vector<EntityBlock*> mAllocatedEntityBlockChunkList;
std::uint64_t mEntityBlockUniqueIDCounter;
void AllocateEntityBlockPool();
culling::EntityBlock* AllocateNewEntityBlockFromPool();
void RemoveEntityFromBlock(EntityBlock* ownerEntityBlock, std::uint32_t entityIndexInBlock);
/// <summary>
/// Block Swap removedblock with last block, and return swapped lastblock to pool
/// </summary>
void FreeEntityBlock(EntityBlock* freedEntityBlock);
EntityBlock* GetNewEntityBlockFromPool();
void ResetCullingModules();
/// <summary>
/// Reset VisibleFlag
/// </summary>
void ResetEntityBlocks();
public:
std::unique_ptr<PreCulling> mPreCulling;
std::unique_ptr<DistanceCulling> mDistanceCulling;
std::unique_ptr<ViewFrustumCulling> mViewFrustumCulling;
std::unique_ptr<MaskedSWOcclusionCulling> mMaskedSWOcclusionCulling;
#ifdef EVERYCULLING_PROFILING_CULLING
EveryCullingProfiler mEveryCullingProfiler;
#endif
private:
unsigned long long mCurrentTickCount;
std::vector<culling::CullingModule*> mUpdatedCullingModules;
// this function is called by multiple threads
void OnStartCullingModule(const culling::CullingModule* const cullingModule);
// this function is called by multiple threads
void OnEndCullingModule(const culling::CullingModule* const cullingModule);
void SetViewProjectionMatrix(const size_t cameraIndex, const culling::Mat4x4& viewProjectionMatrix);
void SetFieldOfViewInDegree(const size_t cameraIndex, const float fov);
void SetCameraNearFarClipPlaneDistance(const size_t cameraIndex, const float nearPlaneDistance, const float farPlaneDistance);;
void SetCameraWorldPosition(const size_t cameraIndex, const culling::Vec3& cameraWorldPos);
void SetCameraRotation(const size_t cameraIndex, const culling::Vec4& cameraRotation);
public:
enum class CullingModuleType
{
PreCulling,
ViewFrustumCulling,
MaskedSWOcclusionCulling,
DistanceCulling
};
EveryCulling() = delete;
EveryCulling(const std::uint32_t resolutionWidth, const std::uint32_t resolutionHeight);
EveryCulling(const EveryCulling&) = delete;
EveryCulling& operator=(const EveryCulling&) = delete;
~EveryCulling();
void SetCameraCount(const size_t cameraCount);
unsigned long long GetTickCount() const;
struct GlobalDataForCullJob
{
culling::Mat4x4 mViewProjectionMatrix;
float mFieldOfViewInDegree;
float mCameraNearPlaneDistance;
float mCameraFarPlaneDistance;
culling::Vec3 mCameraWorldPosition;
culling::Vec4 mCameraRotation;
};
/**
* \brief Update global data for cull job. Should be called every frame.
* \param cameraIndex
* \param settingParameters
*/
void UpdateGlobalDataForCullJob(const size_t cameraIndex, const GlobalDataForCullJob& settingParameters);
EVERYCULLING_FORCE_INLINE size_t GetCameraCount() const
{
return mCameraCount;
}
EVERYCULLING_FORCE_INLINE const culling::Vec3& GetCameraWorldPosition(const size_t cameraIndex) const
{
assert(cameraIndex >= 0 && cameraIndex < EVERYCULLING_MAX_CAMERA_COUNT);
return mCameraWorldPositions[cameraIndex];
}
EVERYCULLING_FORCE_INLINE const culling::Mat4x4& GetCameraModelMatrix(const size_t cameraIndex) const
{
assert(cameraIndex >= 0 && cameraIndex < EVERYCULLING_MAX_CAMERA_COUNT);
return mCameraModelMatrixes[cameraIndex];
}
EVERYCULLING_FORCE_INLINE const culling::Mat4x4& GetCameraViewProjectionMatrix(const size_t cameraIndex) const
{
assert(cameraIndex >= 0 && cameraIndex < EVERYCULLING_MAX_CAMERA_COUNT);
return mCameraViewProjectionMatrixes[cameraIndex];
}
EVERYCULLING_FORCE_INLINE float GetCameraFieldOfView(const size_t cameraIndex) const
{
assert(cameraIndex >= 0 && cameraIndex < EVERYCULLING_MAX_CAMERA_COUNT);
return mCameraFieldOfView[cameraIndex];
}
EVERYCULLING_FORCE_INLINE float GetCameraFarClipPlaneDistance(const size_t cameraIndex) const
{
assert(cameraIndex >= 0 && cameraIndex < EVERYCULLING_MAX_CAMERA_COUNT);
return mFarClipPlaneDistance[cameraIndex];
}
EVERYCULLING_FORCE_INLINE float GetCameraNearClipPlaneDistance(const size_t cameraIndex) const
{
assert(cameraIndex >= 0 && cameraIndex < EVERYCULLING_MAX_CAMERA_COUNT);
return mNearClipPlaneDistance[cameraIndex];
}
/// <summary>
/// Get EntityBlock List with entities
/// </summary>
/// <returns></returns>
const std::vector<EntityBlock*>& GetActiveEntityBlockList() const;
size_t GetActiveEntityBlockCount() const;
/// <summary>
/// You should call this function on your Transform Component or In your game engine
///
/// increment EntityCountInBlock of TargetBlock.
/// If All blocks is full, Get new block from Block Pool
///
/// Allocating New Entity isn't thread safe
/// </summary>
EntityBlockViewer AllocateNewEntity();
/// <summary>
/// You should call this function on your Transform Component or In your game engine
///
/// Remove Entity is nothing, Just decrement AllocatedEntityCountInBlocks
/// And if AllocatedEntityCountInBlocks Of Block become zero, Remove the block using RemoveBlock function
///
/// Removing Entity isn't thread safe
/// </summary>
void RemoveEntityFromBlock(EntityBlockViewer& entityBlockViewer);
void ThreadCullJob(const size_t cameraIndex, const unsigned long long tickCount);
//void ThreadCullJob(const std::uint32_t threadIndex, const std::uint32_t threadCount);
/// <summary>
/// Caller thread will stall until cull job of all entity block is finished
/// </summary>
void WaitToFinishCullJob(const std::uint32_t cameraIndex) const;
void WaitToFinishCullJobOfAllCameras() const;
/**
* \brief Reset cull job. Should be called every frame after finish cull job
*/
void PreCullJob();
auto GetThreadCullJob(const size_t cameraIndex, const unsigned long long tickCount)
{
return [this, cameraIndex, tickCount]()
{
this->ThreadCullJob(cameraIndex, tickCount);
};
}
const culling::CullingModule* GetLastEnabledCullingModule() const;
void SetEnabledCullingModule(const CullingModuleType cullingModuleType, const bool isEnabled);
std::uint32_t GetRunningThreadCount() const;
};
}