1use super::{Fluid, Ori, ship::figuredata::ShipSpec};
2use crate::{
3 comp::{body::ship::figuredata::VoxelCollider, inventory::item::armor::Friction},
4 consts::WATER_DENSITY,
5 terrain::Block,
6 uid::Uid,
7 util::Dir,
8};
9use hashbrown::HashMap;
10use serde::{Deserialize, Serialize};
11use specs::{Component, DerefFlaggedStorage, NullStorage, VecStorage};
12use std::sync::Arc;
13use vek::*;
14
15#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
17pub struct Pos(pub Vec3<f32>);
18
19impl Component for Pos {
20 type Storage = VecStorage<Self>;
21}
22
23#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
25pub struct Vel(pub Vec3<f32>);
26
27impl Vel {
28 pub fn zero() -> Self { Vel(Vec3::zero()) }
29
30 pub fn to_dir(&self) -> Dir { Dir::from_unnormalized(self.0).unwrap_or_default() }
31}
32
33impl Component for Vel {
34 type Storage = VecStorage<Self>;
35}
36
37#[derive(Copy, Clone, Debug)]
39pub struct PosVelOriDefer {
40 pub pos: Option<Pos>,
41 pub vel: Option<Vel>,
42 pub ori: Option<Ori>,
43}
44
45impl Component for PosVelOriDefer {
46 type Storage = VecStorage<Self>;
47}
48
49#[derive(Copy, Clone, Default, Debug, PartialEq)]
53pub struct PreviousPhysCache {
54 pub velocity: Vec3<f32>,
55 pub velocity_dt: Vec3<f32>,
56 pub in_fluid: Option<Fluid>,
57 pub center: Vec3<f32>,
60 pub collision_boundary: f32,
62 pub scale: f32,
63 pub scaled_radius: f32,
65 pub neighborhood_radius: f32,
67 pub origins: Option<(Vec2<f32>, Vec2<f32>)>,
69 pub pos: Option<Pos>,
70 pub ori: Quaternion<f32>,
71}
72
73impl Component for PreviousPhysCache {
74 type Storage = VecStorage<Self>;
75}
76
77#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
79pub struct Scale(pub f32);
80
81impl Component for Scale {
82 type Storage = DerefFlaggedStorage<Self, VecStorage<Self>>;
83}
84
85#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
87pub struct Mass(pub f32);
88
89impl Default for Mass {
90 fn default() -> Mass { Mass(1.0) }
91}
92
93impl Component for Mass {
94 type Storage = DerefFlaggedStorage<Self, VecStorage<Self>>;
95}
96
97#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
100pub struct Density(pub f32);
101
102impl Default for Density {
103 fn default() -> Density { Density(WATER_DENSITY) }
104}
105
106impl Component for Density {
107 type Storage = DerefFlaggedStorage<Self, VecStorage<Self>>;
108}
109
110#[derive(Clone, Debug, Serialize, Deserialize)]
112pub enum Collider {
113 Voxel {
117 id: String,
118 },
119 Volume(Arc<VoxelCollider>),
121 CapsulePrism {
123 p0: Vec2<f32>,
124 p1: Vec2<f32>,
125 radius: f32,
126 z_min: f32,
127 z_max: f32,
128 },
129 Point,
130}
131
132impl Collider {
133 pub fn is_voxel(&self) -> bool { matches!(self, Collider::Voxel { .. } | Collider::Volume(_)) }
134
135 pub fn get_vol<'a>(&'a self, ship_spec: &'a ShipSpec) -> Option<&'a VoxelCollider> {
136 match self {
137 Collider::Voxel { id } => ship_spec.colliders.get(id),
138 Collider::Volume(vol) => Some(&**vol),
139 _ => None,
140 }
141 }
142
143 pub fn bounding_radius(&self) -> f32 {
144 match self {
145 Collider::Voxel { .. } | Collider::Volume(_) => 1.0,
146 Collider::CapsulePrism { radius, p0, p1, .. } => {
147 let a = p0.distance(*p1);
148 a / 2.0 + *radius
149 },
150 Collider::Point => 0.0,
151 }
152 }
153
154 pub fn get_height(&self) -> f32 {
155 let (z_min, z_max) = self.get_z_limits(1.0);
156 z_max - z_min
157 }
158
159 pub fn get_z_limits(&self, modifier: f32) -> (f32, f32) {
160 match self {
161 Collider::Voxel { .. } | Collider::Volume(_) => (0.0, 2.0),
162 Collider::CapsulePrism { z_min, z_max, .. } => (*z_min * modifier, *z_max * modifier),
163 Collider::Point => (0.0, 0.0),
164 }
165 }
166}
167
168impl Component for Collider {
169 type Storage = DerefFlaggedStorage<Self, VecStorage<Self>>;
170}
171
172#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
173pub struct Sticky;
174
175impl Component for Sticky {
176 type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
177}
178
179#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
180pub struct Immovable;
181
182impl Component for Immovable {
183 type Storage = DerefFlaggedStorage<Self, NullStorage<Self>>;
184}
185
186#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
188pub struct PhysicsState {
189 pub on_ground: Option<Block>,
190 pub on_ceiling: bool,
191 pub on_wall: Option<Vec3<f32>>,
192 pub touch_entities: HashMap<Uid, Vec3<f32>>,
193 pub in_fluid: Option<Fluid>,
194 pub ground_vel: Vec3<f32>,
195 pub footwear: Friction,
196 pub skating_last_height: f32,
197 pub skating_active: bool,
198}
199
200impl PhysicsState {
201 pub fn reset(&mut self) {
202 let mut touch_entities = std::mem::take(&mut self.touch_entities);
204 touch_entities.clear();
205 *self = Self {
206 touch_entities,
207 ground_vel: self.ground_vel, ..Self::default()
210 }
211 }
212
213 pub fn on_surface(&self) -> Option<Vec3<f32>> {
214 self.on_ground
215 .map(|_| -Vec3::unit_z())
216 .or_else(|| self.on_ceiling.then_some(Vec3::unit_z()))
217 .or(self.on_wall)
218 }
219
220 pub fn in_liquid(&self) -> Option<f32> { self.in_fluid.and_then(|fluid| fluid.depth()) }
221}
222
223impl Component for PhysicsState {
224 type Storage = VecStorage<Self>;
225}
226
227#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
230pub struct ForceUpdate {
231 flag: bool,
232 counter: u64,
233}
234
235impl ForceUpdate {
236 pub fn forced() -> Self {
237 Self {
238 flag: true,
239 counter: 0,
240 }
241 }
242
243 pub fn update(&mut self) {
244 self.flag = true;
245 self.counter = self.counter.wrapping_add(1);
246 }
247
248 pub fn clear(&mut self) { self.flag = false; }
249
250 pub fn is_forced(&self) -> bool { self.flag }
251
252 pub fn counter(&self) -> u64 { self.counter }
253}
254
255impl Component for ForceUpdate {
256 type Storage = VecStorage<Self>;
257}