1#include "CullingManager.h"
5#include "Services/TaskManager.h"
7#include "Systems/Core/CameraSystem.h"
8#include "Systems/Core/RenderSystem.h"
9#include "Systems/Core/TransformSystem.h"
10#include "Systems/Core/SubMeshRenderSystem.h"
11#include "Systems/Core/StaticModelSystem.h"
12#include "Systems/Core/InstancedMeshRenderSystem.h"
14void Cogs::Core::CullingManager::initializeCulling()
17 context->renderSystem->initializeCulling(&source);
18 context->subMeshRenderSystem->initializeCulling(&source);
19 context->staticModelSystem->initializeCulling(&source);
20 context->instancedMeshRenderSystem->initializeCulling(&source);
24void Cogs::Core::CullingManager::dispatchCulling(CameraData * viewportData)
26 if (!viewportData->cullingData) {
27 viewportData->cullingData = std::shared_ptr<CullingData>(context->cameraSystem->cullingData.create(), [
this](CullingData * cd)
29 if (cd->task.isValid()) {
30 context->taskManager->destroy(cd->task);
33 context->cameraSystem->cullingData.destroy(cd);
37 const size_t count = source.count;
39 auto cullData = viewportData->cullingData.get();
40 cullData->viewMatrix = viewportData->viewMatrix;
41 cullData->viewProjection = viewportData->rawProjectionMatrix * viewportData->viewMatrix;
42 cullData->context = context;
43 cullData->source = &source;
44 cullData->results.resize(count);
45 cullData->depths.resize(count);
46 if (!cullData->task.isValid()) {
47 cullData->task = context->taskManager->createGroup();
52 const size_t batchSize = 1024;
53 const size_t batches = (count / batchSize) + 1;
55 for (
size_t i = 0; i < batches; ++i) {
56 const size_t start = i * batchSize;
57 const size_t end = std::min((i + 1) * batchSize, count);
59 if (0.f < viewportData->discardThreshold) {
60 context->taskManager->enqueueChild(cullData->task,
64 discardThresholdSqr = viewportData->discardThreshold,
65 keepThreshold = viewportData->keepThreshold]()
67 CpuInstrumentationScope(SCOPE_SYSTEMS,
"MeshRenderSystem::culling");
69 const auto * source = cullData->source;
70 for (size_t i = start; i < end; ++i) {
71 glm::vec3 bbMinWorld = source->bbMinWorld[i];
72 glm::vec3 bbMaxWorld = source->bbMaxWorld[i];
74 cullData->results[i] = frustumClassifyBoundingBox(cullData->viewProjection,
80 glm::vec4 p = cullData->viewProjection * glm::vec4(0.5f * (bbMinWorld + bbMaxWorld), 1.f);
81 cullData->depths[i] = p.z / p.w;
85 context->taskManager->enqueueChild(cullData->task, [cullData, start, end]() {
86 CpuInstrumentationScope(SCOPE_SYSTEMS,
"MeshRenderSystem::culling");
88 const auto * source = cullData->source;
89 for (size_t i = start; i < end; ++i) {
90 glm::vec3 bbMinWorld = source->bbMinWorld[i];
91 glm::vec3 bbMaxWorld = source->bbMaxWorld[i];
93 cullData->results[i] = frustumClassifyBoundingBox(cullData->viewProjection,
94 bbMinWorld, bbMaxWorld);
96 glm::vec4 p = cullData->viewProjection * glm::vec4(0.5f * (bbMinWorld + bbMaxWorld), 1.f);
97 cullData->depths[i] = p.z / p.w;