minitracing/src/anim.rs

76 lines
1.9 KiB
Rust

use glam::{vec3, Vec3};
use rand_distr::{Distribution, LogNormal, Uniform};
pub struct SphereParams {
pub radius: f32,
pub color: Vec3,
pub alpha: f32,
pub origin: Vec3,
pub amplitudes: Vec3,
pub frequencies: Vec3,
pub phases: Vec3,
}
pub struct SphereParamsDistribution {
pub drad: Uniform<f32>,
pub dpos: Uniform<f32>,
pub dcol: Uniform<f32>,
pub demit: LogNormal<f32>,
pub dampl: Uniform<f32>,
pub dfreq: Uniform<f32>,
pub dphase: Uniform<f32>,
}
impl Default for SphereParamsDistribution {
fn default() -> Self {
Self {
drad: Uniform::new(0.01, 0.10),
dpos: Uniform::new(-1.0, 1.0),
dcol: Uniform::new(0.0, 1.0),
demit: LogNormal::new(-0.8, 2.0).unwrap(),
dampl: Uniform::new(0.3, 0.8),
dfreq: Uniform::new(0.2, 1.5),
dphase: Uniform::new(0., 2. * std::f32::consts::PI),
}
}
}
impl SphereParamsDistribution {
pub fn make_params(&self, rgen: &mut impl rand::Rng) -> SphereParams {
SphereParams {
origin: self.dpos.sample3(rgen),
radius: self.drad.sample(rgen),
color: self.dcol.sample3(rgen).normalize(),
alpha: self.demit.sample(rgen),
amplitudes: self.dampl.sample3(rgen),
frequencies: self.dfreq.sample3(rgen),
phases: self.dphase.sample3(rgen),
}
}
}
impl SphereParams {
pub fn to_sphere(&self, time: f32) -> crate::Sphere {
let center = self.origin + self.amplitudes * (self.frequencies * time + self.phases).map(|x| x.sin());
let radius = self.radius;
let emit_color = self.alpha * self.color;
let reflect_color = 0.6 * self.color + Vec3::splat(0.2);
crate::Sphere {
center,
radius,
emit_color,
reflect_color,
}
}
}
trait VecDistribution {
fn sample3<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Vec3;
}
impl<T: Distribution<f32>> VecDistribution for T {
fn sample3<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Vec3 {
vec3(rng.sample(self), rng.sample(self), rng.sample(self))
}
}