add basic scene selection
This commit is contained in:
parent
13d58a7ac5
commit
06ea05e112
1 changed files with 146 additions and 16 deletions
158
src/main.rs
158
src/main.rs
|
@ -7,7 +7,7 @@ use {
|
|||
winit::event::{Event, WindowEvent},
|
||||
winit::event_loop::{ControlFlow, EventLoop},
|
||||
winit::window::WindowBuilder,
|
||||
prisma::{Rgb,Hsv,FromColor},
|
||||
prisma::{Rgb,Hsv,FromColor, Lerp},
|
||||
cgmath::{Point2, Vector2},
|
||||
std::time::Duration,
|
||||
angle::Turns
|
||||
|
@ -31,6 +31,9 @@ use crate::{
|
|||
#[derive(Clone)]
|
||||
struct Inputs {
|
||||
t: Duration,
|
||||
transition_time: Duration,
|
||||
|
||||
scene_select: usize,
|
||||
|
||||
intensity: f32,
|
||||
cycle_len: Duration,
|
||||
|
@ -78,16 +81,109 @@ impl ColorGrid for Anim2 {
|
|||
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( 0.0 ),
|
||||
Turns( i ),
|
||||
0.5,
|
||||
( inputs.t.as_millis() as f32 / inputs.cycle_len.as_millis() as f32 ) % 1.0
|
||||
(4.0*i) %1.0
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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( Anim2{ 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 fn main() {
|
||||
let event_loop = EventLoop::new().unwrap();
|
||||
|
@ -104,10 +200,13 @@ async fn main() {
|
|||
let inputs = Arc::new(RwLock::new(
|
||||
Inputs {
|
||||
t: Duration::from_millis(0),
|
||||
transition_time: Duration::from_millis(0),
|
||||
|
||||
intensity: 0.5,
|
||||
cycle_len: Duration::from_millis(300),
|
||||
wave_peak: 0.5,
|
||||
|
||||
scene_select: 0
|
||||
}
|
||||
));
|
||||
|
||||
|
@ -133,12 +232,11 @@ async fn main() {
|
|||
.offset(Vector2::new(0.5, 0.0))
|
||||
],
|
||||
|
||||
Box::new(
|
||||
Anim2{ inputs: inputs.clone() }
|
||||
)
|
||||
Box::new( SceneLibrary::new(inputs.clone()) )
|
||||
);
|
||||
|
||||
let tbegin = std::time::Instant::now();
|
||||
let mut tbegin = std::time::Instant::now();
|
||||
let mut transition_begin = std::time::Instant::now();
|
||||
let mut last_tap = std::time::Instant::now();
|
||||
|
||||
event_loop.run(move |event, elwt| {
|
||||
|
@ -148,12 +246,11 @@ async fn main() {
|
|||
));
|
||||
|
||||
inputs.write().unwrap().t = tcur - tbegin;
|
||||
inputs.write().unwrap().transition_time = tcur - transition_begin;
|
||||
lighting_setup.update_buffers();
|
||||
//lighting_setup.update_outputs();
|
||||
|
||||
match event {
|
||||
//Event::
|
||||
|
||||
Event::WindowEvent { window_id, event: WindowEvent::RedrawRequested } if window_id == window.id() => {
|
||||
let (width, height) = {
|
||||
let size = window.inner_size();
|
||||
|
@ -178,12 +275,45 @@ async fn main() {
|
|||
winit::keyboard::Key::Character(c) => {
|
||||
eprintln!("pressed {}", c);
|
||||
|
||||
if c == "x" {
|
||||
// tap tempo
|
||||
let old_tap = last_tap;
|
||||
last_tap = std::time::Instant::now();
|
||||
match &c[0..1] {
|
||||
"x" => {
|
||||
// tap tempo
|
||||
let old_tap = last_tap;
|
||||
last_tap = std::time::Instant::now();
|
||||
|
||||
inputs.write().unwrap().cycle_len = last_tap - old_tap;
|
||||
if (last_tap - old_tap) < Duration::from_millis(20000) {
|
||||
inputs.write().unwrap().cycle_len = last_tap - old_tap;
|
||||
}
|
||||
}
|
||||
|
||||
"q" => {
|
||||
// sync
|
||||
inputs.write().unwrap().t = Duration::from_millis(0);
|
||||
tbegin = std::time::Instant::now();
|
||||
},
|
||||
|
||||
"0" => {
|
||||
inputs.write().unwrap().scene_select = 0;
|
||||
transition_begin = std::time::Instant::now();
|
||||
}
|
||||
"1" => {
|
||||
inputs.write().unwrap().scene_select = 1;
|
||||
transition_begin = std::time::Instant::now();
|
||||
}
|
||||
"2" => {
|
||||
inputs.write().unwrap().scene_select = 2;
|
||||
transition_begin = std::time::Instant::now();
|
||||
}
|
||||
"3" => {
|
||||
inputs.write().unwrap().scene_select = 3;
|
||||
transition_begin = std::time::Instant::now();
|
||||
}
|
||||
"4" => {
|
||||
inputs.write().unwrap().scene_select = 4;
|
||||
transition_begin = std::time::Instant::now();
|
||||
}
|
||||
|
||||
_=>{}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
Loading…
Reference in a new issue