steel_core/physics/
physics_state.rs1use glam::DVec3;
4#[cfg(test)]
5use steel_registry::entity_type::EntityDimensions;
6use steel_utils::WorldAabb;
7
8use crate::behavior::BlockCollisionContext;
9
10#[derive(Debug, Clone, Copy)]
16pub(crate) struct EntityPhysicsState {
17 position: DVec3,
19
20 bounding_box: WorldAabb,
22
23 max_up_step: f32,
25
26 backs_off_from_edge: bool,
28
29 on_ground: bool,
31
32 fall_distance: f64,
34
35 descending: bool,
37
38 can_walk_on_powder_snow: bool,
40
41 is_falling_block: bool,
43}
44
45impl EntityPhysicsState {
46 #[must_use]
51 pub const fn new(position: DVec3, bounding_box: WorldAabb, max_up_step: f32) -> Self {
52 Self {
53 position,
54 bounding_box,
55 max_up_step,
56 backs_off_from_edge: false,
57 on_ground: false,
58 fall_distance: 0.0,
59 descending: false,
60 can_walk_on_powder_snow: false,
61 is_falling_block: false,
62 }
63 }
64
65 #[cfg(test)]
67 #[must_use]
68 pub fn with_dimensions(
69 position: DVec3,
70 dimensions: EntityDimensions,
71 max_up_step: f32,
72 ) -> Self {
73 let bounding_box = Self::make_bounding_box(position, &dimensions);
74
75 Self::new(position, bounding_box, max_up_step)
76 }
77
78 #[cfg(test)]
81 #[must_use]
82 fn make_bounding_box(position: DVec3, dimensions: &EntityDimensions) -> WorldAabb {
83 let half_width = f64::from(dimensions.width) / 2.0;
84 let height = f64::from(dimensions.height);
85
86 WorldAabb::entity_box(position.x, position.y, position.z, half_width, height)
87 }
88
89 #[must_use]
91 pub const fn position(self) -> DVec3 {
92 self.position
93 }
94
95 #[must_use]
97 pub const fn bounding_box(self) -> WorldAabb {
98 self.bounding_box
99 }
100
101 #[must_use]
103 pub const fn max_up_step(self) -> f32 {
104 self.max_up_step
105 }
106
107 #[must_use]
109 pub const fn backs_off_from_edge(self) -> bool {
110 self.backs_off_from_edge
111 }
112
113 #[must_use]
115 pub const fn on_ground(self) -> bool {
116 self.on_ground
117 }
118
119 #[must_use]
121 pub const fn fall_distance(self) -> f64 {
122 self.fall_distance
123 }
124
125 #[must_use]
127 pub const fn block_collision_context(self) -> BlockCollisionContext {
128 BlockCollisionContext::entity(self.position.y, self.descending)
129 .with_fall_distance(self.fall_distance)
130 .with_can_walk_on_powder_snow(self.can_walk_on_powder_snow)
131 .with_falling_block(self.is_falling_block)
132 }
133
134 #[must_use]
136 pub const fn with_on_ground(mut self, on_ground: bool) -> Self {
137 self.on_ground = on_ground;
138 self
139 }
140
141 #[must_use]
143 pub const fn with_backs_off_from_edge(mut self, backs_off_from_edge: bool) -> Self {
144 self.backs_off_from_edge = backs_off_from_edge;
145 self
146 }
147
148 #[must_use]
150 pub const fn with_fall_distance(mut self, fall_distance: f64) -> Self {
151 self.fall_distance = fall_distance;
152 self
153 }
154
155 #[must_use]
157 pub const fn with_descending(mut self, descending: bool) -> Self {
158 self.descending = descending;
159 self
160 }
161
162 #[must_use]
164 pub const fn with_can_walk_on_powder_snow(mut self, can_walk_on_powder_snow: bool) -> Self {
165 self.can_walk_on_powder_snow = can_walk_on_powder_snow;
166 self
167 }
168
169 #[must_use]
171 pub const fn with_falling_block(mut self, is_falling_block: bool) -> Self {
172 self.is_falling_block = is_falling_block;
173 self
174 }
175}