bevy_utilitarian/randomized_values/
mod.rs1use bevy::prelude::*;
2use serde::{Deserialize, Serialize};
3use std::f32::consts::PI;
4
5pub trait RandValue {
6 type Out;
7
8 fn generate(&self) -> Self::Out;
9 fn constant(value: Self::Out) -> Self;
10}
11
12#[derive(Debug, Clone, Copy, Reflect, Default, Serialize, Deserialize)]
13pub struct RandF32 {
14 pub min: f32,
15 pub max: f32,
16}
17
18impl RandValue for RandF32 {
19 type Out = f32;
20
21 fn generate(&self) -> f32 {
22 rand::random::<f32>() * (self.max - self.min) + self.min
23 }
24
25 fn constant(value: f32) -> Self {
26 Self {
27 min: value,
28 max: value,
29 }
30 }
31}
32
33#[derive(Debug, Clone, Copy, Reflect, Serialize, Deserialize)]
34pub struct RandVec3 {
35 pub magnitude: RandF32,
36 pub direction: Vec3,
37 pub spread: f32,
38}
39
40impl RandValue for RandVec3 {
41 type Out = Vec3;
42
43 fn generate(&self) -> Vec3 {
44 let dir = if self.spread > 0. {
45 let spread_angle = rand::random::<f32>() * 2. * PI;
46 let spread_radius = rand::random::<f32>() * self.spread;
47
48 let local_dir = Quat::from_rotation_x(spread_angle)
49 * Vec3::new(spread_radius.cos(), 0., spread_radius.sin());
50
51 Quat::from_rotation_arc(Vec3::X, self.direction) * local_dir
52 } else {
53 self.direction.normalize_or_zero()
54 };
55
56 dir * self.magnitude.generate()
57 }
58
59 fn constant(value: Vec3) -> Self {
60 Self {
61 direction: value.normalize_or_zero(),
62 magnitude: RandF32::constant(value.length()),
63 spread: 0.,
64 }
65 }
66}
67
68impl Default for RandVec3 {
69 fn default() -> Self {
70 Self {
71 magnitude: RandF32::default(),
72 direction: Vec3::X,
73 spread: 0.,
74 }
75 }
76}