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