3#include <glm/gtc/constants.hpp>
11TrailVertex vertex(
float x,
float z,
float u,
float v,
float alpha) {
12 return {{
x, 0.f,
z}, {
u,
v}, alpha};
15void appendFan(TrailMeshSnapshot&
mesh,
float radius,
float startAngle,
float angle,
16 std::uint32_t segments,
float centerAlpha,
float edgeAlpha) {
17 mesh.vertices.reserve(
static_cast<std::size_t
>(segments) + 2u);
18 mesh.indices.reserve(
static_cast<std::size_t
>(segments) * 3u);
19 mesh.vertices.push_back(vertex(0.f, 0.f, 0.5f, 0.5f, centerAlpha));
20 for (std::uint32_t i = 0; i <= segments; ++i) {
21 const float t =
static_cast<float>(i) /
static_cast<float>(segments);
22 const float radians = startAngle +
angle *
t;
23 const float x = std::cos(radians) *
radius;
24 const float z = std::sin(radians) *
radius;
25 mesh.vertices.push_back(vertex(
x,
z,
x / (2.f *
radius) + 0.5f,
26 z / (2.f *
radius) + 0.5f, edgeAlpha));
27 if (i > 0)
mesh.indices.insert(
mesh.indices.end(), {0u, i, i + 1u});
31void appendRing(TrailMeshSnapshot&
mesh,
float innerRadius,
float outerRadius,
32 std::uint32_t segments,
float innerAlpha,
float outerAlpha) {
33 mesh.vertices.reserve((
static_cast<std::size_t
>(segments) + 1u) * 2u);
34 mesh.indices.reserve(
static_cast<std::size_t
>(segments) * 6u);
35 for (std::uint32_t i = 0; i <= segments; ++i) {
36 const float t =
static_cast<float>(i) /
static_cast<float>(segments);
37 const float radians = glm::two_pi<float>() *
t;
38 const float c = std::cos(radians);
39 const float s = std::sin(radians);
40 mesh.vertices.push_back(vertex(
c * innerRadius,
s * innerRadius,
t, 0.f, innerAlpha));
41 mesh.vertices.push_back(vertex(
c * outerRadius,
s * outerRadius,
t, 1.f, outerAlpha));
43 const std::uint32_t inner0 = (i - 1u) * 2u;
44 const std::uint32_t outer0 = inner0 + 1u;
45 const std::uint32_t inner1 = i * 2u;
46 const std::uint32_t outer1 = inner1 + 1u;
47 mesh.indices.insert(
mesh.indices.end(),
48 {inner0, outer0, inner1, inner1, outer0, outer1});
58 if (!commonValid)
return result;
60 switch (config.
shape) {
62 if (!std::isfinite(config.
radius) || config.
radius <= 0.f)
return result;
63 appendFan(result.
mesh, config.
radius, 0.f, glm::two_pi<float>(),
84 if (!std::isfinite(config.
width) || !std::isfinite(config.
length) ||
AreaIndicatorBuildResult buildAreaIndicator(const AreaIndicatorConfig &config)
Generate a local-XZ area indicator compatible with dynamic mesh submission.
Owning local-space mesh and terminal build status.
AreaIndicatorBuildStatus status
Geometry and edge-fade controls for one local-XZ area indicator.
std::vector< std::uint32_t > indices
std::vector< TrailVertex > vertices