215{
216 return std::visit([&variant](const auto& vec) -> std::optional<VertexAccess> {
217 using V = typename std::decay_t<decltype(vec)>::value_type;
218 const size_t count = vec.size();
219
221 MF_WARN(Journal::Component::Kakshya, Journal::Context::Runtime,
222 "as_vertex_access: empty variant");
223 return std::nullopt;
224 }
225
226 if constexpr (std::is_same_v<V, glm::vec3>) {
227 return VertexAccess { vec.data(),
count *
sizeof(glm::vec3),
228 position_only_layout(
static_cast<uint32_t
>(
count)) };
229 }
230
231 if constexpr (std::is_same_v<V, glm::vec2>) {
232 return VertexAccess { vec.data(),
count *
sizeof(glm::vec2),
233 position_2d_layout(
static_cast<uint32_t
>(
count)) };
234 }
235
236 if constexpr (std::is_same_v<V, glm::vec4>) {
237 return VertexAccess { vec.data(),
count *
sizeof(glm::vec4),
238 position_w_layout(
static_cast<uint32_t
>(
count)) };
239 }
240
241 if constexpr (DecimalData<V> || IntegerData<V>) {
242 if constexpr (std::is_same_v<V, double>) {
243 MF_TRACE(Journal::Component::Kakshya, Journal::Context::Runtime,
244 "as_vertex_access: double narrowed to float for vertex waveform");
245 }
246
247 std::vector<float> floats;
248 extract_from_variant<float>(variant, floats);
249
250 VertexAccess va;
251 va.conversion_buffer.resize(
count *
sizeof(glm::vec3));
252 floats_to_waveform(floats, va.conversion_buffer.data());
253 va.data_ptr = va.conversion_buffer.data();
254 va.byte_count = va.conversion_buffer.size();
255 va.layout = waveform_layout(
static_cast<uint32_t
>(
count));
256 return va;
257 }
258
259 if constexpr (std::is_same_v<V, std::complex<float>>) {
260 std::vector<float> magnitudes;
261 extract_from_variant<float>(variant, magnitudes,
262 ComplexConversionStrategy::MAGNITUDE);
263
264 constexpr float inv_pi = std::numbers::inv_pi_v<float>;
265 const float inv = (
count > 1) ? (2.0F /
static_cast<float>(
count - 1)) : 0.0F;
266
267 VertexAccess va;
268 va.conversion_buffer.resize(
count *
sizeof(glm::vec3));
269 auto* out = reinterpret_cast<glm::vec3*>(va.conversion_buffer.data());
270
271 for (
size_t i = 0; i <
count; ++i) {
272 out[i] = glm::vec3(
273 static_cast<float>(i) * inv - 1.0F,
274 magnitudes[i],
275 std::arg(vec[i]) * inv_pi);
276 }
277
278 va.data_ptr = va.conversion_buffer.data();
279 va.byte_count = va.conversion_buffer.size();
280 va.layout = waveform_layout(
static_cast<uint32_t
>(
count));
281 return va;
282 }
283
284 if constexpr (std::is_same_v<V, std::complex<double>>) {
285 MF_ERROR(Journal::Component::Kakshya, Journal::Context::Runtime,
286 "as_vertex_access: complex<double> rejected: convert to "
287 "complex<float> or extract components manually");
288 return std::nullopt;
289 }
290
291 if constexpr (std::is_same_v<V, glm::mat4>) {
292 MF_ERROR(Journal::Component::Kakshya, Journal::Context::Runtime,
293 "as_vertex_access: glm::mat4 rejected: unpack to vec4 columns first");
294 return std::nullopt;
295 }
296
297 return std::nullopt;
298 },
299 variant);
300}
#define MF_ERROR(comp, ctx,...)
#define MF_TRACE(comp, ctx,...)
#define MF_WARN(comp, ctx,...)