1#[cfg(target_arch = "wasm32")]
6#[allow(unused_imports)]
7use crate::storage::load_section;
8use crate::storage::SectionStorage;
9use bevy::prelude::*;
10
11pub struct SectionPlanePlugin;
13
14impl Plugin for SectionPlanePlugin {
15 fn build(&self, app: &mut App) {
16 app.init_resource::<SectionPlane>()
17 .add_systems(Update, poll_section_settings);
18 }
19}
20
21#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
23pub enum SectionAxis {
24 X,
25 #[default]
26 Y,
27 Z,
28}
29
30impl SectionAxis {
31 pub fn normal(&self, flipped: bool) -> Vec3 {
33 let base = match self {
34 SectionAxis::X => Vec3::X,
35 SectionAxis::Y => Vec3::Y,
36 SectionAxis::Z => Vec3::Z,
37 };
38 if flipped {
39 -base
40 } else {
41 base
42 }
43 }
44
45 pub fn parse(s: &str) -> Self {
47 match s.to_lowercase().as_str() {
48 "x" => SectionAxis::X,
49 "y" => SectionAxis::Y,
50 _ => SectionAxis::Z,
51 }
52 }
53
54 pub fn as_str(&self) -> &'static str {
56 match self {
57 SectionAxis::X => "x",
58 SectionAxis::Y => "y",
59 SectionAxis::Z => "z",
60 }
61 }
62}
63
64#[derive(Resource)]
66pub struct SectionPlane {
67 pub enabled: bool,
69 pub axis: SectionAxis,
71 pub position: f32,
73 pub flipped: bool,
75 pub plane: Vec4,
77}
78
79impl Default for SectionPlane {
80 fn default() -> Self {
81 Self {
82 enabled: false,
83 axis: SectionAxis::Y,
84 position: 0.5,
85 flipped: false,
86 plane: Vec4::new(0.0, 1.0, 0.0, 0.0),
87 }
88 }
89}
90
91impl SectionPlane {
92 pub fn set_axis(&mut self, axis: SectionAxis) {
94 self.axis = axis;
95 self.update_plane();
96 }
97
98 pub fn set_position(&mut self, position: f32) {
100 self.position = position.clamp(0.0, 1.0);
101 self.update_plane();
102 }
103
104 pub fn toggle_flip(&mut self) {
106 self.flipped = !self.flipped;
107 self.update_plane();
108 }
109
110 pub fn toggle(&mut self) {
112 self.enabled = !self.enabled;
113 }
114
115 pub fn update_plane(&mut self) {
117 let normal = self.axis.normal(self.flipped);
118 self.plane = Vec4::new(normal.x, normal.y, normal.z, 0.0);
120 }
121
122 pub fn update_with_bounds(&mut self, min: Vec3, max: Vec3) {
124 let normal = self.axis.normal(self.flipped);
125 let axis_min = match self.axis {
126 SectionAxis::X => min.x,
127 SectionAxis::Y => min.y,
128 SectionAxis::Z => min.z,
129 };
130 let axis_max = match self.axis {
131 SectionAxis::X => max.x,
132 SectionAxis::Y => max.y,
133 SectionAxis::Z => max.z,
134 };
135 let distance = axis_min + (axis_max - axis_min) * self.position;
136 self.plane = Vec4::new(normal.x, normal.y, normal.z, distance);
137 }
138
139 pub fn from_storage(&mut self, storage: &SectionStorage) {
141 self.enabled = storage.enabled;
142 self.axis = SectionAxis::parse(&storage.axis);
143 self.position = storage.position;
144 self.flipped = storage.flipped;
145 self.update_plane();
146 }
147
148 pub fn to_storage(&self) -> SectionStorage {
150 SectionStorage {
151 enabled: self.enabled,
152 axis: self.axis.as_str().to_string(),
153 position: self.position,
154 flipped: self.flipped,
155 }
156 }
157}
158
159#[allow(unused_mut)]
161fn poll_section_settings(mut section: ResMut<SectionPlane>) {
162 #[cfg(target_arch = "wasm32")]
163 {
164 static mut POLL_COUNTER: u32 = 0;
166 unsafe {
167 POLL_COUNTER += 1;
168 if POLL_COUNTER % 30 == 0 {
169 if let Some(storage) = load_section() {
170 if storage.enabled != section.enabled
171 || storage.axis != section.axis.as_str()
172 || storage.position != section.position
173 || storage.flipped != section.flipped
174 {
175 section.from_storage(&storage);
176 }
177 }
178 }
179 }
180 }
181
182 let _ = §ion;
184}
185
186#[derive(Clone, Debug)]
207pub struct SectionPlaneMaterial {
208 pub base_color: Color,
209 pub section_plane: Vec4,
210 pub section_enabled: bool,
211}