dreamwell_engine/physics/
collision.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub enum CollisionMode {
6 None,
7 Plane,
8 TerrainHeightfield,
9 DepthBuffer,
10 SignedDistanceField,
11 ProxyCollider,
12 VoxelGrid,
13}
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub enum CollisionResponse {
18 Bounce,
19 Slide,
20 Stick,
21 Die,
22 Split,
23 Shatter,
24 Embed,
25 Sleep,
26 Promote,
27 TriggerSubEmitter,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct CollisionPolicy {
33 pub mode: CollisionMode,
34 pub response: CollisionResponse,
35 pub restitution: f32,
36 pub friction: f32,
37 pub radius: f32,
38 pub max_collisions: u32,
39 pub material_response_table: Option<String>,
40}
41
42impl Default for CollisionPolicy {
43 fn default() -> Self {
44 Self {
45 mode: CollisionMode::None,
46 response: CollisionResponse::Bounce,
47 restitution: 0.5,
48 friction: 0.3,
49 radius: 0.05,
50 max_collisions: 4,
51 material_response_table: None,
52 }
53 }
54}
55
56impl CollisionMode {
57 pub const ALL: &[CollisionMode] = &[
58 Self::None,
59 Self::Plane,
60 Self::TerrainHeightfield,
61 Self::DepthBuffer,
62 Self::SignedDistanceField,
63 Self::ProxyCollider,
64 Self::VoxelGrid,
65 ];
66}
67
68impl CollisionResponse {
69 pub const ALL: &[CollisionResponse] = &[
70 Self::Bounce,
71 Self::Slide,
72 Self::Stick,
73 Self::Die,
74 Self::Split,
75 Self::Shatter,
76 Self::Embed,
77 Self::Sleep,
78 Self::Promote,
79 Self::TriggerSubEmitter,
80 ];
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn collision_mode_all() {
89 assert_eq!(CollisionMode::ALL.len(), 7);
90 }
91
92 #[test]
93 fn collision_response_all() {
94 assert_eq!(CollisionResponse::ALL.len(), 10);
95 }
96
97 #[test]
98 fn collision_policy_default() {
99 let p = CollisionPolicy::default();
100 assert_eq!(p.mode, CollisionMode::None);
101 assert_eq!(p.response, CollisionResponse::Bounce);
102 }
103
104 #[test]
105 fn collision_policy_serde() {
106 let p = CollisionPolicy {
107 mode: CollisionMode::SignedDistanceField,
108 response: CollisionResponse::Slide,
109 restitution: 0.18,
110 friction: 0.82,
111 radius: 0.06,
112 max_collisions: 12,
113 material_response_table: Some("mat/stone".into()),
114 };
115 let json = serde_json::to_string(&p).unwrap();
116 let restored: CollisionPolicy = serde_json::from_str(&json).unwrap();
117 assert_eq!(restored.mode, CollisionMode::SignedDistanceField);
118 assert_eq!(restored.max_collisions, 12);
119 }
120}