gled-model 2.32.1

The data model of gled: projects, scenes, effects, animations, curves and assets
Documentation
use crate::{
    asset::{
        animation::{Animation, config::AnimationConfig},
        curve::multiplied_curve::{MultipliedCurve, RangeDegrees, RangePercentage},
    },
    asset_id::AssetId,
    collection::Collections,
    patching::layout::LayoutSelection,
    sound::trigger_ref::{CollectSoundTriggers, SoundLevels, SoundTriggerSet},
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct Effect {
    pub color_shift: MultipliedCurve<RangeDegrees>,
    pub opacity: MultipliedCurve<RangePercentage>,
    pub beat_progression: MultipliedCurve<RangePercentage>,
    pub beat_progression_offset: MultipliedCurve<RangePercentage>,
    /// In 2^n of bpm
    pub speed_exponent: i32,
    /// `None` inherits the tile's selection.
    pub selection: Option<LayoutSelection>,
    pub animation: Option<AssetId<Animation>>,
    pub animation_config: AnimationConfig,
}

impl Eq for Effect {}

impl Default for Effect {
    fn default() -> Self {
        Self {
            color_shift: MultipliedCurve::new_multiplier(0.0),
            opacity: MultipliedCurve::new_multiplier(1.0),
            beat_progression: MultipliedCurve::new_curve([
                0x2E, 0x07, 0x5C, 0xCB, 0x90, 0xC4, 0x47, 0x4B, 0x8D, 0x16, 0xC6, 0x70, 0x40, 0x54,
                0x99, 0xA6,
            ]),
            beat_progression_offset: MultipliedCurve::new_multiplier(0.0),
            speed_exponent: Default::default(),
            selection: None,
            animation: Default::default(),
            animation_config: Default::default(),
        }
    }
}

/// An effect's values at one moment, with its curves and sound triggers
/// applied: what the renderer draws it with.
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct EffectValues {
    /// The scene's beat moved by the effect's beat offset; the effect's
    /// settings are evaluated at it.
    pub beat: f32,
    /// The effect's progression curve at `beat`, which drives its animation.
    pub beat_progression: f32,
    pub opacity: f32,
    /// In degrees.
    pub color_shift: f32,
}

impl Effect {
    /// The effect's values at `scene_beat`, the scene's beat position.
    pub fn values(
        &self,
        scene_beat: f32,
        collections: &Collections,
        sound: &dyn SoundLevels,
    ) -> EffectValues {
        let beat = scene_beat
            + self
                .beat_progression_offset
                .value(scene_beat, collections, sound);
        EffectValues {
            beat,
            beat_progression: self.beat_progression.value(beat, collections, sound),
            opacity: self.opacity.value(beat, collections, sound),
            color_shift: self.color_shift.value(beat, collections, sound),
        }
    }
}

impl CollectSoundTriggers for Effect {
    fn collect_sound_triggers(&self, triggers: &mut SoundTriggerSet) {
        self.color_shift.collect_sound_triggers(triggers);
        self.opacity.collect_sound_triggers(triggers);
        self.beat_progression.collect_sound_triggers(triggers);
        self.beat_progression_offset
            .collect_sound_triggers(triggers);
        self.animation_config.collect_sound_triggers(triggers);
    }
}