Unverified Commit b0b72e23 authored by Dan Sheppard's avatar Dan Sheppard Committed by GitHub
Browse files

Dip-to-white animations between chromosomes (#206)

Proper cross-fade animations.
parent bdc06fca
Pipeline #45723 passed with stages
in 5 minutes and 57 seconds
......@@ -50,7 +50,8 @@ impl Compositor {
pub fn get_zmr(&self) -> &ZMenuRegistry { &self.zmr }
pub fn get_prop_trans(&mut self) -> f32 { self.window.get_train_manager().get_prop_trans() }
pub fn get_prop_trans_up(&mut self) -> f32 { self.window.get_train_manager().get_prop_trans_up() }
pub fn get_prop_trans_down(&mut self) -> f32 { self.window.get_train_manager().get_prop_trans_down() }
fn prime_cache(&mut self, t: f64) {
if self.prime_delay.is_none() {
......
......@@ -163,12 +163,14 @@ impl AppRunner {
}
}),5,false);
}
/* draw */
let app = imp.app.clone();
imp.sched_group.add("draw",Box::new(move |_| {
app.lock().unwrap().draw();
}),0,true);
}
/* draw */
self.add_timer("draw",move |app,t,_| {
let actions = app.get_window().get_animator().tick(t);
app.run_actions(&actions,None);
app.draw();
vec![]
},0);
/* xfer */
self.add_timer("xfer",move |app,_,sr| {
if !app.tick_xfer() {
......@@ -176,12 +178,6 @@ impl AppRunner {
}
vec![]
},2);
/* animations */
self.add_timer("animations",move |app,t,_| {
let actions = app.get_window().get_animator().tick(t);
app.run_actions(&actions,None);
vec![]
},0);
/* jumping */
self.add_timer("get-jump",move |app,_,_| {
let tm = app.get_window().get_train_manager();
......
......@@ -66,7 +66,14 @@ impl SchedulerMain {
fn check_tempo(&mut self, burst: bool) {
let now = browser_time();
self.jank.detect(burst,now/1000.);
self.set_timesig(self.jank.gear());
/* This is where jank-detection would be reflected in the scheduler.
* However, it turns out jank-detection is not the best way to do
* this and we really need a better scheduler. In the mean-time it's
* best not to detect jank at all. I'll leave this line here to
* indicate the architecture of this existing (old) scheduler for
* curious visitors or myself when reimplementing.
*/
//self.set_timesig(self.jank.gear());
}
pub(in super) fn beat(&mut self, new: Vec<SchedNewTask>, dels: Vec<u32>, allotment: f64) {
......
......@@ -184,14 +184,15 @@ impl GLPrinter {
impl Printer for GLPrinter {
fn print(&mut self, screen: &Screen, compo: &mut Compositor) {
compo.redraw_where_needed(self);
let prop = compo.get_prop_trans();
let prop_up = compo.get_prop_trans_up();
let prop_down = compo.get_prop_trans_down();
compo.with_current_train(|train| {
let mut tp = WebGLTrainPrinter::new();
tp.contextualize(&mut self.base.borrow_mut(),screen,train,1.-prop);
tp.contextualize(&mut self.base.borrow_mut(),screen,train,prop_down);
});
compo.with_transition_train(|train| {
let mut tp = WebGLTrainPrinter::new();
tp.contextualize(&mut self.base.borrow_mut(),screen,train,prop);
tp.contextualize(&mut self.base.borrow_mut(),screen,train,prop_up);
});
self.base.borrow_mut().prepare_all();
compo.with_current_train(|train| {
......
......@@ -15,7 +15,7 @@ pub use self::train::Train;
pub use self::traincontext::TrainContext;
pub use self::trainid::TrainId;
pub use self::trainmanager::TrainManager;
pub(self) use self::transition::TrainManagerTransition;
pub(self) use self::transition::{ CrossFade, TrainManagerTransition };
pub use self::traveller::Traveller;
pub use self::travellercreator::TravellerCreator;
pub use self::travellerid::TravellerId;
......@@ -127,7 +127,7 @@ impl TrainManagerImpl {
/* if there's a transition and it's reached endstop it is current */
fn transition_maybe_done(&mut self, t: f64) {
self.transition.update(t);
if self.transition.get_prop() >= 1. {
if self.transition.get_prop().get_prop_up() >= 1. {
console!("transition done");
bb_log!("trainmanager","transition done {:?}",self.transition_train.as_ref().map(|x| x.get_train_id().clone()));
self.current_train = self.transition_train.take();
......@@ -156,7 +156,7 @@ impl TrainManagerImpl {
slow = true;
}
}
console!("starting trnasition");
console!("starting transition");
self.transition.start(t,slow);
}
}
......@@ -386,10 +386,13 @@ impl TrainManagerImpl {
*/
/* used by printer to set opacity */
pub fn get_prop_trans(&self) -> f32 {
self.transition.get_prop() as f32
pub fn get_prop_trans_up(&self) -> f32 {
self.transition.get_prop().get_prop_up() as f32
}
pub fn get_prop_trans_down(&self) -> f32 {
self.transition.get_prop().get_prop_down() as f32
}
/* used by printer for actual printing */
pub fn with_current_train<F>(&mut self, mut cb: F) where F: FnMut(&mut Train) {
if let Some(ref mut train) = self.current_train {
......@@ -527,10 +530,14 @@ impl TrainManager {
self.0.lock().unwrap().set_desired_context(context);
}
pub fn get_prop_trans(&self) -> f32 {
self.0.lock().unwrap().get_prop_trans()
pub fn get_prop_trans_up(&self) -> f32 {
self.0.lock().unwrap().get_prop_trans_up()
}
pub fn get_prop_trans_down(&self) -> f32 {
self.0.lock().unwrap().get_prop_trans_down()
}
pub fn with_current_train<F>(&mut self, cb: F) where F: FnMut(&mut Train) {
self.0.lock().unwrap().with_current_train(cb)
}
......
use std::sync::{ Arc, Mutex };
use zhoosh::{ Zhoosh, ZhooshRunner, ZhooshSequence, ZhooshSequenceControl, ZhooshShape, ZhooshStep, ZHOOSH_LINEAR_F64_OPS };
use zhoosh::{ Zhoosh, ZhooshOps, ZhooshRunner, ZhooshSequence, ZhooshSequenceControl, ZhooshShape, ZhooshStep, ZHOOSH_LINEAR_F64_OPS };
const MS_FADE_FAST : f64 = 100.;
const MS_FADE_SLOW : f64 = 750.;
const MS_FADE_FAST : f64 = 250.;
const MS_FADE_SLOW : f64 = 2500.;
pub struct TrainManagerTransitionImpl {
transition_prop: f64,
......@@ -26,29 +26,59 @@ impl TrainManagerTransitionImpl {
}
pub(super) struct TrainManagerTransition {
imp: Arc<Mutex<f64>>,
imp: Arc<Mutex<CrossFade>>,
runner: ZhooshRunner,
control: Option<ZhooshSequenceControl>,
zhoosh_fast: Zhoosh<Arc<Mutex<f64>>,f64>,
zhoosh_slow: Zhoosh<Arc<Mutex<f64>>,f64>
zhoosh_fast: Zhoosh<Arc<Mutex<CrossFade>>,CrossFade>,
zhoosh_slow: Zhoosh<Arc<Mutex<CrossFade>>,CrossFade>
}
fn modify_prop(v: f64, prop: f64, quad: f64) -> f64 {
let v = (1.-v/prop).max(0.).min(1.);
v*v*quad+v*(1.-quad)
}
#[derive(Clone,Copy)]
pub struct CrossFade(f64,f64,f64); /* (prop,dippyness,quadness) */
impl CrossFade {
pub fn get_prop_up(&self) -> f64 {
modify_prop(1.-self.0,self.1,self.2)
}
pub fn get_prop_down(&self) -> f64 {
modify_prop(self.0,self.1,self.2)
}
}
pub struct CrossFader(f64,f64);
impl ZhooshOps<CrossFade> for CrossFader {
fn interpolate(&self, prop: f64, from: &CrossFade, to: &CrossFade) -> CrossFade {
CrossFade(ZHOOSH_LINEAR_F64_OPS.interpolate(prop,&from.0,&to.0),self.0,self.1)
}
fn distance(&self, from: &CrossFade, to: &CrossFade) -> f64 {
ZHOOSH_LINEAR_F64_OPS.distance(&from.0,&to.0)
}
}
impl TrainManagerTransition {
pub(super) fn new() -> TrainManagerTransition {
TrainManagerTransition {
imp: Arc::new(Mutex::new(1.)),
imp: Arc::new(Mutex::new(CrossFade(1.,1.,0.))),
control: None,
runner: ZhooshRunner::new(),
zhoosh_fast: Zhoosh::new(MS_FADE_FAST,0.,0.,ZhooshShape::Quadratic(1.),ZHOOSH_LINEAR_F64_OPS,|imp: &mut Arc<Mutex<f64>>,val| {
zhoosh_fast: Zhoosh::new(MS_FADE_FAST,0.,0.,ZhooshShape::Linear,CrossFader(1.0,0.0),|imp: &mut Arc<Mutex<CrossFade>>,val| {
*imp.lock().unwrap() = val;
}),
zhoosh_slow: Zhoosh::new(MS_FADE_SLOW,0.,0.,ZhooshShape::Quadratic(1.),ZHOOSH_LINEAR_F64_OPS,|imp: &mut Arc<Mutex<f64>>,val| {
zhoosh_slow: Zhoosh::new(MS_FADE_SLOW,0.,0.,ZhooshShape::Linear,CrossFader(0.6,1.0),|imp: &mut Arc<Mutex<CrossFade>>,val| {
*imp.lock().unwrap() = val;
}),
}
}
pub(super) fn get_prop(&self) -> f64 {
pub(super) fn get_prop(&self) -> CrossFade {
*ok!(self.imp.lock())
}
......@@ -56,14 +86,15 @@ impl TrainManagerTransition {
if let Some(mut control) = self.control.take() {
control.abandon();
}
*ok!(self.imp.lock()) = 0.;
*ok!(self.imp.lock()) = CrossFade(0.,1.,0.);
}
pub(super) fn start(&mut self, t: f64, slow: bool) {
console!("start slow={:?}",slow);
self.reset();
let zhoosh = if slow { &self.zhoosh_slow } else { &self.zhoosh_fast };
let mut seq = ZhooshSequence::new();
seq.add(ZhooshStep::new(&zhoosh,self.imp.clone(),0.,1.));
seq.add(ZhooshStep::new(&zhoosh,self.imp.clone(),CrossFade(0.,1.,0.),CrossFade(1.,1.,0.)));
self.control = Some(seq.run(&mut self.runner));
}
......
......@@ -7619,8 +7619,8 @@
}
},
"ensembl-genome-browser": {
"version": "https://raw.githubusercontent.com/Ensembl/ensembl-genome-browser-assets/master/assets-50186459b62c96292dcea637e687d290.tar.gz",
"integrity": "sha512-GT02RoNC9pWqe/F7LyoGg6sBJn/gYpV/+bmujjy1f5dnmbsuCsbR5KDc2FT08RVAIaGqjAHdqLDLI5bAbt5wig=="
"version": "https://raw.githubusercontent.com/Ensembl/ensembl-genome-browser-assets/master/assets-36f906420abe1bf1e375d01ec70516c5.tar.gz",
"integrity": "sha512-UPlE9Lf1warjULCzyKBgsyEtvjcZDt3sEOzq10THs7tgZiTO5aFgfdPBFU6FASrJ8D0Vok7j6yu+b3j3VZA2Cg=="
},
"entities": {
"version": "1.1.2",
......
......@@ -54,7 +54,7 @@
"connected-react-router": "6.5.2",
"core-js": "3.3.6",
"dotenv": "8.2.0",
"ensembl-genome-browser": "https://raw.githubusercontent.com/Ensembl/ensembl-genome-browser-assets/master/assets-50186459b62c96292dcea637e687d290.tar.gz",
"ensembl-genome-browser": "https://raw.githubusercontent.com/Ensembl/ensembl-genome-browser-assets/master/assets-36f906420abe1bf1e375d01ec70516c5.tar.gz",
"koa-proxy": "1.0.0-alpha.3",
"lodash": "4.17.15",
"query-string": "6.8.3",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment