Compare commits
No commits in common. "67d7afbd78e148fd37c84687fd223dd16d24da29" and "eb42f5fa54ed7420a56d92530b824e954f371898" have entirely different histories.
67d7afbd78
...
eb42f5fa54
17 changed files with 232 additions and 458 deletions
|
@ -1,154 +0,0 @@
|
||||||
use {
|
|
||||||
std::time::{Instant, Duration},
|
|
||||||
crate::waveform::Waveform,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Controller {
|
|
||||||
pub tbegin: Instant,
|
|
||||||
pub transition_begin: Instant,
|
|
||||||
pub last_tap: Instant,
|
|
||||||
|
|
||||||
pub ctrl: bool
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Controller {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Controller {
|
|
||||||
tbegin: Instant::now(),
|
|
||||||
transition_begin: Instant::now(),
|
|
||||||
last_tap: Instant::now(),
|
|
||||||
ctrl: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn handle_key(
|
|
||||||
&mut self,
|
|
||||||
event: winit::event::KeyEvent,
|
|
||||||
inputs: &mut crate::inputs::Inputs,
|
|
||||||
setup: &mut crate::setup::LightingSetup
|
|
||||||
) {
|
|
||||||
if event.state == winit::event::ElementState::Released {
|
|
||||||
match event.logical_key {
|
|
||||||
winit::keyboard::Key::Named(
|
|
||||||
winit::keyboard::NamedKey::Control
|
|
||||||
) => {
|
|
||||||
eprintln!("released control");
|
|
||||||
self.ctrl = false;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
if event.state == winit::event::ElementState::Pressed {
|
|
||||||
match event.logical_key {
|
|
||||||
winit::keyboard::Key::Named(
|
|
||||||
winit::keyboard::NamedKey::Control
|
|
||||||
) => {
|
|
||||||
eprintln!("pressed control");
|
|
||||||
self.ctrl = true;
|
|
||||||
}
|
|
||||||
winit::keyboard::Key::Character(c) => {
|
|
||||||
eprintln!("pressed {}", c);
|
|
||||||
|
|
||||||
if self.ctrl {
|
|
||||||
if c.is_ascii() {
|
|
||||||
match &c[0..1] {
|
|
||||||
"0" => {
|
|
||||||
if let Some(f) = setup.fixtures.get_mut(0) {
|
|
||||||
eprintln!("toggle mirror_y of fixture 0");
|
|
||||||
f.mirror_y = !f.mirror_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1" => {
|
|
||||||
if let Some(f) = setup.fixtures.get_mut(1) {
|
|
||||||
eprintln!("toggle mirror_y of fixture 1");
|
|
||||||
f.mirror_y = !f.mirror_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2" => {
|
|
||||||
if let Some(f) = setup.fixtures.get_mut(2) {
|
|
||||||
eprintln!("toggle mirror_y of fixture 2");
|
|
||||||
f.mirror_y = !f.mirror_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3" => {
|
|
||||||
if let Some(f) = setup.fixtures.get_mut(3) {
|
|
||||||
eprintln!("toggle mirror_y of fixture 3");
|
|
||||||
f.mirror_y = !f.mirror_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4" => {
|
|
||||||
if let Some(f) = setup.fixtures.get_mut(4) {
|
|
||||||
eprintln!("toggle mirror_y of fixture 4");
|
|
||||||
f.mirror_y = !f.mirror_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if c.is_ascii() {
|
|
||||||
match &c[0..1] {
|
|
||||||
"x" => {
|
|
||||||
// tap tempo
|
|
||||||
let old_tap = self.last_tap;
|
|
||||||
self.last_tap = std::time::Instant::now();
|
|
||||||
|
|
||||||
if (self.last_tap - old_tap) < Duration::from_millis(20000) {
|
|
||||||
inputs.cycle_len = self.last_tap - old_tap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"q" => {
|
|
||||||
// sync
|
|
||||||
inputs.t = Duration::from_millis(0);
|
|
||||||
self.tbegin = std::time::Instant::now();
|
|
||||||
},
|
|
||||||
"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" => {
|
|
||||||
let idx = c.chars().nth(0).unwrap().to_digit(10).unwrap() as u32;
|
|
||||||
inputs.scene_select = idx as usize;
|
|
||||||
self.transition_begin = std::time::Instant::now();
|
|
||||||
}
|
|
||||||
"r" => { inputs.master_wave = match inputs.master_wave {
|
|
||||||
None => Some(Waveform::Sine),
|
|
||||||
Some(Waveform::Sine) => Some(Waveform::Triangle),
|
|
||||||
Some(Waveform::Triangle) => Some(Waveform::Square),
|
|
||||||
Some(Waveform::Square) => Some(Waveform::Sawtooth),
|
|
||||||
Some(Waveform::Sawtooth) => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"," => { inputs.master_wave = None; }
|
|
||||||
"n" => { inputs.master_intensity += 0.1; }
|
|
||||||
"m" => { inputs.master_intensity -= 0.1; }
|
|
||||||
"s" => { inputs.master_subdivision +=1; }
|
|
||||||
"b" => { inputs.master_subdivision -=1; }
|
|
||||||
"o" => { inputs.wheel +=1; }
|
|
||||||
"z" => { inputs.wheel -=1; }
|
|
||||||
"e" => { inputs.wheel2 += 1; }
|
|
||||||
"p"=> { inputs.wheel2 -= 1; }
|
|
||||||
"a"=> { inputs.wheel3 -= 1; }
|
|
||||||
"i" => { inputs.wheel3 += 1; }
|
|
||||||
"-" => { inputs.master_intensity *= -1.0; }
|
|
||||||
"." => {
|
|
||||||
if inputs.active {
|
|
||||||
eprintln!("DEACTIVATED");
|
|
||||||
inputs.active = false;
|
|
||||||
} else {
|
|
||||||
inputs.active = true;
|
|
||||||
eprintln!("ACTIVATED");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_=>{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eprintln!("--------------");
|
|
||||||
eprintln!("updated inputs:\n {:?}", inputs);
|
|
||||||
eprintln!("--------------");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -15,21 +15,19 @@ pub struct Fixture {
|
||||||
pub position: Vector2<f32>,
|
pub position: Vector2<f32>,
|
||||||
pub rotation: f32,
|
pub rotation: f32,
|
||||||
pub scale: f32,
|
pub scale: f32,
|
||||||
pub mirror_y: bool,
|
|
||||||
pub brightness: f32,
|
pub brightness: f32,
|
||||||
pub buffer: Vec< Rgb<u8> >,
|
pub buffer: Vec< Rgb<u8> >,
|
||||||
pub driver: Option<Box<dyn FixtureDriver>>
|
pub driver: Option<Box<dyn FixtureDriver>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Fixture {
|
impl Fixture {
|
||||||
pub fn new_stripe(mirror_y: bool) -> Self {
|
pub fn new_stripe() -> Self {
|
||||||
let mut fixture = Fixture {
|
let mut fixture = Fixture {
|
||||||
resolution: Vector2::new(1, 72),
|
resolution: Vector2::new(1, 72),
|
||||||
position: Vector2::new(0.0, 0.0),
|
position: Vector2::new(0.0, 0.0),
|
||||||
rotation: 0.0,
|
rotation: 0.0,
|
||||||
scale: 0.015,
|
scale: 0.015,
|
||||||
brightness: 0.8,
|
brightness: 0.8,
|
||||||
mirror_y,
|
|
||||||
buffer: Vec::new(),
|
buffer: Vec::new(),
|
||||||
driver: None
|
driver: None
|
||||||
};
|
};
|
||||||
|
@ -45,7 +43,6 @@ impl Fixture {
|
||||||
position: Vector2::new(0.0, 0.0),
|
position: Vector2::new(0.0, 0.0),
|
||||||
rotation: 0.0,
|
rotation: 0.0,
|
||||||
scale: 0.03,
|
scale: 0.03,
|
||||||
mirror_y: false,
|
|
||||||
brightness: 0.8,
|
brightness: 0.8,
|
||||||
buffer: Vec::new(),
|
buffer: Vec::new(),
|
||||||
driver: None
|
driver: None
|
||||||
|
@ -73,17 +70,12 @@ impl Fixture {
|
||||||
self.position + centered_pixpos * self.scale
|
self.position + centered_pixpos * self.scale
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_buffer(&mut self, view: &dyn crate::view::Animation) {
|
pub fn update_buffer(&mut self, view: &Box<dyn ColorGrid>) {
|
||||||
for xi in 0 .. self.resolution.x {
|
for xi in 0 .. self.resolution.x {
|
||||||
for yi in 0 ..self.resolution.y {
|
for yi in 0 ..self.resolution.y {
|
||||||
let gpos = self.get_global_pos(&Vector2::new(xi, yi));
|
let gpos = self.get_global_pos(&Vector2::new(xi, yi));
|
||||||
let col = view.get(&gpos);
|
let col = view.get(&gpos);
|
||||||
|
|
||||||
let yi = if self.mirror_y {
|
|
||||||
self.resolution.y - 1 - yi
|
|
||||||
} else {
|
|
||||||
yi
|
|
||||||
};
|
|
||||||
let index = xi + yi * self.resolution.x;
|
let index = xi + yi * self.resolution.x;
|
||||||
self.buffer[index as usize] = Rgb::new(
|
self.buffer[index as usize] = Rgb::new(
|
||||||
(col.red() * 255.0 * self.brightness) as u8,
|
(col.red() * 255.0 * self.brightness) as u8,
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
|
|
||||||
use {
|
|
||||||
std::time::Duration,
|
|
||||||
crate::waveform::Waveform
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct Inputs {
|
|
||||||
pub t: Duration,
|
|
||||||
pub transition_time: Duration,
|
|
||||||
|
|
||||||
pub scene_select: usize,
|
|
||||||
pub cycle_len: Duration,
|
|
||||||
pub wave_peak: f32,
|
|
||||||
|
|
||||||
pub master_wave: Option< Waveform >,
|
|
||||||
pub master_subdivision: i32,
|
|
||||||
pub master_intensity: f32,
|
|
||||||
pub wheel: i32,
|
|
||||||
pub wheel2: i32,
|
|
||||||
pub wheel3: i32,
|
|
||||||
|
|
||||||
pub active: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Inputs {
|
|
||||||
fn default() -> Inputs {
|
|
||||||
Inputs {
|
|
||||||
t: Duration::from_millis(0),
|
|
||||||
transition_time: Duration::from_millis(0),
|
|
||||||
cycle_len: Duration::from_millis(300),
|
|
||||||
wave_peak: 0.5,
|
|
||||||
|
|
||||||
scene_select: 0,
|
|
||||||
|
|
||||||
master_wave: None,
|
|
||||||
master_subdivision: 0,
|
|
||||||
master_intensity: 1.0,
|
|
||||||
wheel: 0,
|
|
||||||
wheel2: 0,
|
|
||||||
wheel3: 0,
|
|
||||||
|
|
||||||
active: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
159
src/main.rs
159
src/main.rs
|
@ -16,12 +16,10 @@ use {
|
||||||
mod util;
|
mod util;
|
||||||
mod fixture;
|
mod fixture;
|
||||||
mod setup;
|
mod setup;
|
||||||
mod inputs;
|
|
||||||
mod view;
|
mod view;
|
||||||
mod stripe_driver;
|
mod stripe_driver;
|
||||||
mod jack;
|
mod jack;
|
||||||
mod waveform;
|
mod waveform;
|
||||||
mod controller;
|
|
||||||
|
|
||||||
mod patterns;
|
mod patterns;
|
||||||
mod scene_library;
|
mod scene_library;
|
||||||
|
@ -34,10 +32,25 @@ use crate::{
|
||||||
util::get_angle,
|
util::get_angle,
|
||||||
|
|
||||||
scene_library::SceneLibrary,
|
scene_library::SceneLibrary,
|
||||||
waveform::Waveform,
|
waveform::Waveform
|
||||||
inputs::Inputs
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Inputs {
|
||||||
|
t: Duration,
|
||||||
|
transition_time: Duration,
|
||||||
|
|
||||||
|
scene_select: usize,
|
||||||
|
cycle_len: Duration,
|
||||||
|
wave_peak: f32,
|
||||||
|
|
||||||
|
master_wave: Option< Waveform >,
|
||||||
|
master_subdivision: i32,
|
||||||
|
master_intensity: f32,
|
||||||
|
wheel: i32,
|
||||||
|
wheel2: i32,
|
||||||
|
}
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let event_loop = EventLoop::new().unwrap();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
@ -51,52 +64,64 @@ async fn main() {
|
||||||
socket.write().unwrap().set_read_timeout(Some(std::time::Duration::from_millis(1)));
|
socket.write().unwrap().set_read_timeout(Some(std::time::Duration::from_millis(1)));
|
||||||
socket.write().unwrap().set_write_timeout(Some(std::time::Duration::from_millis(1)));
|
socket.write().unwrap().set_write_timeout(Some(std::time::Duration::from_millis(1)));
|
||||||
|
|
||||||
let mut inputs = Inputs::default();
|
let inputs = Arc::new(RwLock::new(
|
||||||
|
Inputs {
|
||||||
|
t: Duration::from_millis(0),
|
||||||
|
transition_time: Duration::from_millis(0),
|
||||||
|
cycle_len: Duration::from_millis(300),
|
||||||
|
wave_peak: 0.5,
|
||||||
|
|
||||||
|
scene_select: 0,
|
||||||
|
|
||||||
|
master_wave: None,
|
||||||
|
master_subdivision: 0,
|
||||||
|
master_intensity: 1.0,
|
||||||
|
wheel: 0,
|
||||||
|
wheel2: 0
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
let mut lighting_setup = LightingSetup::new(
|
let mut lighting_setup = LightingSetup::new(
|
||||||
vec![
|
vec![
|
||||||
Fixture::new_matrix(),
|
Fixture::new_matrix(),
|
||||||
// .with_driver( Box::new(MatrixTcpDriver::new("ip:port")) ),
|
// .with_driver( Box::new(MatrixTcpDriver::new("ip:port")) ),
|
||||||
|
|
||||||
Fixture::new_stripe(false)
|
Fixture::new_stripe()
|
||||||
.with_driver( Box::new(StripeDriver::new("192.168.0.114:4210", socket.clone())) )
|
.with_driver( Box::new(StripeDriver::new("192.168.0.111:4210", socket.clone())) )
|
||||||
.offset(Vector2::new(-0.5, 0.0)),
|
.offset(Vector2::new(-0.5, 0.0)),
|
||||||
|
|
||||||
Fixture::new_stripe(true)
|
Fixture::new_stripe()
|
||||||
.with_driver( Box::new(StripeDriver::new("192.168.0.113:4210", socket.clone())) )
|
.with_driver( Box::new(StripeDriver::new("192.168.0.112:4210", socket.clone())) )
|
||||||
.offset(Vector2::new(-0.4, 0.0)),
|
.offset(Vector2::new(-0.4, 0.0)),
|
||||||
|
|
||||||
Fixture::new_stripe(true)
|
Fixture::new_stripe()
|
||||||
.with_driver( Box::new(StripeDriver::new("192.168.0.112:4210", socket.clone())) )
|
.with_driver( Box::new(StripeDriver::new("192.168.0.113:4210", socket.clone())) )
|
||||||
.offset(Vector2::new(0.4, 0.0)),
|
.offset(Vector2::new(0.4, 0.0)),
|
||||||
|
|
||||||
Fixture::new_stripe(false)
|
Fixture::new_stripe()
|
||||||
.with_driver( Box::new(StripeDriver::new("192.168.0.111:4210", socket.clone())))
|
.with_driver( Box::new(StripeDriver::new("192.168.0.114:4210", socket.clone())))
|
||||||
.offset(Vector2::new(0.5, 0.0))
|
.offset(Vector2::new(0.5, 0.0))
|
||||||
],
|
],
|
||||||
|
|
||||||
Box::new( SceneLibrary::new() )
|
Box::new( SceneLibrary::new(inputs.clone()) )
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut controller = controller::Controller::new();
|
let mut tbegin = std::time::Instant::now();
|
||||||
|
let mut transition_begin = std::time::Instant::now();
|
||||||
|
let mut last_tap = std::time::Instant::now();
|
||||||
|
let mut z = 0;
|
||||||
|
|
||||||
let mut frame_count = 0;
|
let mut frame_count = 0;
|
||||||
let mut fps_sum_window = std::time::Instant::now();
|
let mut fps_sum_window = std::time::Instant::now();
|
||||||
|
|
||||||
lighting_setup.advance( &inputs );
|
let mut active = false;
|
||||||
|
|
||||||
for i in 0..5 {
|
for i in 0..5 {
|
||||||
lighting_setup.sync_fixture(i);
|
lighting_setup.sync_fixture(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_loop.run(move |event, elwt| {
|
event_loop.run(move |event, elwt| {
|
||||||
let tcur = std::time::Instant::now();
|
let tcur = std::time::Instant::now();
|
||||||
|
|
||||||
elwt.set_control_flow(
|
|
||||||
ControlFlow::WaitUntil(
|
|
||||||
tcur + Duration::from_millis(25)
|
|
||||||
));
|
|
||||||
|
|
||||||
// FPS statistics
|
|
||||||
if (tcur - fps_sum_window).as_millis() > 5000 {
|
if (tcur - fps_sum_window).as_millis() > 5000 {
|
||||||
let avg_fps = (1000.0 * frame_count as f32) / ((tcur - fps_sum_window).as_millis() as f32);
|
let avg_fps = (1000.0 * frame_count as f32) / ((tcur - fps_sum_window).as_millis() as f32);
|
||||||
eprintln!("avg fps: {}", avg_fps);
|
eprintln!("avg fps: {}", avg_fps);
|
||||||
|
@ -106,13 +131,15 @@ async fn main() {
|
||||||
frame_count += 1;
|
frame_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update animation
|
elwt.set_control_flow(ControlFlow::
|
||||||
inputs.t = tcur - controller.tbegin;
|
WaitUntil(
|
||||||
inputs.transition_time = tcur - controller.transition_begin;
|
tcur + Duration::from_millis(25)
|
||||||
lighting_setup.advance( &inputs );
|
));
|
||||||
|
inputs.write().unwrap().t = tcur - tbegin;
|
||||||
|
inputs.write().unwrap().transition_time = tcur - transition_begin;
|
||||||
|
lighting_setup.update_buffers();
|
||||||
|
|
||||||
// refresh fixture outputs
|
if active {
|
||||||
if inputs.active {
|
|
||||||
// sync
|
// sync
|
||||||
let mut rbuf = [0 as u8; 8];
|
let mut rbuf = [0 as u8; 8];
|
||||||
|
|
||||||
|
@ -158,12 +185,76 @@ async fn main() {
|
||||||
window_id: _,
|
window_id: _,
|
||||||
event: winit::event::WindowEvent::KeyboardInput{ device_id, event, is_synthetic }
|
event: winit::event::WindowEvent::KeyboardInput{ device_id, event, is_synthetic }
|
||||||
} => {
|
} => {
|
||||||
controller.handle_key(
|
if event.state == winit::event::ElementState::Pressed {
|
||||||
event, &mut inputs, &mut lighting_setup
|
match event.logical_key {
|
||||||
);
|
winit::keyboard::Key::Character(c) => {
|
||||||
}
|
eprintln!("pressed {}", c);
|
||||||
|
|
||||||
_ => {}
|
let mut inputs = inputs.write().unwrap();
|
||||||
|
if c.is_ascii() {
|
||||||
|
match &c[0..1] {
|
||||||
|
"x" => {
|
||||||
|
// tap tempo
|
||||||
|
let old_tap = last_tap;
|
||||||
|
last_tap = std::time::Instant::now();
|
||||||
|
|
||||||
|
if (last_tap - old_tap) < Duration::from_millis(20000) {
|
||||||
|
inputs.cycle_len = last_tap - old_tap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"q" => {
|
||||||
|
// sync
|
||||||
|
inputs.t = Duration::from_millis(0);
|
||||||
|
tbegin = std::time::Instant::now();
|
||||||
|
},
|
||||||
|
"0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" => {
|
||||||
|
let idx = c.chars().nth(0).unwrap().to_digit(10).unwrap() as u32;
|
||||||
|
inputs.scene_select = idx as usize;
|
||||||
|
transition_begin = std::time::Instant::now();
|
||||||
|
}
|
||||||
|
"r" => { inputs.master_wave = match inputs.master_wave {
|
||||||
|
None => Some(Waveform::Sine),
|
||||||
|
Some(Waveform::Sine) => Some(Waveform::Triangle),
|
||||||
|
Some(Waveform::Triangle) => Some(Waveform::Square),
|
||||||
|
Some(Waveform::Square) => Some(Waveform::Sawtooth),
|
||||||
|
Some(Waveform::Sawtooth) => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"," => { inputs.master_wave = None; }
|
||||||
|
"n" => { inputs.master_intensity += 0.1; }
|
||||||
|
"m" => { inputs.master_intensity -= 0.1; }
|
||||||
|
"s" => { inputs.master_subdivision +=1; }
|
||||||
|
"b" => { inputs.master_subdivision -=1; }
|
||||||
|
"o" => { inputs.wheel +=1; }
|
||||||
|
"z" => { inputs.wheel -=1; }
|
||||||
|
"e" => { inputs.wheel2 += 1; }
|
||||||
|
"p"=> { inputs.wheel2 -= 1; }
|
||||||
|
|
||||||
|
"-" => { inputs.master_intensity *= -1.0; }
|
||||||
|
"." => {
|
||||||
|
if active {
|
||||||
|
eprintln!("DEACTIVATED");
|
||||||
|
active = false;
|
||||||
|
} else {
|
||||||
|
active = true;
|
||||||
|
eprintln!("ACTIVATED");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_=>{}
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("--------------");
|
||||||
|
eprintln!("updated inputs:\n {:?}", inputs);
|
||||||
|
eprintln!("--------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (width, height) = *dim.lock().unwrap();
|
let (width, height) = *dim.lock().unwrap();
|
||||||
|
|
|
@ -10,27 +10,22 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}}
|
crate::{Inputs, view::ColorGrid}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Alternate {
|
pub struct Alternate {
|
||||||
pub inputs: Inputs,
|
pub inputs: Arc<RwLock< Inputs >>,
|
||||||
}
|
|
||||||
|
|
||||||
impl Animation for Alternate {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorGrid for Alternate {
|
impl ColorGrid for Alternate {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
let switch = 0;
|
let switch = 0;
|
||||||
|
|
||||||
let t = (self.inputs.wheel as f32 * self.inputs.t.as_millis() as f32 / self.inputs.cycle_len.as_millis() as f32) % 1.0;
|
let t = (inputs.wheel as f32 * inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32) % 1.0;
|
||||||
|
|
||||||
if ((50.0+p.y*128.0) / self.inputs.wheel as f32) as u32 % 2 == 0 {
|
if ((50.0+p.y*128.0) / inputs.wheel as f32) as u32 % 2 == 0 {
|
||||||
if t < 0.5 {
|
if t < 0.5 {
|
||||||
Rgb::new(0.5, 0.2, 0.2)
|
Rgb::new(0.5, 0.2, 0.2)
|
||||||
} else {
|
} else {
|
||||||
|
@ -43,6 +38,9 @@ impl ColorGrid for Alternate {
|
||||||
Rgb::new(0.0, 0.0, 0.6)
|
Rgb::new(0.0, 0.0, 0.6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,21 +10,16 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}}
|
crate::{Inputs, view::ColorGrid}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
pub struct ArcticRain { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
pub struct ArcticRain { pub inputs: Inputs }
|
|
||||||
|
|
||||||
impl Animation for ArcticRain {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorGrid for ArcticRain {
|
impl ColorGrid for ArcticRain {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let i = ( self.inputs.t.as_millis() as f32 / (4.0*self.inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
// let millis = self
|
||||||
|
|
||||||
|
let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
||||||
|
|
||||||
let pi2 = 2.0 * 3.1415926;
|
let pi2 = 2.0 * 3.1415926;
|
||||||
|
|
||||||
|
@ -32,9 +27,9 @@ impl ColorGrid for ArcticRain {
|
||||||
Rgb::from_color(
|
Rgb::from_color(
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
// Turns( 0.65 + 0.3*(inputs.wheel%10) as f32*0.1 ),
|
// Turns( 0.65 + 0.3*(inputs.wheel%10) as f32*0.1 ),
|
||||||
Turns( (self.inputs.wheel.abs() % 256) as f32 / 256.0 ),
|
Turns( (inputs.wheel.abs() % 256) as f32 / 256.0 ),
|
||||||
0.9,
|
0.9,
|
||||||
1.0 - ((i + (2.0-p.y/(0.2*(1+self.inputs.wheel3.abs()) as f32))) * 12.0) % 1.0,
|
1.0 - ((i + (2.0-p.y/4.0)) * 12.0) % 1.0,
|
||||||
// (f32::sin(-p.y+i) * 12.0) % 1.0,
|
// (f32::sin(-p.y+i) * 12.0) % 1.0,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,25 +9,17 @@ use {
|
||||||
cgmath::{Point2, Vector2},
|
cgmath::{Point2, Vector2},
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
crate::{
|
|
||||||
Inputs,
|
crate::{Inputs, view::ColorGrid, util::get_angle}
|
||||||
view::{ColorGrid, Animation},
|
|
||||||
util::get_angle
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Breathing { pub inputs: Inputs }
|
|
||||||
|
|
||||||
impl Animation for Breathing {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pub struct Breathing { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
impl ColorGrid for Breathing {
|
impl ColorGrid for Breathing {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let millis = self.inputs.t.as_millis();
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let millis = inputs.t.as_millis();
|
||||||
|
|
||||||
let p1 = p + Vector2::new(0.0,0.5);
|
let p1 = p + Vector2::new(0.0,0.5);
|
||||||
let r2 = p1.x*p1.x + p1.y*p1.y;
|
let r2 = p1.x*p1.x + p1.y*p1.y;
|
||||||
|
@ -40,8 +32,8 @@ impl ColorGrid for Breathing {
|
||||||
mirrorphi *
|
mirrorphi *
|
||||||
(
|
(
|
||||||
0.5+ 0.5*f32::sin(
|
0.5+ 0.5*f32::sin(
|
||||||
self.inputs.t.as_millis() as f32
|
inputs.t.as_millis() as f32
|
||||||
/ self.inputs.cycle_len.as_millis() as f32
|
/ inputs.cycle_len.as_millis() as f32
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) % 1.0;
|
) % 1.0;
|
||||||
|
@ -50,7 +42,7 @@ impl ColorGrid for Breathing {
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
Turns( 0.25+0.25*f32::sin(millis as f32/8000.0) + gamma*0.5 ),
|
Turns( 0.25+0.25*f32::sin(millis as f32/8000.0) + gamma*0.5 ),
|
||||||
0.5 + r2 * 0.5,
|
0.5 + r2 * 0.5,
|
||||||
self.inputs.wave_peak,
|
inputs.wave_peak,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ pub mod gastel_fade;
|
||||||
pub mod wheel;
|
pub mod wheel;
|
||||||
pub mod wave_fade;
|
pub mod wave_fade;
|
||||||
pub mod alternate;
|
pub mod alternate;
|
||||||
pub mod oneshotman;
|
|
||||||
|
|
||||||
#[path = "uboot_prüfstand_fade.rs"]
|
#[path = "uboot_prüfstand_fade.rs"]
|
||||||
pub mod uboot;
|
pub mod uboot;
|
||||||
|
@ -21,8 +20,7 @@ pub use {
|
||||||
wave_fade::WaveFade,
|
wave_fade::WaveFade,
|
||||||
uboot::UbootPrüfstandFade,
|
uboot::UbootPrüfstandFade,
|
||||||
wheel::Wheel,
|
wheel::Wheel,
|
||||||
alternate::Alternate,
|
alternate::Alternate
|
||||||
oneshotman::OneShotMan
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
use {
|
|
||||||
std::num::NonZeroU32,
|
|
||||||
std::sync::{Arc, RwLock, Mutex},
|
|
||||||
std::rc::Rc,
|
|
||||||
winit::event::{Event, WindowEvent},
|
|
||||||
winit::event_loop::{ControlFlow, EventLoop},
|
|
||||||
winit::window::WindowBuilder,
|
|
||||||
prisma::{Rgb,Hsv,FromColor, Lerp},
|
|
||||||
cgmath::{Point2, Vector2},
|
|
||||||
std::time::Duration,
|
|
||||||
angle::Turns,
|
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle}
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct OneShotMan {
|
|
||||||
pub inputs: Inputs,
|
|
||||||
velocity: f32,
|
|
||||||
pos: f32,
|
|
||||||
last_t: std::time::Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Animation for OneShotMan {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
self.velocity = (inputs.wheel as f32) / 16.0;
|
|
||||||
|
|
||||||
self.pos = -0.8 + self.velocity * (self.inputs.t.as_millis() as f32) / 1000.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
q
|
|
||||||
impl ColorGrid for OneShotMan {
|
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
|
||||||
if p.y < self.pos {
|
|
||||||
Rgb::from_color(
|
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
|
||||||
Turns( (self.inputs.wheel2 as f32 / 64.0).abs() % 1.0 ),
|
|
||||||
0.8,
|
|
||||||
f32::exp( -(1.0 + (self.inputs.wheel3 as f32) * (self.pos - p.y)) )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Rgb::new(0.0,0.0,0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,21 +10,15 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle}
|
crate::{Inputs, view::ColorGrid, util::get_angle}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
pub struct PastelFade { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
pub struct PastelFade { pub inputs: Inputs }
|
|
||||||
|
|
||||||
impl Animation for PastelFade {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorGrid for PastelFade {
|
impl ColorGrid for PastelFade {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let i = ( 5.0 + 0.7 * self.inputs.t.as_millis() as f32 / (16.0*self.inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let i = ( 5.0 + 0.7 * inputs.t.as_millis() as f32 / (16.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
||||||
|
|
||||||
Rgb::from_color(
|
Rgb::from_color(
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
|
|
|
@ -10,23 +10,18 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}}
|
crate::{Inputs, view::ColorGrid}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Strobe {
|
pub struct Strobe {
|
||||||
pub inputs: Inputs,
|
pub inputs: Arc<RwLock< Inputs >>,
|
||||||
}
|
|
||||||
|
|
||||||
impl Animation for Strobe {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorGrid for Strobe {
|
impl ColorGrid for Strobe {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let t = (self.inputs.wheel as f32 * self.inputs.t.as_millis() as f32 / self.inputs.cycle_len.as_millis() as f32) % 1.0;
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let t = (inputs.wheel as f32 * inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32) % 1.0;
|
||||||
|
|
||||||
if t < 0.6 {
|
if t < 0.6 {
|
||||||
Rgb::new(0.3, 0.3, 0.3)
|
Rgb::new(0.3, 0.3, 0.3)
|
||||||
|
|
|
@ -10,21 +10,16 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}}
|
crate::{Inputs, view::ColorGrid}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
pub struct UbootPrüfstandFade { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
pub struct UbootPrüfstandFade { pub inputs: Inputs }
|
|
||||||
|
|
||||||
impl Animation for UbootPrüfstandFade {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorGrid for UbootPrüfstandFade {
|
impl ColorGrid for UbootPrüfstandFade {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let i = ( self.inputs.t.as_millis() as f32 / (4.0*self.inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
// let millis = self
|
||||||
|
|
||||||
|
let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
||||||
|
|
||||||
let pi2 = 2.0 * 3.1415926;
|
let pi2 = 2.0 * 3.1415926;
|
||||||
|
|
||||||
|
@ -39,7 +34,7 @@ impl ColorGrid for UbootPrüfstandFade {
|
||||||
|
|
||||||
let col2 = Rgb::new(0.8, 0.0, 0.0);
|
let col2 = Rgb::new(0.8, 0.0, 0.0);
|
||||||
|
|
||||||
let p = ( self.inputs.t.as_millis() as f32 / (32.0*self.inputs.cycle_len.as_millis() as f32)) % 1.0;
|
let p = ( inputs.t.as_millis() as f32 / (32.0*inputs.cycle_len.as_millis() as f32)) % 1.0;
|
||||||
if p >= 0.7 {
|
if p >= 0.7 {
|
||||||
col2
|
col2
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,25 +10,21 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle, waveform::Waveform}
|
crate::{Inputs, view::ColorGrid, util::get_angle, waveform::Waveform}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct WaveFade { pub inputs: Inputs,
|
pub struct WaveFade { pub inputs: Arc<RwLock< Inputs >>,
|
||||||
pub hue: f32,
|
pub hue: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Animation for WaveFade {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorGrid for WaveFade {
|
impl ColorGrid for WaveFade {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let nt = ( self.inputs.t.as_millis() as f32 / self.inputs.cycle_len.as_millis() as f32 );
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let nt = ( inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32 );
|
||||||
|
|
||||||
let i =
|
let i =
|
||||||
match self.inputs.wheel % 4 {
|
match inputs.wheel % 4 {
|
||||||
0 => Waveform::Sine{}.get_norm(nt),
|
0 => Waveform::Sine{}.get_norm(nt),
|
||||||
1 => Waveform::Triangle{}.get_norm(nt),
|
1 => Waveform::Triangle{}.get_norm(nt),
|
||||||
2 => Waveform::Sawtooth{}.get_norm(nt),
|
2 => Waveform::Sawtooth{}.get_norm(nt),
|
||||||
|
|
|
@ -10,21 +10,16 @@ use {
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::{Inputs, view::{ColorGrid, Animation}, util::get_angle}
|
crate::{Inputs, view::ColorGrid, util::get_angle}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct Wheel { pub inputs: Inputs }
|
|
||||||
|
|
||||||
impl Animation for Wheel {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pub struct Wheel { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
impl ColorGrid for Wheel {
|
impl ColorGrid for Wheel {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let millis = self.inputs.t.as_millis();
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let millis = inputs.t.as_millis();
|
||||||
|
|
||||||
let p1 = p + Vector2::new(0.0,0.5);
|
let p1 = p + Vector2::new(0.0,0.5);
|
||||||
let r2 = p1.x*p1.x + p1.y*p1.y;
|
let r2 = p1.x*p1.x + p1.y*p1.y;
|
||||||
|
@ -36,8 +31,8 @@ impl ColorGrid for Wheel {
|
||||||
(5.0) *
|
(5.0) *
|
||||||
mirrorphi *
|
mirrorphi *
|
||||||
(
|
(
|
||||||
self.inputs.t.as_millis() as f32
|
inputs.t.as_millis() as f32
|
||||||
/ (self.inputs.cycle_len.as_millis() as f32 * (1.0 + (self.inputs.wheel as f32).abs()))
|
/ (inputs.cycle_len.as_millis() as f32 * (1.0 + (inputs.wheel as f32).abs()))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -45,7 +40,7 @@ impl ColorGrid for Wheel {
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
Turns( gamma*0.5 ),
|
Turns( gamma*0.5 ),
|
||||||
0.5 + r2 * 0.5,
|
0.5 + r2 * 0.5,
|
||||||
(self.inputs.wheel as f32 / 16.0),
|
(inputs.wheel as f32 / 16.0),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,67 +11,56 @@ use {
|
||||||
angle::Turns,
|
angle::Turns,
|
||||||
|
|
||||||
crate::Inputs,
|
crate::Inputs,
|
||||||
crate::view::{ColorGrid, Animation},
|
crate::view::ColorGrid,
|
||||||
crate::patterns::*
|
crate::patterns::*
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
pub struct SceneLibrary {
|
pub struct SceneLibrary {
|
||||||
library: Vec< Box<dyn Animation> >,
|
library: Vec< Box<dyn ColorGrid> >,
|
||||||
current_scene: usize,
|
current_scene: RwLock<usize>,
|
||||||
inputs: Inputs,
|
inputs: Arc<RwLock< Inputs >>,
|
||||||
|
|
||||||
transition_length: Duration,
|
transition_length: Duration,
|
||||||
// transition_curve: enum { Constant, Linear, Sigmoid, Sinus }
|
// transition_curve: enum { Constant, Linear, Sigmoid, Sinus }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SceneLibrary {
|
impl SceneLibrary {
|
||||||
pub fn new() -> Self {
|
pub fn new( inputs: Arc<RwLock<Inputs>> ) -> Self {
|
||||||
SceneLibrary {
|
SceneLibrary {
|
||||||
library: vec![
|
library: vec![
|
||||||
// 0
|
// 0
|
||||||
Box::new( Breathing::default() ),
|
Box::new( Breathing{ inputs: inputs.clone() } ),
|
||||||
|
|
||||||
// 1
|
// 1
|
||||||
Box::new( Strobe::default() ),
|
Box::new( Strobe{ inputs: inputs.clone() } ),
|
||||||
// 2
|
// 2
|
||||||
// Box::new( WaveFade{ inputs: inputs.clone(), hue: 0.5 } ),
|
Box::new( WaveFade{ inputs: inputs.clone(), hue: 0.5 } ),
|
||||||
// 3
|
// 3
|
||||||
Box::new( UbootPrüfstandFade::default() ),
|
Box::new( UbootPrüfstandFade{ inputs: inputs.clone() } ),
|
||||||
//4
|
//4
|
||||||
Box::new( ArcticRain::default() ),
|
Box::new( ArcticRain{ inputs: inputs.clone() } ),
|
||||||
//5
|
//5
|
||||||
Box::new( Wheel::default() ),
|
Box::new( Wheel{ inputs: inputs.clone() } ),
|
||||||
//6
|
//6
|
||||||
Box::new( Alternate::default() ),
|
Box::new( Alternate{ inputs: inputs.clone() } ),
|
||||||
//7
|
//7
|
||||||
Box::new( PastelFade::default() ),
|
Box::new( PastelFade{ inputs: inputs.clone() } ),
|
||||||
//8
|
|
||||||
Box::new( OneShotMan::default() )
|
|
||||||
],
|
],
|
||||||
current_scene: 0,
|
current_scene: RwLock::new(0),
|
||||||
inputs: Inputs::default(),
|
inputs,
|
||||||
transition_length: Duration::from_millis(200),
|
transition_length: Duration::from_millis(200),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Animation for SceneLibrary {
|
|
||||||
fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.inputs = inputs.clone();
|
|
||||||
|
|
||||||
if self.inputs.transition_time.as_millis() as f32 > self.transition_length.as_millis() as f32 {
|
|
||||||
// change own state:
|
|
||||||
self.current_scene = self.inputs.scene_select;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(a) = self.library.get_mut(self.current_scene) {
|
|
||||||
a.advance( inputs );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorGrid for SceneLibrary {
|
impl ColorGrid for SceneLibrary {
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
let mut intensity: f32 = self.inputs.master_intensity;
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let sc = *self.current_scene.read().unwrap();
|
||||||
|
|
||||||
|
let mut intensity: f32 = inputs.master_intensity;
|
||||||
if intensity > 1.0 {
|
if intensity > 1.0 {
|
||||||
intensity = 1.0;
|
intensity = 1.0;
|
||||||
}
|
}
|
||||||
|
@ -79,19 +68,20 @@ impl ColorGrid for SceneLibrary {
|
||||||
intensity = -1.0;
|
intensity = -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(w) = self.inputs.master_wave.clone() {
|
if let Some(w) = inputs.master_wave {
|
||||||
intensity *= w.get_doub(
|
intensity *= w.get_doub(
|
||||||
self.inputs.t.as_millis() as f32
|
inputs.t.as_millis() as f32
|
||||||
/ self.inputs.cycle_len.as_millis() as f32
|
/ inputs.cycle_len.as_millis() as f32
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.inputs.scene_select < self.library.len() {
|
if inputs.scene_select < self.library.len() {
|
||||||
|
|
||||||
if self.inputs.scene_select == self.current_scene {
|
|
||||||
|
if inputs.scene_select == sc {
|
||||||
// display only one animation
|
// display only one animation
|
||||||
let mut hsv = Hsv::from_color(
|
let mut hsv = Hsv::from_color(
|
||||||
&self.library[ self.current_scene ].get(p)
|
&self.library[ sc ].get(p)
|
||||||
);
|
);
|
||||||
|
|
||||||
hsv = Hsv::<f32>::new(
|
hsv = Hsv::<f32>::new(
|
||||||
|
@ -103,18 +93,24 @@ impl ColorGrid for SceneLibrary {
|
||||||
Rgb::from_color(&hsv)
|
Rgb::from_color(&hsv)
|
||||||
} else {
|
} else {
|
||||||
// display transition
|
// display transition
|
||||||
let cur_scene = &self.library[ self.current_scene ];
|
let cur_scene = &self.library[ sc ];
|
||||||
let nxt_scene = &self.library[ self.inputs.scene_select ];
|
let nxt_scene = &self.library[ inputs.scene_select ];
|
||||||
|
|
||||||
// crossfade param
|
// crossfade param
|
||||||
let w = ( self.inputs.transition_time.as_millis() as f32 / self.transition_length.as_millis() as f32 );
|
let w = ( inputs.transition_time.as_millis() as f32 / self.transition_length.as_millis() as f32 );
|
||||||
|
|
||||||
|
if w >= 1.0 {
|
||||||
|
// change own state:
|
||||||
|
*self.current_scene.write().unwrap() = inputs.scene_select;
|
||||||
|
}
|
||||||
|
|
||||||
cur_scene.get(p)
|
cur_scene.get(p)
|
||||||
.lerp(
|
.lerp(
|
||||||
&nxt_scene.get(p),
|
&nxt_scene.get(p),
|
||||||
w
|
w
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Rgb::new(0.0, 0.0, 0.0)
|
Rgb::new(0.0, 0.0, 0.0)
|
||||||
}
|
}
|
||||||
|
|
20
src/setup.rs
20
src/setup.rs
|
@ -1,8 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
fixture::Fixture,
|
fixture::Fixture,
|
||||||
inputs::Inputs,
|
view::ColorGrid
|
||||||
view::{ColorGrid, Animation}
|
|
||||||
},
|
},
|
||||||
cgmath::Vector2,
|
cgmath::Vector2,
|
||||||
std::time::Duration,
|
std::time::Duration,
|
||||||
|
@ -10,25 +9,25 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct LightingSetup {
|
pub struct LightingSetup {
|
||||||
pub fixtures: Vec<Fixture>,
|
fixtures: Vec<Fixture>,
|
||||||
t: Arc<RwLock<Duration>>,
|
t: Arc<RwLock<Duration>>,
|
||||||
|
|
||||||
animation: Box<dyn Animation>
|
view: Box<dyn ColorGrid>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LightingSetup {
|
impl LightingSetup {
|
||||||
pub fn new(fixtures: Vec<Fixture>, animation: Box<dyn Animation>) -> Self {
|
pub fn new(fixtures: Vec<Fixture>, view: Box<dyn ColorGrid>) -> Self {
|
||||||
let t = Arc::new(RwLock::new(Duration::from_millis(0)));
|
let t = Arc::new(RwLock::new(Duration::from_millis(0)));
|
||||||
LightingSetup {
|
LightingSetup {
|
||||||
fixtures,
|
fixtures,
|
||||||
t: t.clone(),
|
t: t.clone(),
|
||||||
animation
|
view
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_buffers(&mut self) {
|
pub fn update_buffers(&mut self) {
|
||||||
for fixture in self.fixtures.iter_mut() {
|
for fixture in self.fixtures.iter_mut() {
|
||||||
fixture.update_buffer( self.animation.as_ref() );
|
fixture.update_buffer( &self.view );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,11 +46,6 @@ impl LightingSetup {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn advance(&mut self, inputs: &Inputs) {
|
|
||||||
self.animation.advance(inputs);
|
|
||||||
self.update_buffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_preview(
|
pub fn draw_preview(
|
||||||
&self,
|
&self,
|
||||||
buffer: &mut softbuffer::Buffer<'_, Arc<winit::window::Window>, Arc<winit::window::Window>>,
|
buffer: &mut softbuffer::Buffer<'_, Arc<winit::window::Window>, Arc<winit::window::Window>>,
|
||||||
|
@ -71,7 +65,7 @@ impl LightingSetup {
|
||||||
let xf = (x as f32 - width as f32/2.0) / mindim as f32;
|
let xf = (x as f32 - width as f32/2.0) / mindim as f32;
|
||||||
let yf = -(y as f32 - height as f32/2.0) / mindim as f32;
|
let yf = -(y as f32 - height as f32/2.0) / mindim as f32;
|
||||||
|
|
||||||
let color = self.animation.get(&Vector2::new(xf, yf));
|
let color = self.view.get(&Vector2::new(xf, yf));
|
||||||
|
|
||||||
|
|
||||||
let red = (color.red() * 16.0) as u32;
|
let red = (color.red() * 16.0) as u32;
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
use {
|
use {
|
||||||
cgmath::Vector2,
|
cgmath::Vector2,
|
||||||
prisma::Rgb,
|
prisma::Rgb
|
||||||
|
|
||||||
crate::inputs::Inputs
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ColorGrid {
|
pub trait ColorGrid {
|
||||||
fn get(&self, pos: &Vector2<f32>) -> Rgb<f32>;
|
fn get(&self, pos: &Vector2<f32>) -> Rgb<f32>;
|
||||||
}
|
}
|
||||||
pub trait Animation : ColorGrid {
|
|
||||||
fn advance(&mut self, inputs: &Inputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue