1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
//! Hexagonal tools lib in rust.
//!
//! > Inspired by this [`RedBlobGames` article](https://www.redblobgames.com/grids/hexagons/implementation.html)
//! > and [Sander Evers](https://sanderevers.github.io/) work
//!
//! This lib allows you to:
//!
//! * Manipulate hexagon coordinates
//! * Generate hexagonal maps with custom layouts and orientation
//! * Generate hexagon meshes (planes or columns)
//!
//! I made the choice to use *Axial Coordinates* for performance and utility
//! reasons, but the [`Hex`](crate::hex::Hex) type has conversion utilities with
//! *cubic*, *doubled*, *hexmod* and *offset* coordinates.
//!
//! > See the [hexagonal coordinate systems](https://www.redblobgames.com/grids/hexagons/#coordinates)
//!
//! ## Installation
//!
//! Run `cargo add hexx` in your project or add the following line to your
//! `Cargo.toml`:
//!
//! * `hexx = "0.24"`
//!
//! ### Cargo features
//!
//! `hexx` provides the following cargo features:
//! * `serde`: Enables [serde](https://github.com/serde-rs/serde) support for
//! most types
//! * `facet`: Enables [facet](https://github.com/facet-rs/facet) support for
//! most types
//! * `rayon`: Enables [rayon](https://github.com/rayon-rs/rayon) support for
//! parallel processing
//! * `packed`: Makes [`Hex`](crate::hex::Hex) `repr(C)`, useful to use it
//! accross the FFI
//! * `grid`: Enables support for Face/Vertex/Edge [grid handling](https://www.redblobgames.com/grids/parts/#hexagon-coordinates)
//! using `Hex` as Face, `GridVertex` as vertex and `GridEdge` as edge.
//! * `algorithms`: Enables the [algorithms](crate::algorithms) module with:
//! * Field of Movement
//! * A Star Pathfinding
//! * Field of view
//! * `mesh`: Enables procedural mesh generation
//! * `bevy`: Enables [Bevy](https://bevyengine.org/) support including:
//! * `bevy_platform`: Enables [Bevy Platform](https://docs.rs/bevy_platform/latest/bevy_platform)
//! for `HashMap`
//! * `bevy_reflect`: Enables [Bevy Reflection](https://docs.rs/bevy_reflect/latest/bevy_reflect)
//! for most types
//! * `bevy_ecs`: Enables `Component` and `Resource` derives for common hexx
//! types
//!
//! _Some features are enabled by default, it is recommended to enable only
//! what is needed for your usage_
//!
//! ## Features
//!
//! `hexx` provides the [`Hex`](crate::hex::Hex) coordinates with:
//!
//! * Distances
//! * Neighbors and directions
//! * Lines
//! * Ranges
//! * Rings
//! * Edges
//! * Wedges
//! * Spirals
//! * Rotation
//! * Symmetry
//! * Vector operations
//! * Conversions to other coordinate systems:
//! * Cubic coordinates
//! * Offset coordinates
//! * Doubled coordinates
//! * Hexmod coordinates
//! * Multiple hex resolution
//! * Euclidean norm
//!
//! ## Basic usage
//!
//!```rust
//! use hexx::*;
//!
//! // Declare points in hexagonal spaces
//! let point_a = hex(10, -5); // Equivalent of `Hex::new(10, -5)`
//! let point_b = hex(-8, 15);
//! // Find distance between them
//! let dist = point_a.unsigned_distance_to(point_b);
//! // Compute a line between points
//! let line: Vec<Hex> = point_a.line_to(point_b).collect();
//! // Compute a ring from `point_a` containing `point_b`
//! let ring: Vec<Hex> = point_a.ring(dist).collect();
//! // Rotate `point_b` around `point_a` by 2 times 60 degrees clockwise
//! let rotated = point_b.rotate_cw_around(point_a, 2);
//! // Find the direction between the two points
//! let dir_a = point_a.main_direction_to(point_b);
//! let dir_b = point_b.main_direction_to(point_a);
//! assert!(dir_a == -dir_b);
//! // Compute a wedge from `point_a` to `point_b`
//! let wedge = point_a.wedge_to(point_b);
//! // Get the average value of the wedge
//! let avg = wedge.average();
//! ```
//!
//! ## Layout usage
//!
//! [`HexLayout`](crate::layout::HexLayout) is the bridge between your
//! world/screen/pixel coordinate system and the hexagonal coordinates system.
//!
//!```rust
//! use hexx::*;
//!
//! // Define your layout
//! let layout = HexLayout {
//! scale: Vec2::new(1.0, 1.0),
//! orientation: HexOrientation::Flat,
//! ..Default::default()
//! };
//! // Get the hex coordinate at the world position `world_pos`.
//! let world_pos = Vec2::new(53.52, 189.28);
//! let point = layout.world_pos_to_hex(world_pos);
//! // Get the world position of `point`
//! let point = hex(123, 45);
//! let world_pos = layout.hex_to_world_pos(point);
//! ```
//!
//! ## Wrapping
//!
//! [`HexBounds`](crate::bounds::HexBounds) defines a bounding hexagon around a
//! center coordinate. It can be used for boundary and interesection checks but
//! also for wrapping coordinates.
//! Coordinate wrapping transform a point outside of the bounds to a point
//! inside. This allows for seamless or repeating [wraparound](https://www.redblobgames.com/grids/hexagons/#wraparound)
//! maps.
//!
//! ```rust
//! use hexx::*;
//!
//! let center = hex(23, -45);
//! let radius = 5;
//! let bounds = HexBounds::new(center, radius);
//! let outside_coord = hex(12345, 98765);
//! assert!(!bounds.is_in_bounds(outside_coord));
//! let wrapped_coord = bounds.wrap(outside_coord);
//! assert!(bounds.is_in_bounds(wrapped_coord));
//! ```
//!
//! ## Resolutions and chunks
//!
//! [`Hex`](crate::hex::Hex) support multi-resolution coordinates.
//! In practice this means that you may convert a coordinate to a different
//! resolution:
//!
//! * To a lower resolution, meaning retrieving a *parent* coordinate
//! * to a higher resolution, meaning retrieving the center *child* coordinate
//!
//! Resolutions are abstract, the only useful information is the resolution
//! **radius**.
//!
//! For example, if you use a big grid, with a radius of a 100, you might want
//! to split that grid evenly in larger hexagons containing a 10 radius of
//! coordinates and maybe do operations locally inside of these chunks.
//!
//! So instead of using a big range directly:
//!
//! ```rust
//! use hexx::*;
//!
//! const MAP_RADIUS: u32 = 100;
//!
//! // Our big grid with hundreds of hexagons
//! let big_grid = Hex::ZERO.range(MAP_RADIUS);
//! ```
//!
//! You may define a smaller grid you will then divide to a higher resolution
//!
//! ```rust
//! use hexx::*;
//!
//! const CHUNK_RADIUS: u32 = 10;
//! const MAP_RADIUS: u32 = 20;
//!
//! let chunks = Hex::ZERO.range(MAP_RADIUS);
//! for chunk in chunks {
//! // We can retrieve the center of that chunk by increasing the resolution
//! let center = chunk.to_higher_res(CHUNK_RADIUS);
//! // And retrieve the other coordinates in the chunk
//! let children = center.range(CHUNK_RADIUS);
//! // We can retrieve the chunk coordinates from any coordinate..
//! for coord in children {
//! // .. by reducing the resolution
//! assert_eq!(coord.to_lower_res(CHUNK_RADIUS), chunk);
//! }
//! }
//! ```
//!
//! An other usage could be to draw an infinite hex grid, with different
//! resolutions displayed, dynamically changing according to user zoom level.
//!
//! ## Dense map storage
//!
//! [`Hex`](crate::hex::Hex) implements `Hash`, and most users store hexagonal
//! maps in a `HashMap`. But for some cases `hexx` provides *dense storage*
//! [collections](crate::storage) with more performant accessors:
//!
//! - [`HexagonalMap<T>`](crate::storage::hexagonal::HexagonalMap)
//! - [`HexModMap<T>`](crate::storage::hexmod::HexModMap)
//! - [`RombusMap<T>`](crate::storage::rombus::RombusMap)
//!
//! ## Procedural meshes
//!
//! > Requires the `mesh` feature
//!
//! `hexx` provides 3 built-in procedural mesh construction utilies:
//! - [`PlaneMeshBuilder`](crate::mesh::plane_builder::PlaneMeshBuilder) for
//! hexagonal planes
//! - [`ColumnMeshBuilder`](crate::mesh::column_builder::ColumnMeshBuilder) for
//! hexagonal columns
//! - [`HeightMapMeshBuilder`](crate::mesh::heightmap_builder::HeightMapMeshBuilder)
//! for hexagonal height maps
//!
//! All those builders have a lot of customization options and will output a
//! [`MeshInfo`](crate::mesh::MeshInfo) struct containing vertex positions,
//! normals and uvs
//!
//! ### Usage in [Bevy](https://bevyengine.org/)
//!
//! If you want to integrate the procedural meshes in [bevy](bevyengine.org) you
//! may do it this way:
//!
//!```rust
//! use bevy::{
//! asset::RenderAssetUsages, mesh::Indices, prelude::Mesh,
//! render::render_resource::PrimitiveTopology,
//! };
//! use hexx::MeshInfo;
//!
//! pub fn hexagonal_mesh(mesh_info: MeshInfo) -> Mesh {
//! Mesh::new(
//! PrimitiveTopology::TriangleList,
//! // Means you won't interact with the mesh on the CPU afterwards
//! // Check bevy docs for more information
//! RenderAssetUsages::RENDER_WORLD,
//! )
//! .with_inserted_attribute(Mesh::ATTRIBUTE_POSITION, mesh_info.vertices)
//! .with_inserted_attribute(Mesh::ATTRIBUTE_NORMAL, mesh_info.normals)
//! .with_inserted_attribute(Mesh::ATTRIBUTE_UV_0, mesh_info.uvs)
//! .with_inserted_indices(Indices::U16(mesh_info.indices))
//! }
//! ```
// For lib.rs docs only
/// Non exhaustive collection of classic algorithms.
/// Hexagonal range bounds module
/// Hexagonal coordinates conversion module
/// Hexagonal directions module
/// Hexagonal coordinates module
/// Hexagonal layout module
/// Mesh generation utils module
/// Hexagon oritentation module
/// Map shapes generation functions
pub use HexBounds;
pub use *;
pub use *;
pub use ;
pub use ;
pub use ;
pub use HexLayout;
pub use *;
pub use HexOrientation;