pub mod sector_cost;
pub mod sector_portals;
use crate::prelude::*;
use bevy::prelude::*;
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash, Reflect)]
pub struct SectorID((u32, u32));
impl SectorID {
pub fn new(column: u32, row: u32) -> Self {
SectorID((column, row))
}
pub fn get(&self) -> (u32, u32) {
self.0
}
pub fn get_column(&self) -> u32 {
self.0 .0
}
pub fn get_row(&self) -> u32 {
self.0 .1
}
}
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
#[derive(Component, Default, Clone, Copy, Reflect)]
#[reflect(Component)]
pub struct MapDimensions {
size: (u32, u32),
sector_resolution: u32,
actor_scale: u32,
}
impl MapDimensions {
pub fn new(length: u32, depth: u32, sector_resolution: u32, actor_size: f32) -> Self {
let length_rem = length % sector_resolution;
let depth_rem = depth % sector_resolution;
if length_rem > 0 || depth_rem > 0 {
panic!(
"Map dimensions `({}, {})` cannot support sectors, dimensions must be exact factors of {}",
length, depth, sector_resolution
);
}
if actor_size < 0.0 {
panic!("Actor size cannot be less than zero");
}
if actor_size >= sector_resolution as f32 {
panic!("actor_size cannot be bigger than sector_resolution");
}
let actor_scale = (actor_size / (sector_resolution as f32 / 10.0)).ceil() as u32;
if actor_scale >= 10 {
panic!("Actors cannot be larger than an entire sector, actor_size and/or sector_resolution is incorrect. Size: {}, resolution {}, has produced an actor scale factor of {}. The scale factor must be less than 10 (`scale=actor_size/(sector_resolution * 0.1)`).", actor_size, sector_resolution, actor_scale);
}
MapDimensions {
size: (length, depth),
sector_resolution,
actor_scale,
}
}
pub fn get_size(&self) -> (u32, u32) {
self.size
}
pub fn get_length(&self) -> u32 {
self.size.0
}
pub fn get_depth(&self) -> u32 {
self.size.1
}
pub fn get_sector_resolution(&self) -> u32 {
self.sector_resolution
}
pub fn get_actor_scale(&self) -> u32 {
self.actor_scale
}
pub fn get_total_field_cell_columns(&self) -> usize {
(self.get_length() / self.get_sector_resolution()) as usize * FIELD_RESOLUTION
}
pub fn get_total_field_cell_rows(&self) -> usize {
(self.get_depth() / self.get_sector_resolution()) as usize * FIELD_RESOLUTION
}
pub fn get_field_cell_unit_size(&self) -> f32 {
(self.get_sector_resolution() as usize / FIELD_RESOLUTION) as f32
}
#[cfg(feature = "2d")]
pub fn get_sector_id_from_xy(&self, position: Vec2) -> Option<SectorID> {
if position.x < -((self.get_length() / 2) as f32)
|| position.x > (self.get_length() / 2) as f32
|| position.y < -((self.get_depth() / 2) as f32)
|| position.y > (self.get_depth() / 2) as f32
{
error!("Position is out of bounds of MapDimensions, x {}, y {}, cannot calculate SectorID. Is the actor outside of the map or trying to request route outside of it?", position.x, position.y);
return None;
}
let x_sector_count = self.get_length() / self.get_sector_resolution();
let y_sector_count = self.get_depth() / self.get_sector_resolution();
let x_origin = position.x + (self.get_length() / 2) as f32;
let y_origin = (self.get_depth() / 2) as f32 - position.y;
let mut column = (x_origin / (self.get_sector_resolution() as f32)).floor() as u32;
let mut row = (y_origin / (self.get_sector_resolution() as f32)).floor() as u32;
if column >= x_sector_count {
column = x_sector_count - 1;
}
if row >= y_sector_count {
row = y_sector_count - 1;
}
Some(SectorID::new(column, row))
}
#[cfg(feature = "2d")]
pub fn get_sector_corner_xy(&self, sector_id: SectorID) -> Vec2 {
let x_origin = -(self.get_length() as f32) / 2.0;
let x = x_origin + sector_id.get_column() as f32 * self.get_sector_resolution() as f32;
let y_origin = self.get_depth() as f32 / 2.0;
let y = y_origin - sector_id.get_row() as f32 * self.get_sector_resolution() as f32;
Vec2::new(x, y)
}
#[cfg(feature = "2d")]
pub fn get_sector_and_field_cell_from_xy(
&self,
position: Vec2,
) -> Option<(SectorID, FieldCell)> {
if let Some(sector_id) = self.get_sector_id_from_xy(position) {
let sector_corner_origin = self.get_sector_corner_xy(sector_id);
let pixel_sector_field_ratio =
self.get_sector_resolution() as f32 / FIELD_RESOLUTION as f32;
let field_id_0 =
((position.x - sector_corner_origin.x) / pixel_sector_field_ratio).floor() as usize;
let field_id_1 = ((-position.y + sector_corner_origin.y) / pixel_sector_field_ratio)
.floor() as usize;
let field_id = FieldCell::new(field_id_0, field_id_1);
return Some((sector_id, field_id));
}
None
}
#[cfg(feature = "2d")]
pub fn get_xy_from_field_sector(&self, sector: SectorID, field: FieldCell) -> Option<Vec2> {
let sector_grid_origin_offset = {
Vec2::new(
self.get_length() as f32 / -2.0,
self.get_depth() as f32 / 2.0,
)
};
let sector_origin = Vec2::new(
(sector.get_column() * self.get_sector_resolution()) as f32,
-((sector.get_row() * self.get_sector_resolution()) as f32),
);
let xy_of_sector_top_left = sector_grid_origin_offset + sector_origin;
let cell_size = self.get_sector_resolution() as f32 / FIELD_RESOLUTION as f32;
let cell_position = Vec2::new(
field.get_column() as f32 * cell_size + cell_size / 2.0,
-(field.get_row() as f32 * cell_size + cell_size / 2.0),
);
let real_space_pos = xy_of_sector_top_left + cell_position;
if real_space_pos.x.abs() > self.get_length() as f32 / 2.0
|| real_space_pos.y.abs() > self.get_depth() as f32 / 2.0
{
None
} else {
Some(real_space_pos)
}
}
#[cfg(feature = "3d")]
pub fn get_xyz_from_field_sector(&self, sector: SectorID, field: FieldCell) -> Option<Vec3> {
let sector_grid_origin_offset = {
Vec3::new(
self.get_length() as f32 / -2.0,
0.0,
self.get_depth() as f32 / -2.0,
)
};
let sector_origin = Vec3::new(
(sector.get_column() * self.get_sector_resolution()) as f32,
0.0,
(sector.get_row() * self.get_sector_resolution()) as f32,
);
let xyz_of_sector_top_left = sector_grid_origin_offset + sector_origin;
let cell_size = self.get_sector_resolution() as f32 / FIELD_RESOLUTION as f32;
let cell_position = Vec3::new(
field.get_column() as f32 * cell_size + cell_size / 2.0,
0.0,
field.get_row() as f32 * cell_size + cell_size / 2.0,
);
let real_space_pos = xyz_of_sector_top_left + cell_position;
if real_space_pos.x.abs() > self.get_length() as f32 / 2.0
|| real_space_pos.z.abs() > self.get_depth() as f32 / 2.0
{
None
} else {
Some(real_space_pos)
}
}
#[cfg(feature = "3d")]
pub fn get_sector_id_from_xyz(&self, position: Vec3) -> Option<SectorID> {
if position.x < -((self.get_length() / 2) as f32)
|| position.x > (self.get_length() / 2) as f32
|| position.z < -((self.get_depth() / 2) as f32)
|| position.z > (self.get_depth() / 2) as f32
{
error!("Position is out of bounds of MapDimensions, x {}, y {}, cannot calculate SectorID. Is the actor outside of the map or trying to request route outside of it?", position.x, position.y);
return None;
}
let x_sector_count = self.get_length() / self.get_sector_resolution();
let z_sector_count = self.get_depth() / self.get_sector_resolution();
let x_origin = position.x + (self.get_length() / 2) as f32;
let z_origin = (self.get_depth() / 2) as f32 + position.z;
let mut column = (x_origin / (self.get_sector_resolution() as f32)).floor() as u32;
let mut row = (z_origin / (self.get_sector_resolution() as f32)).floor() as u32;
if column >= x_sector_count {
column = x_sector_count - 1;
}
if row >= z_sector_count {
row = z_sector_count - 1;
}
Some(SectorID::new(column, row))
}
#[cfg(feature = "3d")]
pub fn get_sector_corner_xyz(&self, sector_id: SectorID) -> Vec3 {
let x_origin = -(self.get_length() as f32) / 2.0;
let x = x_origin + sector_id.get_column() as f32 * self.get_sector_resolution() as f32;
let z_origin = -(self.get_depth() as f32) / 2.0;
let z = z_origin + sector_id.get_row() as f32 * self.get_sector_resolution() as f32;
Vec3::new(x, 0.0, z)
}
#[cfg(feature = "3d")]
pub fn get_sector_and_field_cell_from_xyz(
&self,
position: Vec3,
) -> Option<(SectorID, FieldCell)> {
if let Some(sector_id) = self.get_sector_id_from_xyz(position) {
let sector_corner_origin = self.get_sector_corner_xyz(sector_id);
let resolution_by_field_dimension =
self.get_sector_resolution() as f32 / FIELD_RESOLUTION as f32;
let field_id_0 = ((position.x - sector_corner_origin.x) / resolution_by_field_dimension)
.floor() as usize;
let field_id_1 = ((position.z - sector_corner_origin.z) / resolution_by_field_dimension)
.floor() as usize;
let field_id = FieldCell::new(field_id_0, field_id_1);
return Some((sector_id, field_id));
}
None
}
pub fn get_ids_of_neighbouring_sectors(self, sector_id: &SectorID) -> Vec<SectorID> {
Ordinal::get_sector_neighbours(
sector_id,
self.get_length(),
self.get_depth(),
self.get_sector_resolution(),
)
}
pub fn get_ordinal_and_ids_of_neighbouring_sectors(
&self,
sector_id: &SectorID,
) -> Vec<(Ordinal, SectorID)> {
Ordinal::get_sector_neighbours_with_ordinal(
sector_id,
self.get_length(),
self.get_depth(),
self.get_sector_resolution(),
)
}
pub fn get_sector_id_from_ordinal(
&self,
ordinal: Ordinal,
sector_id: &SectorID,
) -> Option<SectorID> {
match ordinal {
Ordinal::North => sector_id
.get_row()
.checked_sub(1)
.map(|row| SectorID::new(sector_id.get_column(), row)),
Ordinal::East => {
if sector_id.get_column() + 1 < self.get_length() / self.get_sector_resolution() - 1
{
Some(SectorID::new(
sector_id.get_column() + 1,
sector_id.get_row(),
))
} else {
None
}
}
Ordinal::South => {
if sector_id.get_row() + 1 < self.get_depth() / self.get_sector_resolution() - 1 {
Some(SectorID::new(
sector_id.get_column(),
sector_id.get_row() + 1,
))
} else {
None
}
}
Ordinal::West => sector_id
.get_column()
.checked_sub(1)
.map(|column| SectorID::new(column, sector_id.get_row())),
Ordinal::NorthEast => {
if let Some(row) = sector_id.get_row().checked_sub(1) {
if sector_id.get_column() + 1
< self.get_length() / self.get_sector_resolution() - 1
{
Some(SectorID::new(sector_id.get_column() + 1, row))
} else {
None
}
} else {
None
}
}
Ordinal::SouthEast => {
if sector_id.get_row() + 1 < self.get_depth() / self.get_sector_resolution() - 1 {
if sector_id.get_column() + 1
< self.get_length() / self.get_sector_resolution() - 1
{
Some(SectorID::new(
sector_id.get_column() + 1,
sector_id.get_row() + 1,
))
} else {
None
}
} else {
None
}
}
Ordinal::SouthWest => {
if sector_id.get_row() + 1 < self.get_depth() / self.get_sector_resolution() - 1 {
sector_id
.get_column()
.checked_sub(1)
.map(|column| SectorID::new(column, sector_id.get_row() + 1))
} else {
None
}
}
Ordinal::NorthWest => {
if let Some(row) = sector_id.get_row().checked_sub(1) {
sector_id
.get_column()
.checked_sub(1)
.map(|column| SectorID::new(column, row))
} else {
None
}
}
Ordinal::Zero => {
error!("`get_sector_id_from_ordinal` should never be called with `Ordinal::Zero`");
None
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sector_costfields_top_left_sector_id_from_xyz() {
let map_dimensions = MapDimensions::new(20, 20, 10, 1.0);
let position = Vec3::new(-5.0, 0.0, -5.0);
let result = map_dimensions.get_sector_id_from_xyz(position).unwrap();
let actual: SectorID = SectorID::new(0, 0);
assert_eq!(actual, result);
}
#[test]
fn sector_costfields_top_right_sector_id_from_xyz() {
let map_dimensions = MapDimensions::new(20, 20, 10, 1.0);
let position = Vec3::new(5.0, 0.0, -5.0);
let result = map_dimensions.get_sector_id_from_xyz(position).unwrap();
let actual: SectorID = SectorID::new(1, 0);
assert_eq!(actual, result);
}
#[test]
fn sector_costfields_bottom_right_sector_id_from_xyz() {
let map_dimensions = MapDimensions::new(20, 20, 10, 1.0);
let position = Vec3::new(5.0, 0.0, 5.0);
let result = map_dimensions.get_sector_id_from_xyz(position).unwrap();
let actual: SectorID = SectorID::new(1, 1);
assert_eq!(actual, result);
}
#[test]
fn sector_costfields_bottom_left_sector_id_from_xyz() {
let map_dimensions = MapDimensions::new(20, 20, 10, 1.0);
let position = Vec3::new(-5.0, 0.0, 5.0);
let result = map_dimensions.get_sector_id_from_xyz(position).unwrap();
let actual: SectorID = SectorID::new(0, 1);
assert_eq!(actual, result);
}
#[test]
fn sector_fieldcell_id_from_xyz() {
let map_dimensions = MapDimensions::new(300, 300, 100, 1.0);
let position = Vec3::new(0.0, 0.0, 0.0);
let result = map_dimensions
.get_sector_and_field_cell_from_xyz(position)
.unwrap();
let actual = FieldCell::new(5, 5);
assert_eq!(actual, result.1);
}
#[test]
fn sector_fieldcell_id_from_xyz_small() {
let map_dimensions = MapDimensions::new(25, 50, 5, 1.0);
let position = Vec3::new(0.0, 0.0, 0.0);
let result = map_dimensions
.get_sector_and_field_cell_from_xyz(position)
.unwrap();
let actual_sector = SectorID::new(2, 5);
let actual_field = FieldCell::new(5, 0);
assert_eq!(actual_sector, result.0);
assert_eq!(actual_field, result.1);
}
#[test]
fn sector_fieldcell_id_from_xyz_large() {
let map_dimensions = MapDimensions::new(290, 290, 290, 1.0);
let position = Vec3::new(0.0, 0.0, 0.0);
let result = map_dimensions
.get_sector_and_field_cell_from_xyz(position)
.unwrap();
let actual_sector = SectorID::new(0, 0);
let actual_field = FieldCell::new(5, 5);
assert_eq!(actual_sector, result.0);
assert_eq!(actual_field, result.1);
}
#[test]
fn sector_from_xy_none() {
let map_dimensions = MapDimensions::new(1280, 1280, 640, 16.0);
let position = Vec2::new(-1500.0, 0.0);
let result = map_dimensions.get_sector_id_from_xy(position);
assert!(result.is_none());
}
#[test]
fn sector_from_xy() {
let map_dimensions = MapDimensions::new(1280, 1280, 640, 16.0);
let position = Vec2::new(530.0, 75.0);
let result = map_dimensions.get_sector_id_from_xy(position);
let actual = SectorID::new(1, 0);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_xyz_corner_zero() {
let sector_id = SectorID::new(0, 0);
let map_dimensions = MapDimensions::new(30, 30, 10, 1.0);
let result = map_dimensions.get_sector_corner_xyz(sector_id);
let actual = Vec3::new(-15.0, 0.0, -15.0);
assert_eq!(actual, result)
}
#[test]
fn sector_xyz_corner_centre() {
let sector_id = SectorID::new(1, 1);
let map_dimensions = MapDimensions::new(30, 30, 10, 1.0);
let result = map_dimensions.get_sector_corner_xyz(sector_id);
let actual = Vec3::new(-5.0, 0.0, -5.0);
assert_eq!(actual, result)
}
#[test]
fn get_northern_sector_neighbours() {
let sector_id = SectorID::new(4, 0);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
SectorID::new(5, 0),
SectorID::new(4, 1),
SectorID::new(3, 0),
];
assert_eq!(actual, result);
}
#[test]
fn get_eastern_sector_neighbours() {
let sector_id = SectorID::new(19, 3);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
SectorID::new(19, 2),
SectorID::new(19, 4),
SectorID::new(18, 3),
];
assert_eq!(actual, result);
}
#[test]
fn get_southern_sector_neighbours() {
let sector_id = SectorID::new(5, 19);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
SectorID::new(5, 18),
SectorID::new(6, 19),
SectorID::new(4, 19),
];
assert_eq!(actual, result);
}
#[test]
fn get_western_sector_neighbours() {
let sector_id = SectorID::new(0, 5);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
SectorID::new(0, 4),
SectorID::new(1, 5),
SectorID::new(0, 6),
];
assert_eq!(actual, result);
}
#[test]
fn get_centre_sector_neighbours() {
let sector_id = SectorID::new(5, 7);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
SectorID::new(5, 6),
SectorID::new(6, 7),
SectorID::new(5, 8),
SectorID::new(4, 7),
];
assert_eq!(actual, result);
}
#[test]
fn get_northern_sector_neighbours_with_drection() {
let sector_id = SectorID::new(4, 0);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ordinal_and_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
(Ordinal::East, SectorID::new(5, 0)),
(Ordinal::South, SectorID::new(4, 1)),
(Ordinal::West, SectorID::new(3, 0)),
];
assert_eq!(actual, result);
}
#[test]
fn get_eastern_sector_neighbours_with_drection() {
let sector_id = SectorID::new(19, 3);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ordinal_and_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
(Ordinal::North, SectorID::new(19, 2)),
(Ordinal::South, SectorID::new(19, 4)),
(Ordinal::West, SectorID::new(18, 3)),
];
assert_eq!(actual, result);
}
#[test]
fn get_southern_sector_neighbours_with_drection() {
let sector_id = SectorID::new(5, 19);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ordinal_and_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
(Ordinal::North, SectorID::new(5, 18)),
(Ordinal::East, SectorID::new(6, 19)),
(Ordinal::West, SectorID::new(4, 19)),
];
assert_eq!(actual, result);
}
#[test]
fn get_western_sector_neighbours_with_drection() {
let sector_id = SectorID::new(0, 5);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ordinal_and_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
(Ordinal::North, SectorID::new(0, 4)),
(Ordinal::East, SectorID::new(1, 5)),
(Ordinal::South, SectorID::new(0, 6)),
];
assert_eq!(actual, result);
}
#[test]
fn get_centre_sector_neighbours_with_drection() {
let sector_id = SectorID::new(5, 7);
let map_dimensions = MapDimensions::new(200, 200, 10, 1.0);
let result = map_dimensions.get_ordinal_and_ids_of_neighbouring_sectors(§or_id);
let actual = vec![
(Ordinal::North, SectorID::new(5, 6)),
(Ordinal::East, SectorID::new(6, 7)),
(Ordinal::South, SectorID::new(5, 8)),
(Ordinal::West, SectorID::new(4, 7)),
];
assert_eq!(actual, result);
}
#[test]
fn sector_id_ordinal_north() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::North, §or_id);
let actual = SectorID::new(1, 0);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_east() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::East, §or_id);
let actual = SectorID::new(2, 1);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_south() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::South, §or_id);
let actual = SectorID::new(1, 2);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_west() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::West, §or_id);
let actual = SectorID::new(0, 1);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_northeast() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::NorthEast, §or_id);
let actual = SectorID::new(2, 0);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_southeast() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::SouthEast, §or_id);
let actual = SectorID::new(2, 2);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_southwest() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::SouthWest, §or_id);
let actual = SectorID::new(0, 2);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_northwest() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 1);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::NorthWest, §or_id);
let actual = SectorID::new(0, 0);
assert_eq!(actual, result.unwrap());
}
#[test]
fn sector_id_ordinal_oob() {
let map_dimensions = MapDimensions::new(300, 300, 10, 0.5);
let sector_id = SectorID::new(1, 0);
let result = map_dimensions.get_sector_id_from_ordinal(Ordinal::North, §or_id);
assert!(result.is_none())
}
#[test]
fn get_xy() {
let map_dimensions = MapDimensions::new(1920, 1920, 640, 16.0);
let sector_id = SectorID::new(2, 1);
let field_id = FieldCell::new(6, 2);
let actual = Vec2::new(736.0, 160.0);
let result = map_dimensions
.get_xy_from_field_sector(sector_id, field_id)
.unwrap();
assert_eq!(actual, result);
}
#[test]
fn get_xyz() {
let map_dimensions = MapDimensions::new(30, 30, 10, 0.5);
let sector_id = SectorID::new(2, 1);
let field_id = FieldCell::new(6, 2);
let actual = Vec3::new(11.5, 0.0, -2.5);
let result = map_dimensions
.get_xyz_from_field_sector(sector_id, field_id)
.unwrap();
assert_eq!(actual, result);
}
}