& DJ Khaled

This commit is contained in:
firestarsdog
2026-08-07 00:33:13 -04:00
parent d326365ee4
commit cdd8a0b2df
2 changed files with 56 additions and 54 deletions
+50 -49
View File
@@ -29,8 +29,8 @@ PERSPECTIVE_EXPONENT = 1.8
ROAD_HEIGHT = 80.0 * SCALE
ROAD_SEGMENTS = 24
ROAD_W_BOTTOM = 22.0 * SCALE
ROAD_W_TOP = 14.0 * SCALE
ROAD_W_BOTTOM = 32.0 * SCALE
ROAD_W_TOP = 18.0 * SCALE
ROAD_THICKNESS = 4.0 * SCALE
ROAD_HALF_SIZE = 40.0 * SCALE
ROAD_EDGE_INSET = 2.0 * SCALE
@@ -530,8 +530,8 @@ class AetherGauge:
t_lead = max(0.15, min(0.85, t_lead))
car_scale = 0.45 + (1.0 - t_lead) * 0.55
W = 30.0 * SCALE * car_scale
H = 18.0 * SCALE * car_scale
W = 38.0 * SCALE * car_scale
H = 22.0 * SCALE * car_scale
is_stopped = data.indicator_extra == "stopped"
is_slower = data.indicator_extra == "slower"
@@ -543,30 +543,31 @@ class AetherGauge:
else:
border_color = _fade(data.color, alpha)
# Car body: cabin and main body
# Car body: cabin and main body with high-contrast outlines
for rect_args, corner_r, fill in [
((cx_lead - W * 0.3, cy_lead - H, W * 0.6, H * 0.45), 0.5, _fade(rl.Color(15, 15, 15, 240), alpha)),
((cx_lead - W / 2, cy_lead - H * 0.65, W, H * 0.55), 0.3, _fade(rl.Color(20, 20, 20, 240), alpha)),
]:
r = rl.Rectangle(*rect_args)
rl.draw_rectangle_rounded(r, corner_r, 4, fill)
rl.draw_rectangle_rounded_lines_ex(r, corner_r, 4, 1.5, border_color)
rl.draw_rectangle_rounded_lines_ex(r, corner_r, 4, 2.0, border_color)
# Tail lights with glow
tl_w = W * 0.15
tl_h = H * 0.12
# Tail lights with radial bloom
tl_w = max(4.0, W * 0.16)
tl_h = max(2.5, H * 0.14)
tl_y = int(cy_lead - H * 0.55)
glow_y = int(cy_lead - H * 0.5)
for tl_x, glow_x in [(int(cx_lead - W * 0.45), int(cx_lead - W * 0.38)),
(int(cx_lead + W * 0.3), int(cx_lead + W * 0.38))]:
if is_stopped:
pulse = _pulse(2.5)
r_glow = int(W * 0.08 * (1.0 + 0.4 * pulse))
r_glow = int(W * 0.10 * (1.0 + 0.4 * pulse))
rl.draw_circle(glow_x, glow_y, r_glow + 4, _fade(rl.Color(255, 30, 60, int(60 + 40 * pulse)), alpha))
rl.draw_circle(glow_x, glow_y, r_glow, _fade(rl.Color(255, 30, 60, int(150 + 105 * pulse)), alpha))
c_tl = _fade(rl.Color(255, 220, 220, 255), alpha)
elif is_slower:
pulse = _pulse(1.2)
r_glow = int(W * 0.06 * (1.0 + 0.2 * pulse))
r_glow = int(W * 0.08 * (1.0 + 0.2 * pulse))
rl.draw_circle(glow_x, glow_y, r_glow, _fade(rl.Color(255, 140, 30, int(100 + 80 * pulse)), alpha))
c_tl = _fade(rl.Color(255, 160, 60, int(180 + 75 * pulse)), alpha)
else:
@@ -594,8 +595,8 @@ class AetherGauge:
road_h = self._current_road_h
cy_t = bottom - t * road_h
chevron_w = 12.0 * SCALE - t * 5.0 * SCALE
chevron_thick = max(1.5 * SCALE, 3.5 * SCALE - t * 1.5 * SCALE)
chevron_w = 14.0 * SCALE - t * 5.0 * SCALE
chevron_thick = max(2.0 * SCALE, 4.0 * SCALE - t * 1.5 * SCALE)
lx = cx_t - chevron_w
rx = cx_t + chevron_w
@@ -636,9 +637,9 @@ class AetherGauge:
dir_right_x = -dir_up_y
dir_right_y = dir_up_x
chevron_w = max(2.0 * SCALE, 14.0 * SCALE - t * 6.0 * SCALE)
chevron_w = max(3.0 * SCALE, 18.0 * SCALE - t * 7.0 * SCALE)
chevron_h = chevron_w * 0.6
chevron_thick = max(2.0 * SCALE, 4.0 * SCALE - t * 2.0 * SCALE)
chevron_thick = max(2.5 * SCALE, 4.5 * SCALE - t * 2.0 * SCALE)
lx = cx_t - dir_right_x * chevron_w + dir_up_x * chevron_h
ly = cy_t - dir_right_y * chevron_w + dir_up_y * chevron_h
@@ -659,29 +660,29 @@ class AetherGauge:
t_light, cx_light, cy_road = _road_xy(distance, icx, icy + ROAD_HALF_SIZE, data, self._current_road_h)
s_light = 1.0 - t_light
scale_light = 0.6 + (s_light ** 2.0) * 1.4
cy_light = cy_road - 35.0 * SCALE * s_light
width = 11.0 * SCALE * scale_light
height = 27.0 * SCALE * scale_light
scale_light = 0.65 + (s_light ** 2.0) * 1.35
cy_light = cy_road - 38.0 * SCALE * s_light
width = 15.0 * SCALE * scale_light
height = 36.0 * SCALE * scale_light
rl.draw_rectangle_rounded(rl.Rectangle(cx_light - width/2, cy_light - height/2 + 1.5, width, height), 0.2, 4, _fade(rl.Color(0, 0, 0, 120), alpha))
rl.draw_rectangle_rounded(rl.Rectangle(cx_light - width/2, cy_light - height/2 + 1.5, width, height), 0.25, 4, _fade(rl.Color(0, 0, 0, 120), alpha))
rect_housing = rl.Rectangle(cx_light - width/2, cy_light - height/2, width, height)
rl.draw_rectangle_rounded(rect_housing, 0.2, 4, _fade(rl.Color(22, 22, 22, 255), alpha))
rl.draw_rectangle_rounded_lines_ex(rect_housing, 0.2, 4, 1.0, _fade(rl.Color(80, 80, 80, 255), alpha))
rl.draw_rectangle_rounded(rect_housing, 0.25, 4, _fade(rl.Color(22, 22, 22, 255), alpha))
rl.draw_rectangle_rounded_lines_ex(rect_housing, 0.25, 4, 1.5, _fade(rl.Color(100, 100, 100, 255), alpha))
r_bulb = 2.2 * SCALE * scale_light
r_bulb = 3.2 * SCALE * scale_light
active_light = data.indicator_extra if data.indicator_extra in ("red", "yellow", "green") else "red"
bulbs = [
(cy_light - 7.5 * SCALE * scale_light, "red", rl.Color(255, 30, 60, 255), rl.Color(50, 10, 15, 255)),
(cy_light - 10.0 * SCALE * scale_light, "red", rl.Color(255, 30, 60, 255), rl.Color(50, 10, 15, 255)),
(cy_light, "yellow", rl.Color(255, 200, 0, 255), rl.Color(50, 40, 0, 255)),
(cy_light + 7.5 * SCALE * scale_light, "green", rl.Color(0, 255, 100, 255), rl.Color(0, 40, 15, 255)),
(cy_light + 10.0 * SCALE * scale_light, "green", rl.Color(0, 255, 100, 255), rl.Color(0, 40, 15, 255)),
]
for y, name, active_c, inactive_c in bulbs:
if name == "red" and active_light == "red":
glow_pulse = _pulse(1.5)
rl.draw_circle_v(rl.Vector2(cx_light, y), r_bulb + 3.0 * SCALE * glow_pulse, _fade(rl.Color(255, 30, 60, 45), alpha))
rl.draw_circle_v(rl.Vector2(cx_light, y), r_bulb + 6.0 * SCALE * glow_pulse, _fade(rl.Color(255, 30, 60, 15), alpha))
rl.draw_circle_v(rl.Vector2(cx_light, y), r_bulb + 8.0 * SCALE * glow_pulse, _fade(rl.Color(255, 30, 60, 25), alpha))
rl.draw_circle_v(rl.Vector2(cx_light, y), r_bulb + 4.0 * SCALE * glow_pulse, _fade(rl.Color(255, 30, 60, 60), alpha))
c = _fade(active_c if active_light == name else inactive_c, alpha)
rl.draw_circle_v(rl.Vector2(cx_light, y), r_bulb, c)
@@ -696,16 +697,16 @@ class AetherGauge:
cy_road = bottom - t_stop_gauge * road_h
y_sign = cy_road - 25.0 * SCALE * smoothed_s
r_min = 6.0 * SCALE
r_max = 20.0 * SCALE
r_min = 12.0 * SCALE
r_max = 28.0 * SCALE
r_sign = r_min + (smoothed_s ** 2.0) * (r_max - r_min)
shadow_alpha = int(min(120, r_sign * 12))
shadow_alpha = int(min(140, r_sign * 10))
rl.draw_poly(rl.Vector2(cx_stop, y_sign + 2.0), 8, r_sign, 22.5, _fade(rl.Color(0, 0, 0, shadow_alpha), alpha))
rl.draw_poly(rl.Vector2(cx_stop, y_sign), 8, r_sign, 22.5, _fade(COLOR_FORCE_STOP, alpha))
outline_t = max(0.8, min(1.5, r_sign * 0.07))
outline_a = int(max(0, min(200, (r_sign - 5.0) * 20)))
outline_t = max(1.5, min(2.5, r_sign * 0.08))
outline_a = int(max(0, min(220, (r_sign - 5.0) * 20)))
if outline_a > 20:
for i in range(8):
a1 = math.radians(22.5 + i * 45.0)
@@ -714,9 +715,9 @@ class AetherGauge:
p2 = rl.Vector2(cx_stop + r_sign * math.cos(a2), y_sign + r_sign * math.sin(a2))
rl.draw_line_ex(p1, p2, outline_t, _fade(_with_alpha(COLOR_STOP_SIGN_OUTLINE, outline_a), alpha))
if r_sign < 8.0 * SCALE:
if r_sign < 10.0 * SCALE:
return
stop_font_size = max(10, int(r_sign * 0.7))
stop_font_size = max(14, int(r_sign * 0.7))
stop_txt_size = measure_text_cached(font_bold, "STOP", stop_font_size)
rl.draw_text_ex(font_bold, "STOP", rl.Vector2(cx_stop - stop_txt_size.x / 2, y_sign - stop_txt_size.y / 2), stop_font_size, 0, _fade(rl.WHITE, alpha))
@@ -725,30 +726,30 @@ class AetherGauge:
return
if data.is_numeric:
val_size = measure_text_cached(font_bold, data.text, int(48 * SCALE))
val_pos = rl.Vector2(int(cx - val_size.x / 2), int(bottom + 12 * SCALE))
_draw_text_with_shadow(font_bold, data.text, val_pos, int(48 * SCALE), data.color, alpha)
val_size = measure_text_cached(font_bold, data.text, int(50 * SCALE))
val_pos = rl.Vector2(int(cx - val_size.x / 2), int(bottom + 6 * SCALE))
_draw_text_with_shadow(font_bold, data.text, val_pos, int(50 * SCALE), data.color, alpha)
accent_y = int(bottom + 12 * SCALE + val_size.y + 2 * SCALE)
accent_w = int(val_size.x + 12 * SCALE)
accent_y = int(val_pos.y + val_size.y + 2 * SCALE)
accent_w = int(val_size.x + 16 * SCALE)
accent_x = int(cx - accent_w / 2)
rl.draw_line_ex(
rl.Vector2(accent_x, accent_y),
rl.Vector2(accent_x + accent_w, accent_y),
2.0 * SCALE,
_fade(_with_alpha(data.color, 150), alpha),
_fade(_with_alpha(data.color, 160), alpha),
)
if data.reduction_text:
red_size = measure_text_cached(font_medium, data.reduction_text, int(20 * SCALE))
red_pos = rl.Vector2(int(cx + val_size.x / 2 + 8 * SCALE), int(bottom + 12 * SCALE + val_size.y / 2 - red_size.y / 2))
_draw_text_with_shadow(font_medium, data.reduction_text, red_pos, int(20 * SCALE), COLOR_REDUCTION, alpha)
red_size = measure_text_cached(font_medium, data.reduction_text, int(22 * SCALE))
red_pos = rl.Vector2(int(cx + val_size.x / 2 + 6 * SCALE), int(val_pos.y + val_size.y / 2 - red_size.y / 2))
_draw_text_with_shadow(font_medium, data.reduction_text, red_pos, int(22 * SCALE), COLOR_REDUCTION, alpha)
if data.unit:
unit_size = measure_text_cached(font_medium, data.unit, int(18 * SCALE))
unit_pos = rl.Vector2(int(cx - unit_size.x / 2), int(bottom + 12 * SCALE + val_size.y + 4 * SCALE))
_draw_text_with_shadow(font_medium, data.unit, unit_pos, int(18 * SCALE), rl.Color(255, 255, 255, 160), alpha)
unit_size = measure_text_cached(font_medium, data.unit, int(20 * SCALE))
unit_pos = rl.Vector2(int(cx - unit_size.x / 2), int(accent_y + 3 * SCALE))
_draw_text_with_shadow(font_medium, data.unit, unit_pos, int(20 * SCALE), rl.Color(255, 255, 255, 180), alpha)
else:
val_size = measure_text_cached(font_bold, data.text, int(24 * SCALE))
val_pos = rl.Vector2(int(cx - val_size.x / 2), int(bottom + 16 * SCALE))
_draw_text_with_shadow(font_bold, data.text, val_pos, int(24 * SCALE), data.color, alpha)
val_size = measure_text_cached(font_bold, data.text, int(32 * SCALE))
val_pos = rl.Vector2(int(cx - val_size.x / 2), int(bottom + 10 * SCALE))
_draw_text_with_shadow(font_bold, data.text, val_pos, int(32 * SCALE), data.color, alpha)
@@ -2,7 +2,7 @@ import pyray as rl
from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.system.ui.lib.application import gui_app, FontWeight
from openpilot.selfdrive.ui.onroad.starpilot.widgets.base import LayoutWidget
from openpilot.selfdrive.ui.onroad.starpilot.aethergauge import AetherGauge
from openpilot.selfdrive.ui.onroad.starpilot.aethergauge import AetherGauge, _fade
class AetherGaugeWidget(LayoutWidget):
def __init__(self, hud_renderer):
@@ -18,17 +18,18 @@ class AetherGaugeWidget(LayoutWidget):
return self._aethergauge.has_active_source()
def get_size(self) -> tuple[float, float]:
# Width 180, height 250 covers the road visual and the mini text cradle
return 180.0, 250.0
# Width 172 aligns with SetSpeedWidget; height 260 covers the road visual and text cradle
return 172.0, 260.0
def _render(self, rect: rl.Rectangle) -> None:
target = 1.0 if self._aethergauge.has_active_source() else 0.0
alpha = self._alpha_filter.update(target)
if alpha < 0.02:
return
cx = rect.x + rect.width / 2
# Set the road bottom to rect.y + 130, leaving 120px for the text cradle underneath
bottom = rect.y + 130
# Set the road bottom to rect.y + 145, leaving 115px for the text cradle underneath
bottom = rect.y + 145.0
self._aethergauge.render(
rect, self._font_bold, self._font_medium,
current_speed=self.hud_renderer.speed,