move patterns into separate module
This commit is contained in:
parent
393f7aa891
commit
d56a8ab988
10 changed files with 359 additions and 206 deletions
210
src/main.rs
210
src/main.rs
|
@ -20,14 +20,18 @@ mod view;
|
||||||
mod stripe_driver;
|
mod stripe_driver;
|
||||||
mod jack;
|
mod jack;
|
||||||
|
|
||||||
|
mod patterns;
|
||||||
|
mod scene_library;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
view::ColorGrid,
|
view::ColorGrid,
|
||||||
fixture::Fixture,
|
fixture::Fixture,
|
||||||
setup::LightingSetup,
|
setup::LightingSetup,
|
||||||
stripe_driver::StripeDriver,
|
stripe_driver::StripeDriver,
|
||||||
util::get_angle
|
util::get_angle,
|
||||||
};
|
|
||||||
|
|
||||||
|
scene_library::SceneLibrary
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Inputs {
|
pub struct Inputs {
|
||||||
|
@ -42,204 +46,6 @@ pub struct Inputs {
|
||||||
wave_peak: f32
|
wave_peak: f32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Breathing { inputs: Arc<RwLock< Inputs >> }
|
|
||||||
impl ColorGrid for Breathing {
|
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
|
||||||
let inputs = self.inputs.read().unwrap().clone();
|
|
||||||
|
|
||||||
let millis = inputs.t.as_millis();
|
|
||||||
|
|
||||||
let p1 = p + Vector2::new(0.0,0.5);
|
|
||||||
let r2 = p1.x*p1.x + p1.y*p1.y;
|
|
||||||
let v = if r2 > 1.0 { 1.0 } else { r2 };
|
|
||||||
let phi = ( get_angle(&p1) );
|
|
||||||
let mirrorphi = if phi < 0.5 { phi } else { 1.0-phi };
|
|
||||||
let gamma =
|
|
||||||
(
|
|
||||||
(5.0) *
|
|
||||||
mirrorphi *
|
|
||||||
(
|
|
||||||
0.5+ 0.5*f32::sin(
|
|
||||||
inputs.t.as_millis() as f32
|
|
||||||
/ inputs.cycle_len.as_millis() as f32
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) % 1.0;
|
|
||||||
|
|
||||||
Rgb::from_color(
|
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
|
||||||
Turns( 0.25+0.25*f32::sin(millis as f32/8000.0) + gamma*0.5 ),
|
|
||||||
0.5 + r2 * 0.5,
|
|
||||||
inputs.wave_peak,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
struct PastelFade { inputs: Arc<RwLock< Inputs >> }
|
|
||||||
impl ColorGrid for PastelFade {
|
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
|
||||||
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;
|
|
||||||
|
|
||||||
Rgb::from_color(
|
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
|
||||||
Turns( i ),
|
|
||||||
0.5,
|
|
||||||
(4.0*i) %1.0
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct UbootPrüfstandFade { inputs: Arc<RwLock< Inputs >> }
|
|
||||||
impl ColorGrid for UbootPrüfstandFade {
|
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
|
||||||
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 col1 =
|
|
||||||
Rgb::from_color(
|
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
|
||||||
Turns( 0.65 ),
|
|
||||||
0.9,
|
|
||||||
0.5 + 0.5*f32::sin(i*pi2),//(4.0*i) %1.0
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
let col2 = Rgb::new(0.5+0.5*f32::sin(i*pi2), 0.0, 0.0);
|
|
||||||
|
|
||||||
let p = ( inputs.t.as_millis() as f32 / (32.0*inputs.cycle_len.as_millis() as f32)) % 1.0;
|
|
||||||
if p >= 0.7 {
|
|
||||||
col2
|
|
||||||
} else {
|
|
||||||
col1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ArcticRain { inputs: Arc<RwLock< Inputs >> }
|
|
||||||
impl ColorGrid for ArcticRain {
|
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
|
||||||
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 col1 =
|
|
||||||
Rgb::from_color(
|
|
||||||
&Hsv::<f32, Turns<f32>>::new(
|
|
||||||
Turns( 0.65 ),
|
|
||||||
0.9,
|
|
||||||
1.0 - ((i + (2.0-p.y/4.0)) * 12.0) % 1.0,
|
|
||||||
// (f32::sin(-p.y+i) * 12.0) % 1.0,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
col1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Waveform {
|
|
||||||
Sawtooth{ pulse_width: Duration },
|
|
||||||
Square{ },
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Strobe {
|
|
||||||
inputs: Arc<RwLock< Inputs >>,
|
|
||||||
//waveform: Waveform,
|
|
||||||
subdivision: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorGrid for Strobe {
|
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
|
||||||
let inputs = self.inputs.read().unwrap().clone();
|
|
||||||
|
|
||||||
let t = (self.subdivision as f32 * inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32) % 1.0;
|
|
||||||
|
|
||||||
if t < 0.6 {
|
|
||||||
Rgb::new(0.6, 0.6, 0.6)
|
|
||||||
} else {
|
|
||||||
Rgb::new(0.0, 0.0, 0.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub struct SceneLibrary {
|
|
||||||
library: Vec< Box<dyn ColorGrid> >,
|
|
||||||
current_scene: RwLock<usize>,
|
|
||||||
inputs: Arc<RwLock< Inputs >>,
|
|
||||||
|
|
||||||
transition_length: Duration,
|
|
||||||
// transition_curve: enum { Constant, Linear, Sigmoid, Sinus }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SceneLibrary {
|
|
||||||
pub fn new( inputs: Arc<RwLock<Inputs>> ) -> Self {
|
|
||||||
SceneLibrary {
|
|
||||||
library: vec![
|
|
||||||
// 0
|
|
||||||
Box::new( Breathing{ inputs: inputs.clone() } ),
|
|
||||||
|
|
||||||
// 1 - 4
|
|
||||||
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 4 } ),
|
|
||||||
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 8 } ),
|
|
||||||
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 12 } ),
|
|
||||||
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 16 } ),
|
|
||||||
|
|
||||||
// others
|
|
||||||
Box::new( PastelFade{ inputs: inputs.clone() } ),
|
|
||||||
Box::new( UbootPrüfstandFade{ inputs: inputs.clone() } ),
|
|
||||||
Box::new( ArcticRain{ inputs: inputs.clone() } ),
|
|
||||||
],
|
|
||||||
current_scene: RwLock::new(0),
|
|
||||||
inputs,
|
|
||||||
transition_length: Duration::from_millis(200),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ColorGrid for SceneLibrary {
|
|
||||||
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
|
||||||
let inputs = self.inputs.read().unwrap().clone();
|
|
||||||
|
|
||||||
let sc = *self.current_scene.read().unwrap();
|
|
||||||
|
|
||||||
if inputs.scene_select == sc {
|
|
||||||
// display only one animation
|
|
||||||
self.library[ sc ].get(p)
|
|
||||||
} else {
|
|
||||||
// display transition
|
|
||||||
let cur_scene = &self.library[ sc ];
|
|
||||||
let nxt_scene = &self.library[ inputs.scene_select ];
|
|
||||||
|
|
||||||
// crossfade param
|
|
||||||
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)
|
|
||||||
.lerp(
|
|
||||||
&nxt_scene.get(p),
|
|
||||||
w
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let event_loop = EventLoop::new().unwrap();
|
let event_loop = EventLoop::new().unwrap();
|
||||||
|
@ -276,7 +82,7 @@ async fn main() {
|
||||||
.offset(Vector2::new(-0.5, 0.0)),
|
.offset(Vector2::new(-0.5, 0.0)),
|
||||||
|
|
||||||
Fixture::new_stripe()
|
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.112:4210", socket.clone())) )
|
||||||
.offset(Vector2::new(-0.4, 0.0)),
|
.offset(Vector2::new(-0.4, 0.0)),
|
||||||
|
|
||||||
Fixture::new_stripe()
|
Fixture::new_stripe()
|
||||||
|
@ -284,7 +90,7 @@ async fn main() {
|
||||||
.offset(Vector2::new(0.4, 0.0)),
|
.offset(Vector2::new(0.4, 0.0)),
|
||||||
|
|
||||||
Fixture::new_stripe()
|
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.114:4210", socket.clone())))
|
||||||
.offset(Vector2::new(0.5, 0.0))
|
.offset(Vector2::new(0.5, 0.0))
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
39
src/patterns/arctic_rain.rs
Normal file
39
src/patterns/arctic_rain.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
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}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ArcticRain { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
|
impl ColorGrid for ArcticRain {
|
||||||
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
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 col1 =
|
||||||
|
Rgb::from_color(
|
||||||
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
|
Turns( 0.65 ),
|
||||||
|
0.9,
|
||||||
|
1.0 - ((i + (2.0-p.y/4.0)) * 12.0) % 1.0,
|
||||||
|
// (f32::sin(-p.y+i) * 12.0) % 1.0,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
col1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
50
src/patterns/breathing.rs
Normal file
50
src/patterns/breathing.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
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, util::get_angle}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct Breathing { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
|
impl ColorGrid for Breathing {
|
||||||
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let millis = inputs.t.as_millis();
|
||||||
|
|
||||||
|
let p1 = p + Vector2::new(0.0,0.5);
|
||||||
|
let r2 = p1.x*p1.x + p1.y*p1.y;
|
||||||
|
let v = if r2 > 1.0 { 1.0 } else { r2 };
|
||||||
|
let phi = ( get_angle(&p1) );
|
||||||
|
let mirrorphi = if phi < 0.5 { phi } else { 1.0-phi };
|
||||||
|
let gamma =
|
||||||
|
(
|
||||||
|
(5.0) *
|
||||||
|
mirrorphi *
|
||||||
|
(
|
||||||
|
0.5+ 0.5*f32::sin(
|
||||||
|
inputs.t.as_millis() as f32
|
||||||
|
/ inputs.cycle_len.as_millis() as f32
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) % 1.0;
|
||||||
|
|
||||||
|
Rgb::from_color(
|
||||||
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
|
Turns( 0.25+0.25*f32::sin(millis as f32/8000.0) + gamma*0.5 ),
|
||||||
|
0.5 + r2 * 0.5,
|
||||||
|
inputs.wave_peak,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
18
src/patterns/mod.rs
Normal file
18
src/patterns/mod.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
pub mod breathing;
|
||||||
|
pub mod strobe;
|
||||||
|
pub mod arctic_rain;
|
||||||
|
pub mod pastel_fade;
|
||||||
|
|
||||||
|
#[path = "uboot_prüfstand_fade.rs"]
|
||||||
|
pub mod uboot;
|
||||||
|
|
||||||
|
pub use {
|
||||||
|
breathing::Breathing,
|
||||||
|
strobe::Strobe,
|
||||||
|
arctic_rain::ArcticRain,
|
||||||
|
pastel_fade::PastelFade,
|
||||||
|
uboot::UbootPrüfstandFade
|
||||||
|
};
|
||||||
|
|
||||||
|
|
31
src/patterns/pastel_fade.rs
Normal file
31
src/patterns/pastel_fade.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
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, util::get_angle}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct PastelFade { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
|
impl ColorGrid for PastelFade {
|
||||||
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let i = ( inputs.t.as_millis() as f32 / (4.0*inputs.cycle_len.as_millis() as f32) ) % 1.0;
|
||||||
|
|
||||||
|
Rgb::from_color(
|
||||||
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
|
Turns( i ),
|
||||||
|
0.5,
|
||||||
|
(4.0*i) %1.0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
35
src/patterns/strobe.rs
Normal file
35
src/patterns/strobe.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
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}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Strobe {
|
||||||
|
pub inputs: Arc<RwLock< Inputs >>,
|
||||||
|
pub subdivision: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorGrid for Strobe {
|
||||||
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let t = (self.subdivision as f32 * inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32) % 1.0;
|
||||||
|
|
||||||
|
if t < 0.6 {
|
||||||
|
Rgb::new(0.6, 0.6, 0.6)
|
||||||
|
} else {
|
||||||
|
Rgb::new(0.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
45
src/patterns/uboot_prüfstand_fade.rs
Normal file
45
src/patterns/uboot_prüfstand_fade.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
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}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct UbootPrüfstandFade { pub inputs: Arc<RwLock< Inputs >> }
|
||||||
|
impl ColorGrid for UbootPrüfstandFade {
|
||||||
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
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 col1 =
|
||||||
|
Rgb::from_color(
|
||||||
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
|
Turns( 0.65 ),
|
||||||
|
0.9,
|
||||||
|
0.5 + 0.5*f32::sin(i*pi2),//(4.0*i) %1.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
let col2 = Rgb::new(0.5+0.5*f32::sin(i*pi2), 0.0, 0.0);
|
||||||
|
|
||||||
|
let p = ( inputs.t.as_millis() as f32 / (32.0*inputs.cycle_len.as_millis() as f32)) % 1.0;
|
||||||
|
if p >= 0.7 {
|
||||||
|
col2
|
||||||
|
} else {
|
||||||
|
col1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
83
src/scene_library.rs
Normal file
83
src/scene_library.rs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
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,
|
||||||
|
crate::view::ColorGrid,
|
||||||
|
crate::patterns::*
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct SceneLibrary {
|
||||||
|
library: Vec< Box<dyn ColorGrid> >,
|
||||||
|
current_scene: RwLock<usize>,
|
||||||
|
inputs: Arc<RwLock< Inputs >>,
|
||||||
|
|
||||||
|
transition_length: Duration,
|
||||||
|
// transition_curve: enum { Constant, Linear, Sigmoid, Sinus }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SceneLibrary {
|
||||||
|
pub fn new( inputs: Arc<RwLock<Inputs>> ) -> Self {
|
||||||
|
SceneLibrary {
|
||||||
|
library: vec![
|
||||||
|
// 0
|
||||||
|
Box::new( Breathing{ inputs: inputs.clone() } ),
|
||||||
|
|
||||||
|
// 1 - 4
|
||||||
|
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 4 } ),
|
||||||
|
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 8 } ),
|
||||||
|
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 12 } ),
|
||||||
|
Box::new( Strobe{ inputs: inputs.clone(), subdivision: 16 } ),
|
||||||
|
|
||||||
|
// others
|
||||||
|
Box::new( PastelFade{ inputs: inputs.clone() } ),
|
||||||
|
Box::new( UbootPrüfstandFade{ inputs: inputs.clone() } ),
|
||||||
|
Box::new( ArcticRain{ inputs: inputs.clone() } ),
|
||||||
|
],
|
||||||
|
current_scene: RwLock::new(0),
|
||||||
|
inputs,
|
||||||
|
transition_length: Duration::from_millis(200),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorGrid for SceneLibrary {
|
||||||
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
let inputs = self.inputs.read().unwrap().clone();
|
||||||
|
|
||||||
|
let sc = *self.current_scene.read().unwrap();
|
||||||
|
|
||||||
|
if inputs.scene_select == sc {
|
||||||
|
// display only one animation
|
||||||
|
self.library[ sc ].get(p)
|
||||||
|
} else {
|
||||||
|
// display transition
|
||||||
|
let cur_scene = &self.library[ sc ];
|
||||||
|
let nxt_scene = &self.library[ inputs.scene_select ];
|
||||||
|
|
||||||
|
// crossfade param
|
||||||
|
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)
|
||||||
|
.lerp(
|
||||||
|
&nxt_scene.get(p),
|
||||||
|
w
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct StripeDriver {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StripeDriver {
|
impl StripeDriver {
|
||||||
fn new(addr: &str, socket: Arc<RwLock<std::net::UdpSocket>>) -> Self {
|
pub fn new(addr: &str, socket: Arc<RwLock<std::net::UdpSocket>>) -> Self {
|
||||||
StripeDriver {
|
StripeDriver {
|
||||||
addr: addr.into(),
|
addr: addr.into(),
|
||||||
socket
|
socket
|
||||||
|
@ -24,9 +24,9 @@ impl FixtureDriver for StripeDriver {
|
||||||
let mut buf = [0 as u8; STRIPE_LEN*3];
|
let mut buf = [0 as u8; STRIPE_LEN*3];
|
||||||
|
|
||||||
for x in 0 .. STRIPE_LEN {
|
for x in 0 .. STRIPE_LEN {
|
||||||
buf[x*3+0] = pixels[x].green();
|
buf[x*3+0] = pixels[x].green()/2;
|
||||||
buf[x*3+1] = pixels[x].red();
|
buf[x*3+1] = pixels[x].red()/2;
|
||||||
buf[x*3+2] = pixels[x].blue();
|
buf[x*3+2] = pixels[x].blue()/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.socket.write().unwrap().send_to(&buf, &self.addr);
|
self.socket.write().unwrap().send_to(&buf, &self.addr);
|
||||||
|
|
46
src/uboot_prüfstand_fade.rs
Normal file
46
src/uboot_prüfstand_fade.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
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}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
pub struct UbootPrüfstandFade { inputs: Arc<RwLock< Inputs >> }
|
||||||
|
impl ColorGrid for UbootPrüfstandFade {
|
||||||
|
fn get(&self, p: &Vector2<f32>) -> Rgb<f32> {
|
||||||
|
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 col1 =
|
||||||
|
Rgb::from_color(
|
||||||
|
&Hsv::<f32, Turns<f32>>::new(
|
||||||
|
Turns( 0.65 ),
|
||||||
|
0.9,
|
||||||
|
0.5 + 0.5*f32::sin(i*pi2),//(4.0*i) %1.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
let col2 = Rgb::new(0.5+0.5*f32::sin(i*pi2), 0.0, 0.0);
|
||||||
|
|
||||||
|
let p = ( inputs.t.as_millis() as f32 / (32.0*inputs.cycle_len.as_millis() as f32)) % 1.0;
|
||||||
|
if p >= 0.7 {
|
||||||
|
col2
|
||||||
|
} else {
|
||||||
|
col1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue