src: implement ego tracking models, and port shaders from renderbug into here

This commit is contained in:
2025-09-22 13:16:39 +02:00
parent 29ba78d5b2
commit 19875f6ae5
18 changed files with 1191 additions and 184 deletions

View File

@@ -1,23 +1,26 @@
use embassy_sync::{blocking_mutex::raw::NoopRawMutex, pubsub::Subscriber};
use embassy_time::{Duration, Instant, Timer};
use esp_hal::{rmt::ChannelCreator, Async, peripherals::GPIO5};
use esp_hal::{gpio::AnyPin, rmt::ChannelCreator, Async};
use esp_hal_smartled::{buffer_size_async, SmartLedsAdapterAsync};
use figments::{hardware::Output, liber8tion::trig::sin8, prelude::Rectangle, render::Sample};
use figments::{hardware::{Brightness, Output}, prelude::Hsv, surface::{BufferedSurfacePool, Surfaces}};
use log::{info, warn};
use rgb::Rgb;
use rgb::Rgba;
use crate::{display::BikeOutput, events::Notification};
use crate::{display::{BikeOutput, BikeSpace}, events::DisplayControls};
#[derive(Default)]
pub struct Uniforms {
pub frame: usize,
pub primary_color: Hsv
}
//TODO: Import the bike surfaces from renderbug-prime, somehow make those surfaces into tasks
#[embassy_executor::task]
pub async fn render(mut events: Subscriber<'static, NoopRawMutex, Notification, 4, 4, 4>, rmt_channel: ChannelCreator<Async, 0>, gpio: GPIO5<'static>) {
pub async fn render(rmt_channel: ChannelCreator<Async, 0>, gpio: AnyPin<'static>, surfaces: BufferedSurfacePool<Uniforms, BikeSpace, Rgba<u8>>, controls: &'static DisplayControls) {
let rmt_buffer = [0u32; buffer_size_async(178)];
let target = SmartLedsAdapterAsync::new(rmt_channel, gpio, rmt_buffer);
// Change this number to use a different number of LEDs
//let mut pixbuf = [Default::default(); 16];
// Change this to adjust the power available; the USB spec says 500ma is the standard limit, but sometimes you can draw more from a power brick
const POWER_MA : u32 = 500;
@@ -26,31 +29,25 @@ pub async fn render(mut events: Subscriber<'static, NoopRawMutex, Notification,
const MAX_POWER_MW : u32 = POWER_VOLTS * POWER_MA;
// This value is used as the 'seed' for rendering each frame, allowing us to do things like run the animation backwards, frames for double FPS, or even use system uptime for more human-paced animations
let mut frame = 0;
let mut uniforms = Uniforms::default();
//let mut target = BrightnessWriter::new(target, MAX_POWER_MW);
let mut output = BikeOutput::new(target, MAX_POWER_MW);
info!("Rendering started!");
loop {
/*if let Some(evt) = events.try_next_message() {
}*/
let start = Instant::now();
//pixbuf.blank();
output.blank().await.expect("Failed to blank framebuf");
// Render the frame to the pixbuf, while also calculating the power consumption as we go
for (coords, pix) in output.sample(&Rectangle::everything()) {
*pix = Rgb::new(sin8(coords.x.wrapping_mul(3).wrapping_add(coords.y.wrapping_mul(3)).wrapping_add(frame)), 0, 0);
}
surfaces.render_to(&mut output, &uniforms);
// Apply hardware controls
output.set_on(controls.on.load(core::sync::atomic::Ordering::Relaxed));
output.set_brightness(controls.brightness.load(core::sync::atomic::Ordering::Relaxed));
// Finally, write out the rendered frame
//target.write(pixbuf.iter().cloned()).await.expect("Could not write frame");
//info!("frame");
output.commit().await.expect("Failed to commit frame");
//info!("commit");
let render_duration = Instant::now() - start;
let render_budget = Duration::from_millis(16);
@@ -63,6 +60,6 @@ pub async fn render(mut events: Subscriber<'static, NoopRawMutex, Notification,
}
// Increment the frame counter
frame += 1;
uniforms.frame += 1;
}
}