// TruVisuals Telemetry Gauge — a clean 270° HUD power gauge drawn in-shader.
// Keyframe "Power %" to sweep the needle + fill the arc.
// Pixel math verified in Python before shipping (identical result).

DEFINE_UI_PARAMS(power, Power %, DCTLUI_SLIDER_FLOAT, 65.0, 0.0, 100.0, 1.0)
DEFINE_UI_PARAMS(gcx, Center X, DCTLUI_SLIDER_FLOAT, 0.86, 0.0, 1.0, 0.005)
DEFINE_UI_PARAMS(gcy, Center Y, DCTLUI_SLIDER_FLOAT, 0.74, 0.0, 1.0, 0.005)
DEFINE_UI_PARAMS(gsize, Size, DCTLUI_SLIDER_FLOAT, 0.13, 0.03, 0.45, 0.005)

__DEVICE__ float3 over3(float3 base, float3 col, float a)
{
    a = _saturatef(a);
    return make_float3(base.x * (1.0f - a) + col.x * a,
                       base.y * (1.0f - a) + col.y * a,
                       base.z * (1.0f - a) + col.z * a);
}

__DEVICE__ float band(float x, float c, float hw, float pxper)
{
    return _saturatef((hw - _fabs(x - c)) / (1.5f * pxper) + 0.5f);
}

__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
{
    float Hf = (float)p_Height;
    float pxper = 1.0f / Hf;
    float px = (float)p_X / Hf;
    float py = (float)p_Y / Hf;
    float cx = gcx * (float)p_Width / Hf;
    float cy = gcy;
    float dx = px - cx;
    float dy = cy - py;                       // y-up
    float r = _sqrtf(dx * dx + dy * dy);
    float ang = _atan2f(dy, dx) * 57.29578f;  // degrees
    ang = _fmod(ang + 360.0f, 360.0f);

    // parametric position t along the 270-degree sweep (min 225deg -> max -45deg)
    float t = (ang <= 225.0f) ? (225.0f - ang) / 270.0f : (585.0f - ang) / 270.0f;
    float in_arc = ((ang <= 225.0f) || (ang >= 315.0f)) ? 1.0f : 0.0f;
    float val = power / 100.0f;
    float R = gsize;

    float3 hud = make_float3(0.30f, 0.85f, 1.0f);
    float3 white = make_float3(0.95f, 0.98f, 1.0f);
    float3 col = make_float3(p_R, p_G, p_B);

    // track ring + value fill
    float ring = band(r, R, 0.006f, pxper) * in_arc;
    col = over3(col, hud, ring * 0.35f);
    float fill = ring * ((t <= val) ? 1.0f : 0.0f);
    col = over3(col, hud, fill * 0.95f);

    // tick marks (major every 5th)
    float tickA = 0.0f;
    for (int k = 0; k < 11; k++)
    {
        float tk = (float)k / 10.0f;
        float ta = _fmod(225.0f - tk * 270.0f + 360.0f, 360.0f);
        float da = _fabs(_fmod(ang - ta + 540.0f, 360.0f) - 180.0f);
        int major = (k % 5 == 0) ? 1 : 0;
        float inner = R - (major ? 0.03f : 0.018f);
        float tr = _saturatef((r - inner) / pxper + 0.5f) * _saturatef((R - 0.004f - r) / pxper + 0.5f);
        float tm = ((da < (major ? 1.6f : 1.1f)) ? 1.0f : 0.0f) * tr * in_arc;
        tickA = _fmaxf(tickA, tm);
    }
    col = over3(col, hud, tickA * 0.8f);

    // needle + small back tail
    float na = (225.0f - val * 270.0f) * 0.01745329f;
    float ndx = _cosf(na);
    float ndy = _sinf(na);
    float proj = dx * ndx + dy * ndy;
    float perp = _fabs(dx * ndy - dy * ndx);
    float needle = _saturatef((0.004f - perp) / pxper + 0.5f) * ((proj > 0.0f && proj < R - 0.02f) ? 1.0f : 0.0f);
    float tail = _saturatef((0.003f - perp) / pxper + 0.5f) * ((proj < 0.0f && proj > -0.03f) ? 1.0f : 0.0f);
    col = over3(col, white, _fmaxf(needle, tail));

    // hub
    col = over3(col, white, _saturatef((0.011f - r) / pxper + 0.5f));
    col = over3(col, hud, _saturatef((0.006f - r) / pxper + 0.5f));

    return col;
}
