bevy_flowfield_tiles_plugin/
bundle.rs1use crate::prelude::*;
6use bevy::prelude::*;
7
8#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10#[derive(Bundle)]
11pub struct FlowFieldTilesBundle {
12 pub sector_cost_fields: SectorCostFields,
14 pub sector_portals: SectorPortals,
16 pub portal_graph: PortalGraph,
18 pub map_dimensions: MapDimensions,
20 pub route_cache: RouteCache,
22 pub flow_field_cache: FlowFieldCache,
24}
25
26impl FlowFieldTilesBundle {
27 pub fn get_sector_cost_fields(&self) -> &SectorCostFields {
29 &self.sector_cost_fields
30 }
31 pub fn get_sector_portals(&self) -> &SectorPortals {
33 &self.sector_portals
34 }
35 pub fn get_portal_graph(&self) -> &PortalGraph {
37 &self.portal_graph
38 }
39 pub fn get_map_dimensions(&self) -> &MapDimensions {
41 &self.map_dimensions
42 }
43 pub fn get_route_cache(&self) -> &RouteCache {
45 &self.route_cache
46 }
47 pub fn get_route_cache_mut(&mut self) -> &mut RouteCache {
49 &mut self.route_cache
50 }
51 pub fn get_flowfield_cache(&self) -> &FlowFieldCache {
53 &self.flow_field_cache
54 }
55 pub fn get_flowfield_cache_mut(&mut self) -> &mut FlowFieldCache {
57 &mut self.flow_field_cache
58 }
59 pub fn new(map_length: u32, map_depth: u32, sector_resolution: u32, actor_size: f32) -> Self {
61 let map_dimensions =
62 MapDimensions::new(map_length, map_depth, sector_resolution, actor_size);
63 let cost_fields = SectorCostFields::new(&map_dimensions);
64 let mut portals = SectorPortals::new(map_length, map_depth, sector_resolution);
65 for sector_id in cost_fields.get_scaled().keys() {
67 portals.update_portals(*sector_id, &cost_fields, &map_dimensions);
68 }
69 let graph = PortalGraph::new(&portals, &cost_fields, &map_dimensions);
70 let route_cache = RouteCache::default();
71 let cache = FlowFieldCache::default();
72 FlowFieldTilesBundle {
73 sector_cost_fields: cost_fields,
74 sector_portals: portals,
75 portal_graph: graph,
76 map_dimensions,
77 route_cache,
78 flow_field_cache: cache,
79 }
80 }
81 #[cfg(feature = "ron")]
83 pub fn from_ron(
84 map_length: u32,
85 map_depth: u32,
86 sector_resolution: u32,
87 actor_size: f32,
88 path: &str,
89 ) -> Self {
90 let map_dimensions =
91 MapDimensions::new(map_length, map_depth, sector_resolution, actor_size);
92 let cost_fields = SectorCostFields::from_ron(path.to_string(), &map_dimensions);
93 if ((map_length * map_depth) / (sector_resolution * sector_resolution)) as usize
94 != cost_fields.get_baseline().len()
95 {
96 panic!("Map size ({}, {}) with resolution {} produces ({}x{}) sectors. Ron file only produces {} sectors", map_length, map_depth, sector_resolution, map_length/sector_resolution, map_depth/sector_resolution, cost_fields.get_baseline().len());
97 }
98 let mut portals = SectorPortals::new(map_length, map_depth, sector_resolution);
99 for sector_id in cost_fields.get_scaled().keys() {
101 portals.update_portals(*sector_id, &cost_fields, &map_dimensions);
102 }
103 let graph = PortalGraph::new(&portals, &cost_fields, &map_dimensions);
104 let route_cache = RouteCache::default();
105 let cache = FlowFieldCache::default();
106 FlowFieldTilesBundle {
107 sector_cost_fields: cost_fields,
108 sector_portals: portals,
109 portal_graph: graph,
110 map_dimensions,
111 route_cache,
112 flow_field_cache: cache,
113 }
114 }
115 #[cfg(not(tarpaulin_include))]
117 #[cfg(feature = "csv")]
118 pub fn from_csv(
119 map_length: u32,
120 map_depth: u32,
121 sector_resolution: u32,
122 actor_size: f32,
123 directory: &str,
124 ) -> Self {
125 let map_dimensions =
126 MapDimensions::new(map_length, map_depth, sector_resolution, actor_size);
127 let cost_fields = SectorCostFields::from_csv_dir(&map_dimensions, directory.to_string());
128 let mut portals = SectorPortals::new(map_length, map_depth, sector_resolution);
129 for sector_id in cost_fields.get_scaled().keys() {
131 portals.update_portals(*sector_id, &cost_fields, &map_dimensions);
132 }
133 let graph = PortalGraph::new(&portals, &cost_fields, &map_dimensions);
134 let route_cache = RouteCache::default();
135 let cache = FlowFieldCache::default();
136 FlowFieldTilesBundle {
137 sector_cost_fields: cost_fields,
138 sector_portals: portals,
139 portal_graph: graph,
140 map_dimensions,
141 route_cache,
142 flow_field_cache: cache,
143 }
144 }
145 #[cfg(not(tarpaulin_include))]
148 #[cfg(feature = "heightmap")]
149 pub fn from_heightmap(
150 map_length: u32,
151 map_depth: u32,
152 sector_resolution: u32,
153 actor_size: f32,
154 file_path: &str,
155 ) -> Self {
156 let map_dimensions =
157 MapDimensions::new(map_length, map_depth, sector_resolution, actor_size);
158 let cost_fields = SectorCostFields::from_heightmap(&map_dimensions, file_path.to_string());
159 let mut portals = SectorPortals::new(map_length, map_depth, sector_resolution);
160 for sector_id in cost_fields.get_scaled().keys() {
162 portals.update_portals(*sector_id, &cost_fields, &map_dimensions);
163 }
164 let graph = PortalGraph::new(&portals, &cost_fields, &map_dimensions);
165 let route_cache = RouteCache::default();
166 let cache = FlowFieldCache::default();
167 FlowFieldTilesBundle {
168 sector_cost_fields: cost_fields,
169 sector_portals: portals,
170 portal_graph: graph,
171 map_dimensions,
172 route_cache,
173 flow_field_cache: cache,
174 }
175 }
176 #[cfg(not(tarpaulin_include))]
182 #[cfg(feature = "2d")]
183 pub fn from_bevy_2d_meshes(
184 meshes: Vec<(&Mesh, Vec2)>,
185 map_length: u32,
186 map_depth: u32,
187 sector_resolution: u32,
188 actor_size: f32,
189 internal_cost: u8,
190 external_cost: u8,
191 ) -> Self {
192 let map_dimensions =
193 MapDimensions::new(map_length, map_depth, sector_resolution, actor_size);
194 let cost_fields = SectorCostFields::from_bevy_2d_meshes(
195 &map_dimensions,
196 &meshes,
197 internal_cost,
198 external_cost,
199 );
200 let mut portals = SectorPortals::new(
201 map_dimensions.get_length(),
202 map_dimensions.get_depth(),
203 sector_resolution,
204 );
205 for sector_id in cost_fields.get_scaled().keys() {
207 portals.update_portals(*sector_id, &cost_fields, &map_dimensions);
208 }
209 let graph = PortalGraph::new(&portals, &cost_fields, &map_dimensions);
210 let route_cache = RouteCache::default();
211 let cache = FlowFieldCache::default();
212 FlowFieldTilesBundle {
213 sector_cost_fields: cost_fields,
214 sector_portals: portals,
215 portal_graph: graph,
216 map_dimensions,
217 route_cache,
218 flow_field_cache: cache,
219 }
220 }
221}
222
223#[cfg(test)]
225mod tests {
226 use super::*;
227 #[test]
228 fn valid_map_dimensions() {
229 let _map_dimsions = MapDimensions::new(10, 10, 10, 0.5);
230 }
231 #[test]
232 #[should_panic]
233 fn invalid_map_dimensions() {
234 MapDimensions::new(99, 3, 10, 1.0);
235 }
236 #[test]
237 fn new_bundle() {
238 let b = FlowFieldTilesBundle::new(30, 30, 10, 0.5);
239 let _ = b.get_sector_cost_fields();
240 let _ = b.get_sector_portals();
241 let _ = b.get_portal_graph();
242 let _ = b.get_map_dimensions();
243 let _ = b.get_route_cache();
244 let _ = b.get_flowfield_cache();
245 let mut b = FlowFieldTilesBundle::new(30, 30, 10, 0.5);
246 let _ = b.get_route_cache_mut();
247 let _ = b.get_flowfield_cache_mut();
248 }
249 #[test]
250 fn new_bundle_from_ron() {
251 let path = env!("CARGO_MANIFEST_DIR").to_string()
252 + "/assets/sector_cost_fields_continuous_layout.ron";
253 let _ = FlowFieldTilesBundle::from_ron(30, 30, 10, 0.5, &path);
254 }
255}