mod globe;
mod globe_ext;
pub mod icosahedron;
mod spec;
pub mod chunk;
mod view;
mod gen;
mod chunk_view;
mod chunk_view_system;
mod chunk_system;
mod cursor;
mod chunk_origin;
mod iters;
mod chunk_shared_points;
mod chunk_pair;
#[cfg(test)]
mod tests;
use types::*;
pub use self::globe::Globe;
pub use self::spec::*;
pub use self::view::*;
pub use self::chunk_view::*;
pub use self::chunk_view_system::*;
pub use self::chunk_system::ChunkSystem;
pub use self::cursor::{Cursor, CursorMut};
pub use self::chunk_origin::*;
pub use self::iters::*;
pub use self::chunk_shared_points::ChunkSharedPoints;
use grid::{GridCoord, GridPoint3, Root, PosInOwningRoot};
#[cfg_attr(feature = "cargo-clippy", allow(many_single_char_names))]
pub fn project(root: Root, mut pt_in_root_quad: Pt2) -> Pt3 {
use self::icosahedron::{FACES, VERTICES};
let triangle_indices = [
root.index as usize * 4,
root.index as usize * 4 + 1,
root.index as usize * 4 + 2,
root.index as usize * 4 + 3,
];
let faces = [
FACES[triangle_indices[0]],
FACES[triangle_indices[1]],
FACES[triangle_indices[2]],
FACES[triangle_indices[3]],
];
let a: Pt3 = Pt3::new(
VERTICES[faces[0][0]][0],
VERTICES[faces[0][0]][1],
VERTICES[faces[0][0]][2],
);
let b: Pt3 = Pt3::new(
VERTICES[faces[0][1]][0],
VERTICES[faces[0][1]][1],
VERTICES[faces[0][1]][2],
);
let c: Pt3 = Pt3::new(
VERTICES[faces[1][1]][0],
VERTICES[faces[1][1]][1],
VERTICES[faces[1][1]][2],
);
let d: Pt3 = Pt3::new(
VERTICES[faces[1][0]][0],
VERTICES[faces[1][0]][1],
VERTICES[faces[1][0]][2],
);
let e: Pt3 = Pt3::new(
VERTICES[faces[3][1]][0],
VERTICES[faces[3][1]][1],
VERTICES[faces[3][1]][2],
);
let f: Pt3 = Pt3::new(
VERTICES[faces[3][0]][0],
VERTICES[faces[3][0]][1],
VERTICES[faces[3][0]][2],
);
let ab = b - a;
let ac = c - a;
let db = b - d;
let dc = c - d;
let cd = d - c;
let ce = e - c;
let fd = d - f;
let fe = e - f;
pt_in_root_quad[1] *= 2.0;
let pos_on_icosahedron = if pt_in_root_quad[0] + pt_in_root_quad[1] < 1.0 {
a + ab * pt_in_root_quad[0] + ac * pt_in_root_quad[1]
} else if pt_in_root_quad[1] < 1.0 {
d + dc * (1.0 - pt_in_root_quad[0]) + db * (1.0 - pt_in_root_quad[1])
} else if pt_in_root_quad[0] + pt_in_root_quad[1] < 2.0 {
pt_in_root_quad[1] -= 1.0;
c + cd * pt_in_root_quad[0] + ce * pt_in_root_quad[1]
} else {
pt_in_root_quad[1] -= 1.0;
f + fe * (1.0 - pt_in_root_quad[0]) + fd * (1.0 - pt_in_root_quad[1])
};
Pt3::from_coordinates(pos_on_icosahedron.coords.normalize())
}
pub fn origin_of_chunk_in_same_root_containing(
pos: GridPoint3,
root_resolution: [GridCoord; 2],
chunk_resolution: [GridCoord; 3],
) -> ChunkOrigin {
let end_x = root_resolution[0];
let chunk_origin_x = if pos.x == end_x {
(end_x / chunk_resolution[0] - 1) * chunk_resolution[0]
} else {
pos.x / chunk_resolution[0] * chunk_resolution[0]
};
let end_y = root_resolution[1];
let chunk_origin_y = if pos.y == end_y {
(end_y / chunk_resolution[1] - 1) * chunk_resolution[1]
} else {
pos.y / chunk_resolution[1] * chunk_resolution[1]
};
let chunk_origin_z = pos.z / chunk_resolution[2] * chunk_resolution[2];
ChunkOrigin::new(
GridPoint3::new(pos.root, chunk_origin_x, chunk_origin_y, chunk_origin_z),
root_resolution,
chunk_resolution,
)
}
pub fn origin_of_chunk_owning(
pos_in_owning_root: PosInOwningRoot,
root_resolution: [GridCoord; 2],
chunk_resolution: [GridCoord; 3],
) -> ChunkOrigin {
let pos: GridPoint3 = pos_in_owning_root.into();
let end_x = root_resolution[0];
let end_y = root_resolution[1];
let last_chunk_x = (end_x / chunk_resolution[0] - 1) * chunk_resolution[0];
let last_chunk_y = (end_y / chunk_resolution[1] - 1) * chunk_resolution[1];
let chunk_origin_z = pos.z / chunk_resolution[2] * chunk_resolution[2];
if pos.x == 0 && pos.y == 0 {
ChunkOrigin::new(
GridPoint3::new(pos.root, 0, 0, chunk_origin_z),
root_resolution,
chunk_resolution,
)
} else if pos.x == end_x && pos.y == end_y {
ChunkOrigin::new(
GridPoint3::new(pos.root, last_chunk_x, last_chunk_y, chunk_origin_z),
root_resolution,
chunk_resolution,
)
} else {
let chunk_origin_x = pos.x / chunk_resolution[0] * chunk_resolution[0];
let chunk_origin_y = (pos.y - 1) / chunk_resolution[1] * chunk_resolution[1];
ChunkOrigin::new(
GridPoint3::new(pos.root, chunk_origin_x, chunk_origin_y, chunk_origin_z),
root_resolution,
chunk_resolution,
)
}
}
pub fn is_point_on_chunk_edge(point: GridPoint3, chunk_resolution: [GridCoord; 3]) -> bool {
(point.x % chunk_resolution[0]) == point.x
||
(point.y % chunk_resolution[1]) == point.y
||
(point.z % chunk_resolution[2]) == point.z
||
((point.z + 1) % chunk_resolution[2]) == (point.z + 1)
}