Cylindrical projection around a world axis.
u = azimuth angle in [0, 1], wraps at the seam behind the axis. v = axial distance / height, unbounded — tiles vertically.
Vertices straddling the seam (angle wraps π to -π) will show a UV discontinuity. Orient geometry or rotate axis to push the seam to a non-visible region.
62{
63 const glm::vec3 n = glm::normalize(axis);
64
65 const glm::vec3 tangent = (std::abs(n.y) <= std::abs(n.x) && std::abs(n.y) <= std::abs(n.z))
66 ? glm::normalize(glm::cross(n, glm::vec3(0.0F, 1.0F, 0.0F)))
67 : glm::
normalize(glm::cross(n, glm::vec3(1.0F, 0.0F, 0.0F)));
68
69 const glm::vec3 bitangent = glm::cross(n, tangent);
70
71 const float inv_radius = (radius > 1e-6F) ? (1.0F / radius) : 1.0F;
72 const float inv_height = (height > 1e-6F) ? (1.0F / height) : 1.0F;
73
74 return { .fn = [n, tangent, bitangent, origin, inv_radius, inv_height](const glm::vec3& p) -> glm::vec2 {
75 const glm::vec3 d = p - origin;
76 const float axial = glm::dot(d, n);
77 const float radial_x = glm::dot(d, tangent) * inv_radius;
78 const float radial_y = glm::dot(d, bitangent) * inv_radius;
79 const float u = (glm::atan(radial_y, radial_x) / static_cast<float>(std::numbers::pi) + 1.0F) * 0.5F;
80 const float v = axial * inv_height;
81 return { u, v };
82 } };
83}
void normalize(std::vector< double > &data, double target_peak)
Normalize single-channel data to specified peak level (in-place)