use std::f32::consts::PI;
use vera::{Transformation, Tf, Evolution, Cl, Colorization};
use crate::{Mat4, Color};
impl Mat4 {
fn from_t(transformation: Transformation, advancement: f32) -> Self {
match transformation {
Transformation::Scale(x, y, z) => Self::scale(x * advancement + (1.0 - advancement), y * advancement + (1.0 - advancement), z * advancement + (1.0 - advancement)),
Transformation::Translate(x, y, z) => Self::translate(x * advancement, y * advancement, z * advancement),
Transformation::RotateX(angle) => Self::rotate_x(angle * advancement),
Transformation::RotateY(angle) => Self::rotate_y(angle * advancement),
Transformation::RotateZ(angle) => Self::rotate_z(angle * advancement),
Transformation::Lookat(eye_x, eye_y, eye_z, target_x, target_y, target_z, up_x, up_y, up_z) => Self::lookat(eye_x * advancement, eye_y * advancement, eye_z * advancement, target_x * advancement, target_y * advancement, target_z * advancement, up_x * advancement, up_y * advancement, up_z * advancement),
Transformation::Perspective(l, r, b, t, n, f) => Self::project_perspective(l * advancement, r * advancement, b * advancement, t * advancement, n * advancement, f * advancement),
_ => { println!("Transformation not implemented, ignoring."); Mat4::new() },
}
}
}
pub(crate) struct Transformer {
previous: Vec<Tf>,
current: Vec<Tf>,
result: Mat4,
}
impl Transformer {
pub(crate) fn from_t(transformations: Vec<Tf>) -> Self {
Self {
previous: Vec::with_capacity(transformations.len()),
current: transformations,
result: Mat4::new(),
}
}
pub(crate) fn update_vm(&mut self, time: f32) -> Mat4 {
let mut buffer_matrix = self.result;
self.current.iter().for_each(|tf| {
let adv: f32 = advancement(tf.start, tf.end, time, tf.e);
if adv>0.0 {
buffer_matrix.mult(Mat4::from_t(tf.t, adv));
}
});
buffer_matrix
}
pub(crate) fn update_vp(&mut self, time: f32) -> Mat4 {
let mut buffer_matrix = self.result;
self.current.iter().for_each(|tf| {
let adv: f32 = advancement(tf.start, tf.end, time, tf.e);
if adv>0.0 {
buffer_matrix.interpolate(Mat4::from_t(tf.t, 1.0), adv);
}
});
buffer_matrix
}
}
pub(crate) struct Colorizer {
previous: Vec<Cl>,
current: Vec<Cl>,
result: Color,
}
impl Color {
fn with_c(&mut self, colorization: Colorization, advancement: f32) {
match colorization {
Colorization::ToColor(r, g, b, a) => self.interpolate([r, g, b, a], advancement),
_ => { println!("No colorization applied, unknown colorization."); },
}
}
}
impl Colorizer {
pub(crate) fn from_c(initial_color: [f32 ; 4], colorizations: Vec<Cl>) -> Self {
Self {
previous: Vec::with_capacity(colorizations.len()),
current: colorizations,
result: Color(initial_color),
}
}
pub(crate) fn update(&mut self, time: f32) -> Color {
let mut buffer_color = self.result;
self.current.iter().for_each(|cl| { buffer_color.with_c(cl.c, advancement(cl.start, cl.end, time, cl.e)); });
buffer_color
}
}
fn advancement(start: f32, end: f32, time: f32, e: Evolution) -> f32 {
if start>=end {
if time<start { return 0.0; }
else { return 1.0; }
}
if time < start {
return 0.0;
}
if time >= end {
return 1.0
}
let init: f32 = (time-start)/(end-start);
match e {
Evolution::Linear => {
init
}
Evolution::FastIn => {
(init * PI / 2.0).sin()
}
Evolution::SlowOut => {
(init * PI / 2.0).sin()
}
Evolution::FastOut => {
1.0 - (init * PI / 2.0).cos()
}
Evolution::SlowIn => {
1.0 - (init * PI / 2.0).cos()
}
Evolution::FastMiddle => {
(((init - 0.5) * PI).sin() + 1.0) / 2.0
}
Evolution::SlowInOut => {
(((init - 0.5) * PI).sin() + 1.0) / 2.0
}
Evolution::FastInOut => {
if init < 0.5 { (init * PI).sin() / 2.0 }
else { 0.5 + (1.0 - (init * PI).sin()) / 2.0 }
}
Evolution::SlowMiddle => {
if init < 0.5 { (init * PI).sin() / 2.0 }
else { 0.5 + (1.0 - (init * PI).sin()) / 2.0 }
}
}
}