1#include "Platform/Instrumentation.h"
2#include "Services/TaskManager.h"
5#include "MarchingCubesTables.h"
6#include "IsoSurfaces_internal.h"
8#include "Foundation/Platform/Timer.h"
9#include "Foundation/Platform/Threads.h"
16 const uint8_t* axesTable =
nullptr;
17 const uint8_t* activeCellCases =
nullptr;
18 const int32_t* activeCellVertexOffsets =
nullptr;
19 const int32_t* activeCellIndices =
nullptr;
25 std::atomic<uint64_t>* elapsed_us =
nullptr;
26 Cogs::Core::IsoSurfaces::VertexEmitFunc emit;
30 CpuInstrumentationScope(SCOPE_ISOSURFACES,
"ExtVtx");
31 auto timer = Cogs::Timer::startNew();
33 glm::ivec4 samples[4];
34 for (
int c = ca; c < cb; c++) {
35 auto oc = activeCellVertexOffsets[c];
36 const auto on = activeCellVertexOffsets[c + 1];
37 if (oc == on)
continue;
39 auto ijk = activeCellIJK[c];
43 auto i = glm::ivec3(ijk.i, ijk.j, ijk.k) + gridA;
54 samples[2][1] = i.z + 1;
55 uint32_t ixN = ((axes & 4) != 0) ? 1 : 0;
57 samples[0][1 + ixN] = i.x;
58 samples[1][1 + ixN] = i.y + 1;
59 samples[2][1 + ixN] = i.z;
60 ixN += ((axes & 2) != 0) ? 1 : 0;
62 samples[0][1 + ixN] = i.x + 1;
63 samples[1][1 + ixN] = i.y;
64 samples[2][1 + ixN] = i.z;
65 ixN += ((axes & 1) != 0) ? 1 : 0;
67 emit(oc, samples, ixN);
80 if (elapsed_us !=
nullptr) {
81 elapsed_us->fetch_add(timer.elapsedMicroseconds());
89void Cogs::Core::IsoSurfaces::extractVertices(Context* context,
91 VertexEmitFunc emitFunc,
92 const uint8_t* activeCellCases,
93 const int32_t* activeCellVertexOffsets,
94 const int32_t* activeCellIndices,
95 const Scratch::ijk_t* activeCellIJK,
96 const int32_t activeCellCount,
97 const glm::ivec3 gridA,
98 const glm::ivec3 gridB,
99 std::atomic<uint64_t>* elapsed_us)
101 const auto & axesTable = MarchingCubes::axesTable();
102 const glm::ivec3 M = gridB - gridA;
104 const auto Q =
static_cast<int>(Threads::hardwareConcurrency());
105 const auto taskSize = std::max(1024, (activeCellCount + Q - 1) / Q);
106 for (
int c = 0; c < activeCellCount; c += taskSize) {
109 task.context = context;
110 task.axesTable = axesTable.data();
111 task.activeCellCases = activeCellCases;
112 task.activeCellVertexOffsets = activeCellVertexOffsets;
113 task.activeCellIndices = activeCellIndices;
114 task.activeCellIJK = activeCellIJK;
118 task.cb = std::min(c + taskSize, activeCellCount);
119 task.elapsed_us = elapsed_us;
120 task.emit = emitFunc;
122 context->taskManager->enqueueChild(group, task);
A Context instance contains all the services, systems and runtime components needed to use Cogs.