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}