Cogs.Core
ExtractVertices.cpp
1#include "Platform/Instrumentation.h"
2#include "Services/TaskManager.h"
3#include "Context.h"
4
5#include "MarchingCubesTables.h"
6#include "IsoSurfaces_internal.h"
7
8#include "Foundation/Platform/Timer.h"
9#include "Foundation/Platform/Threads.h"
10
11namespace {
12
13 struct ExtractVtxTask
14 {
15 Cogs::Core::Context* context = nullptr;
16 const uint8_t* axesTable = nullptr;
17 const uint8_t* activeCellCases = nullptr;
18 const int32_t* activeCellVertexOffsets = nullptr;
19 const int32_t* activeCellIndices = nullptr;
20 const Cogs::Core::IsoSurfaces::Scratch::ijk_t* activeCellIJK = nullptr;
21 glm::ivec3 M;
22 glm::ivec3 gridA;
23 int ca = 0;
24 int cb = 0;
25 std::atomic<uint64_t>* elapsed_us = nullptr;
26 Cogs::Core::IsoSurfaces::VertexEmitFunc emit;
27
28 void operator()()
29 {
30 CpuInstrumentationScope(SCOPE_ISOSURFACES, "ExtVtx");
31 auto timer = Cogs::Timer::startNew();
32
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;
38
39 auto ijk = activeCellIJK[c];
40
41 //auto q = activeCellIndices[c];
42 //auto i = delinarize(q, M, gridA);
43 auto i = glm::ivec3(ijk.i, ijk.j, ijk.k) + gridA;
44
45 auto axes = ijk.axes;// axesTable[code];
46
47
48 samples[0][0] = i.x;
49 samples[1][0] = i.y;
50 samples[2][0] = i.z;
51
52 samples[0][1] = i.x;
53 samples[1][1] = i.y;
54 samples[2][1] = i.z + 1;
55 uint32_t ixN = ((axes & 4) != 0) ? 1 : 0;
56
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;
61
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;
66
67 emit(oc, samples, ixN);
68
69 /* if (axes & 4) {
70 emit(oc++, i, i + ivec3(0, 0, 1));
71 }
72 if (axes & 2) {
73 emit(oc++, i, i + ivec3(0, 1, 0));
74 }
75 if (axes & 1) {
76 emit(oc++, i, i + ivec3(1, 0, 0));
77 }*/
78 }
79
80 if (elapsed_us != nullptr) {
81 elapsed_us->fetch_add(timer.elapsedMicroseconds());
82 }
83 }
84 };
85
86}
87
88
89void Cogs::Core::IsoSurfaces::extractVertices(Context* context,
90 TaskId group,
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)
100{
101 const auto & axesTable = MarchingCubes::axesTable();
102 const glm::ivec3 M = gridB - gridA;
103
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) {
107
108 ExtractVtxTask task;
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;
115 task.M = M;
116 task.gridA = gridA;
117 task.ca = c;
118 task.cb = std::min(c + taskSize, activeCellCount);
119 task.elapsed_us = elapsed_us;
120 task.emit = emitFunc;
121
122 context->taskManager->enqueueChild(group, task);
123 }
124}
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83