pub struct SceneShake {
pub impacts: Vec<ShakeImpact>,
pub decay: f64,
pub frequency: f64,
pub rotation: f64,
}Expand description
Declarative camera shake: every impact in SceneShake::impacts is an
independent damped harmonic oscillator, summed together. Additive
over whatever super::scenario::Scene::camera already resolves to —
camera.keyframes is a single value-over-time series per property,
with no way to layer a second signal onto it without replacing the
first, so a shake needs its own field to coexist with a pan instead of
fighting over one keyframe track.
§Formula
For an impact of amplitude A landing at t0, its contribution at
t >= t0 (exactly zero before t0 — an impact never affects time
before it lands) is:
Δt = t - t0
envelope = A * exp(-decay * Δt)
phase = 2π * frequency * Δt
x = envelope * cos(phase)
y = envelope * sin(phase)
rotation = shake.rotation * x (degrees)x and y are 90° out of phase, so the combined offset traces a
decaying spiral rather than a straight line back and forth — this is
what reads as a shake instead of a bounce. decay (1/seconds) is
the exponential rate: the envelope reaches 1/e (~37%) of its peak
after 1/decay seconds. frequency (Hz) is how many oscillations per
second it makes while decaying. rotation is a degrees-per-pixel
coefficient applied to the already-computed x offset — not an
independent oscillator — so the twist always stays in phase with the
translation instead of drifting against it; 0.0 (the default)
disables rotational shake entirely.
Multiple impacts are summed — not replaced — at every instant, so a fast retrigger before the previous impact has decayed accumulates rather than resetting: the same physical intuition as striking a bell twice in quick succession.
Fields§
§impacts: Vec<ShakeImpact>Every hit contributing to this scene’s shake. Impacts are summed,
not last-wins — see SceneShake’s formula.
decay: f64Exponential decay rate, in 1/seconds. Higher decays faster: the
envelope reaches 1/e of its peak after 1/decay seconds.
Default: 10.0 (~0.1s to 1/e, fully read as settled well within half
a second).
frequency: f64Oscillations per second while the envelope decays. Default: 20.0.
rotation: f64Degrees of rotational shake per pixel of the (already-computed) x
offset — see SceneShake’s formula. 0.0 (default) disables
rotational shake.
Trait Implementations§
Source§impl Clone for SceneShake
impl Clone for SceneShake
Source§impl Debug for SceneShake
impl Debug for SceneShake
Source§impl<'de> Deserialize<'de> for SceneShake
impl<'de> Deserialize<'de> for SceneShake
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl JsonSchema for SceneShake
impl JsonSchema for SceneShake
Source§fn schema_name() -> String
fn schema_name() -> String
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn is_referenceable() -> bool
fn is_referenceable() -> bool
$ref keyword. Read moreSource§impl PartialEq for SceneShake
impl PartialEq for SceneShake
Source§impl Serialize for SceneShake
impl Serialize for SceneShake
impl StructuralPartialEq for SceneShake
Auto Trait Implementations§
impl Freeze for SceneShake
impl RefUnwindSafe for SceneShake
impl Send for SceneShake
impl Sync for SceneShake
impl Unpin for SceneShake
impl UnsafeUnpin for SceneShake
impl UnwindSafe for SceneShake
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more