1#include "Services/TaskManager.h"
2#include "OctProviderBuildTileTask.h"
3#include "../../../Volumetric/Source/Components/OctComponent.h"
4#include "../BeamUtils.h"
8void Cogs::Core::EchoSounder::OctProviderBuildTileTask::operator()()
10 CpuInstrumentationScope(SCOPE_ECHOSOUNDER,
"OctBuild");
11 auto & res = persistent->responses[index];
12 const auto & N = res->N;
13 auto * context = persistent->context;
19 age.resize(N.x*N.y*N.z,
false);
20 res->data1.resize(N.x*N.y*N.z,
false);
23 const auto taskCount = persistent->taskCount[index];
24 for (
unsigned subTask = 0; subTask < taskCount; subTask++) {
25 auto a = (subTask * N.z) / taskCount;
26 auto b = std::min(N.z, ((subTask + 1)*N.z) / taskCount);
27 context->taskManager->enqueueChild(group,
28 OctProviderBuildSubTileTask{
this,
34 persistent->context->taskManager->wait(group);
36 res->data0.resize(N.x*N.y*N.z,
false);
37 calcGradients(res->data0, res->data1, age, N);
40void Cogs::Core::EchoSounder::OctProviderBuildSubTileTask::operator()()
46void Cogs::Core::EchoSounder::OctProviderBuildTileTask::setup(std::vector<Misc>& m)
48 CpuInstrumentationScope(SCOPE_ECHOSOUNDER,
"OctBuild_setup");
49 auto & res = persistent->responses[index];
52 std::vector<SrcPing> pings;
53 pings.reserve(res->regionKeys.size());
54 for (
auto regionKey : res->regionKeys) {
56 decodeKey2(src, ping, regionKey);
57 auto it = persistent->pingCache.find(encodeKey2(persistent->groupCache[src].dataId, ping));
58 assert(it != persistent->pingCache.end());
59 assert(it->second->linearized);
60 pings.push_back(SrcPing{ it->second.get(), src });
62 std::sort(pings.begin(), pings.end(), [](
const auto &a,
const auto & b) { return a.ping->timestamp > b.ping->timestamp; });
63 res->clientData = pings[0].ping->timestamp;
65 std::vector<Misc> tmp;
66 tmp.resize(pings.size());
67 for (
size_t i = 0; i <tmp.size(); i++) {
70 misc.ping = pings[i].ping;
71 const auto & grp = persistent->groupCache[pings[i].src];
73 const auto minDistance = misc.ping->depthOffset;
74 const auto maxDistance = minDistance + misc.ping->sampleCount * misc.ping->depthStep;
77 getBoundingFrustum(frustum,
78 misc.ping->metaPing.arrayOrientationGlobal,
79 misc.ping->metaPing.arrayPositionGlobal,
81 grp.minDirectionX, grp.maxDirectionX,
82 grp.minDirectionY, grp.maxDirectionY,
83 minDistance, maxDistance);
85 for (
unsigned k = 0; k < 4; k++) {
86 misc.boundingFrustumNormals[k] = glm::vec3(frustum[k]);
88 misc.inverseOrientation = glm::inverse(misc.ping->metaPing.arrayOrientationGlobal);
89 misc.shift = misc.ping->metaPing.arrayPositionGlobal - res->min;
90 misc.minDistanceSquared = minDistance * minDistance;
91 misc.maxDistanceSquared = maxDistance * maxDistance;
93 misc.maxIndices = glm::uvec3(glm::max(1u, grp.minorCount) - 1u,
94 glm::max(1u, grp.majorCount) - 1u,
95 glm::max(1u, misc.ping->sampleCount) - 1u);
97 misc.polarShift = glm::vec3(grp.minDirectionY,
100 misc.polarScale = glm::vec3((glm::max(2u, grp.minorCount) - 2u) / (grp.maxDirectionY - grp.minDirectionY),
101 (glm::max(2u, grp.majorCount) - 2u) / (grp.maxDirectionX - grp.minDirectionX),
102 (glm::max(2u, misc.ping->sampleCount) - 2u) / (maxDistance - minDistance));
103 misc.minorCount = grp.minorCount;
104 misc.sampleCount = misc.ping->sampleCount;
105 misc.v = misc.ping->linear.data();
121void Cogs::Core::EchoSounder::OctProviderBuildSubTileTask::sample()
123 CpuInstrumentationScope(SCOPE_ECHOSOUNDER,
"OctBuild_sample");
124 auto & res = parent->persistent->responses[parent->index];
125 auto & value = res->data1;
127 const auto & N = res->N;
128 const unsigned Np =
static_cast<unsigned>(m->size());
130 auto scale = (res->max - res->min)*glm::vec3(1.f / N.x,
135 for (
size_t k = a; k < b; k++) {
136 for (
size_t j = 0; j < N.y; j++) {
137 for (
size_t i = 0; i < N.x; i++) {
138 auto p = scale * glm::vec3(i + 0.5f,
144 for (
size_t l = 0; l < Np; l++) {
145 const auto & misc = (*m)[l];
146 const auto q = p - misc.shift;
147 const auto r2 = glm::dot(q, q);
149 bool in_0 = 0.f <= glm::dot(misc.boundingFrustumNormals[0], q);
150 bool in_1 = 0.f <= glm::dot(misc.boundingFrustumNormals[1], q);
151 bool in_2 = 0.f <= glm::dot(misc.boundingFrustumNormals[2], q);
152 bool in_3 = 0.f <= glm::dot(misc.boundingFrustumNormals[3], q);
153 bool in_4 = misc.minDistanceSquared <= r2;
154 bool in_5 = r2 <= misc.maxDistanceSquared;
155 if (!in_0 || !in_1 || !in_2 || !in_3 || !in_4 || !in_5) {
159 const auto a = misc.inverseOrientation * q;
160 const float r = std::sqrt(r2);
162 const float dirX = std::asin(a.x / r);
163 const float dirY = std::asin(a.y / r);
164 const auto polarPos = glm::vec3(dirY, dirX, r);
165 const auto xi = glm::max(glm::vec3(0.f), misc.polarScale*(polarPos - misc.polarShift));
168 const auto tau = glm::floor(xi);
169 const auto t = xi - tau;
170 const auto ii = glm::min(misc.maxIndices, glm::uvec3(tau));
171 const auto jj = glm::min(glm::uvec2(misc.maxIndices), glm::uvec2(ii) + glm::uvec2(1));
173 const auto val00 = misc.v[(ii.y*misc.minorCount + ii.x)*misc.sampleCount + ii.z];
174 const auto val01 = misc.v[(jj.y*misc.minorCount + ii.x)*misc.sampleCount + ii.z];
175 const auto val0 = (1.f - t.y)*val00 + t.y*val01;
177 const auto val10 = misc.v[(ii.y*misc.minorCount + jj.x)*misc.sampleCount + ii.z];
178 const auto val11 = misc.v[(jj.y*misc.minorCount + jj.x)*misc.sampleCount + ii.z];
179 const auto val1 = (1.f - t.y)*val10 + t.y*val11;
181 v = (1.f - t.x)*val0 + t.x*val1;
182 e =
float(10e-7*((*m)[0].ping->timestamp - misc.ping->timestamp));
186 value[(k*N.y + j)*N.x + i] = v;
187 (*age)[(k*N.y + j)*N.x + i] = e;
195 CpuInstrumentationScope(SCOPE_ECHOSOUNDER,
"OctBuild_gradients");
197 for (
unsigned k = 0; k < N.z; k++) {
198 for (
unsigned j = 0; j < N.y; j++) {
199 for (
unsigned i = 0; i < N.x; i++) {
201 unsigned km = std::max(k, 1u) - 1;
202 unsigned kp = std::min(k + 1, N.z - 1);
203 unsigned jm = std::max(j, 1u) - 1;
204 unsigned jp = std::min(j + 1, N.y - 1);
205 unsigned im = std::max(i, 1u) - 1;
206 unsigned ip = std::min(i + 1, N.x - 1);
208 out[(k*N.y + j)*N.x + i] = glm::vec4((1.0 / (ip - im))*(in[(k*N.y + j)*N.x + ip] - in[(k*N.y + j)*N.x + im]),
209 (1.0 / (jp - jm))*(in[(k*N.y + jp)*N.x + i] - in[(k*N.y + jm)*N.x + i]),
210 (1.0 / (kp - km))*(in[(kp*N.y + j)*N.x + i] - in[(km*N.y + j)*N.x + i]),
211 age[(k*N.y + j)*N.x + i]);
static constexpr TaskQueueId ResourceQueue
Resource task queue.