1#include "Platform/Instrumentation.h"
3#include "../Extensions/IsoSurfaces/IsoSurfaces.h"
5#include "Resources/Buffer.h"
9#include "../Tasks/DensityFieldTask.h"
10#include "../Systems/DensityFieldSystem.h"
12#include "Foundation/Platform/Timer.h"
14void Cogs::Core::Volumetric::DensityFieldTaskData::update(Context * ctx,
15 DensityFieldComponent &fieldComp,
16 DensityFieldData& fieldData,
17 BufferView<glm::vec3> positions,
18 BufferView<float> data)
20 CpuInstrumentationScope(SCOPE_VOLUMETRIC,
"DensityTask::update");
24 thresholds = fieldComp.thresholds;
25 if (16 < thresholds.size()) thresholds.resize(16);
27 resolution = fieldData.resolution;
29 dataAttached = fieldComp.attachData
31 && data.size() == positions.size();
33 const auto extent = fieldComp.extentMax - fieldComp.extentMin;
34 const auto cellSize = glm::vec3(1.f / fieldComp.resolution.x,
35 1.f / fieldComp.resolution.y,
36 1.f / fieldComp.resolution.z)*extent;
39 densityWeight = fieldComp.pointWeight;
40 boxFilterWidth = Blur::boxFilterWidthFromStdDev(fieldComp.basisStdDev / glm::max(glm::max(cellSize.x, cellSize.y), cellSize.z),
41 fieldComp.basisQuality);
42 boxFilterIterations = fieldComp.basisQuality;
43 extentMin = fieldComp.extentMin;
44 extentMax = fieldComp.extentMax;
46 rPositions.resize(positions.size());
47 rData.resize(positions.size());
49 std::memcpy(rPositions.data(), positions.data(), rPositions.size() *
sizeof(glm::vec3));
51 std::memcpy(rData.data(), data.data(), rData.size() *
sizeof(
float));
54 attachedDataScale = fieldComp.attachedDataScale;
55 attachedDataOffset = fieldComp.attachedDataOffset;
58void Cogs::Core::Volumetric::DensityFieldTask::operator()()
60 CpuInstrumentationScope(SCOPE_VOLUMETRIC,
"DensityTask::compute");
62 auto & data = *persistentData.get();
64 const glm::vec3 s = glm::vec3(data.resolution) / (data.extentMax - data.extentMin);
65 const glm::vec3 o = -data.extentMin;
66 const auto dts = data.attachedDataScale;
67 const auto dto = data.attachedDataOffset;
70 data.points.reserve(data.rPositions.size());
72 for (
size_t i = 0; i < data.rPositions.size(); i++) {
73 glm::uvec3 k(s*(data.rPositions.data()[i] + o));
74 if ((k.x < data.resolution.x)
75 && (k.y < data.resolution.y)
76 && (k.z < data.resolution.z)) {
77 data.points.push_back({ k, data.dataAttached ? dts * (data.rData.data()[i] + dto) : 0.f });
81 const auto X = data.resolution.x;
82 const auto Y = data.resolution.y;
83 const auto Z = data.resolution.y;
84 const auto numCells = X * Y * Z;
85 const auto w = data.densityWeight;
87 data.densityField.resize(numCells,
false);
88 std::memset(data.densityField.data(), 0, data.densityField.byteSize());
90 auto phi = data.densityField.data();
91 for (
auto & p : data.points) {
92 phi[(p.ix.z*Y + p.ix.y)*X + p.ix.x] += w;
95 data.densityFieldOut.resize(numCells,
false);
96 Blur::boxFilterIterations3D(data.context,
97 data.densityFieldOut.data(),
98 data.densityField.data(),
101 data.boxFilterIterations);
103 if (data.dataAttached) {
104 data.dataField.resize(numCells);
105 std::memset(data.dataField.data(), 0, data.dataField.byteSize());
107 auto F = data.dataField.data();
109 for (
auto & p : data.points) {
110 F[(p.ix.z*Y + p.ix.y)*X + p.ix.x] += w * p.data;
113 data.dataFieldOut.resize(numCells);
114 Blur::boxFilterIterations3D(data.context,
115 data.dataFieldOut.data(),
116 data.dataField.data(),
119 data.boxFilterIterations);
122 IsoSurfaces::Scratch scratch;
123 data.mesh = IsoSurfaces::createIsoSurfacesMesh(data.context,
126 data.densityFieldOut.data(),
127 data.dataAttached ? data.dataFieldOut.data() :
nullptr,
129 data.extentMin, data.extentMax,
false,
false,
true,
true,
true,
true,
true,
true,