bevy_silk/stick.rs
1use bevy::{math::Vec3, reflect::Reflect};
2
3/// Defines how the cloth will compute sticks from mesh indices.
4#[derive(Debug, Copy, Clone, Default, Reflect, PartialEq, Eq)]
5pub enum StickGeneration {
6 #[default]
7 /// 2 sticks will be generated by triangle, following the actual quad edges
8 Quads,
9 /// 3 sticks will be generated by triangle
10 Triangles,
11}
12
13/// Defines the target length of cloth sticks
14#[derive(Debug, Copy, Clone, Default, Reflect)]
15pub enum StickLen {
16 #[default]
17 /// The target length will be the actual distance between the vertices
18 Auto,
19 /// Custom target length
20 Fixed(f32),
21 /// Same as [`StickLen::Auto`] with a custom additional offset
22 Offset(f32),
23 /// Same as [`StickLen::Auto`] with a custom coefficient
24 Coefficient(f32),
25}
26
27/// Defines cloth stick behaviour
28#[derive(Debug, Copy, Clone, Default, Reflect)]
29pub enum StickMode {
30 /// The stick will attempt to always remain at the same length (See
31 /// [`StickLen`]). This is the default behaviour and the fastest to
32 /// compute.
33 #[default]
34 Fixed,
35 /// The stick will clamp its length between a `min_percent` and
36 /// `max_percent` of its expected length (See [`StickLen`]).
37 ///
38 /// For example, the following mode:
39 /// ```rust
40 /// # use bevy_silk::prelude::*;
41 /// let mode = StickMode::Spring {
42 /// min_percent: 0.0,
43 /// max_percent: 1.0,
44 /// };
45 /// ```
46 /// will behave like a [`StickMode::Fixed`].
47 ///
48 /// # Notes
49 ///
50 /// * Please note that this mode is slower, as some distance computing
51 /// involving square roots, will happen every frame. If you just want to
52 /// have smaller or larger sticks, prefer setting a different [`StickLen`]
53 /// instead
54 /// * Setting invalid `min_percent` and `max_percent` will result in
55 /// unexpected behaviour:
56 /// - max value being lower than the min value
57 /// - use of negative values
58 /// * Setting both values to `None` will result in no constraint
59 /// * The values are percentages expressed between 0 and 1:
60 /// - `0.0` means 0%
61 /// - `0.5` means 50%
62 /// - `1.0` means 100%
63 /// - `2.0` means 200%
64 Spring {
65 /// The stick will attempt to be at least this percent of its expected
66 /// length.
67 min_percent: f32,
68 /// The stick will attempt to be at most this percent of its expected
69 /// length.
70 max_percent: f32,
71 },
72}
73
74impl StickLen {
75 /// Retrieves the stick length from the two points it connects
76 #[must_use]
77 pub fn get_len(&self, point_a: Vec3, point_b: Vec3) -> f32 {
78 match self {
79 Self::Auto => point_a.distance(point_b),
80 Self::Fixed(v) => *v,
81 Self::Offset(offset) => point_a.distance(point_b) + offset,
82 Self::Coefficient(coeff) => point_a.distance(point_b) * coeff,
83 }
84 }
85}
86
87impl From<[f32; 2]> for StickMode {
88 fn from([min, max]: [f32; 2]) -> Self {
89 Self::Spring {
90 min_percent: min,
91 max_percent: max,
92 }
93 }
94}
95
96impl From<(f32, f32)> for StickMode {
97 fn from((min, max): (f32, f32)) -> Self {
98 Self::Spring {
99 min_percent: min,
100 max_percent: max,
101 }
102 }
103}