use crate::traits::coordinate::Coordinate;
use super::super::structs::transition_sides::*;
use crate::implementation::voxel_coordinates::*;
use crate::prelude::Block;
use crate::structs::position::OutputPosition;
use super::aux_tables;
#[derive(Debug)]
pub struct Xyz {
pub x: isize,
pub y: isize,
pub z: isize,
}
#[derive(Debug)]
pub struct Rotation {
pub side: TransitionSide,
pub uvw_base: Xyz,
pub u: Xyz,
pub v: Xyz,
pub w: Xyz,
pub plus_x_as_uvw: HighResolutionVoxelDelta,
pub plus_y_as_uvw: HighResolutionVoxelDelta,
pub plus_z_as_uvw: HighResolutionVoxelDelta,
}
impl Xyz {
const fn from(xyz: (isize, isize, isize)) -> Self {
Xyz {
x: xyz.0,
y: xyz.1,
z: xyz.2,
}
}
}
impl Rotation {
pub fn for_side(side: TransitionSide) -> &'static Self {
&aux_tables::ROTATIONS[side as usize]
}
pub fn to_position<F>(
&self,
block: Block<F>,
voxel_index: &HighResolutionVoxelIndex,
) -> OutputPosition<F>
where
F: Coordinate,
{
let block_size = block.subdivisions;
let cell_index = voxel_index.cell;
let delta = voxel_index.delta;
let x = self.uvw_base.x * 2 * block_size as isize
+ self.u.x * (2 * cell_index.cell_u as isize + delta.u)
+ self.v.x * (2 * cell_index.cell_v as isize + delta.v)
+ self.w.x * delta.w;
let x = F::half(x) * F::from_ratio(1, block_size);
let y = self.uvw_base.y * 2 * block_size as isize
+ self.u.y * (2 * cell_index.cell_u as isize + delta.u)
+ self.v.y * (2 * cell_index.cell_v as isize + delta.v)
+ self.w.y * delta.w;
let y = F::half(y) * F::from_ratio(1, block_size);
let z = self.uvw_base.z * 2 * block_size as isize
+ self.u.z * (2 * cell_index.cell_u as isize + delta.u)
+ self.v.z * (2 * cell_index.cell_v as isize + delta.v)
+ self.w.z * delta.w;
let z = F::half(z) * F::from_ratio(1, block_size);
OutputPosition {
x: block.base[0] + block.size * x,
y: block.base[1] + block.size * y,
z: block.base[2] + block.size * z,
}
}
pub fn to_regular_voxel_index(
&self,
block_size: usize,
cell_index: &TransitionCellIndex,
face_u: usize,
face_v: usize,
) -> RegularVoxelIndex {
let x = self.uvw_base.x * block_size as isize
+ self.u.x * (cell_index.cell_u + face_u) as isize
+ self.v.x * (cell_index.cell_v + face_v) as isize;
let y = self.uvw_base.y * block_size as isize
+ self.u.y * (cell_index.cell_u + face_u) as isize
+ self.v.y * (cell_index.cell_v + face_v) as isize;
let z = self.uvw_base.z * block_size as isize
+ self.u.z * (cell_index.cell_u + face_u) as isize
+ self.v.z * (cell_index.cell_v + face_v) as isize;
RegularVoxelIndex { x, y, z }
}
#[allow(clippy::too_many_arguments)]
pub const fn from(
side: TransitionSide,
uvw_base: (isize, isize, isize),
u: (isize, isize, isize),
v: (isize, isize, isize),
w: (isize, isize, isize),
_xyz_base: (isize, isize, isize),
x: (isize, isize, isize),
y: (isize, isize, isize),
z: (isize, isize, isize),
) -> Self {
Rotation {
side,
uvw_base: Xyz::from(uvw_base),
u: Xyz::from(u),
v: Xyz::from(v),
w: Xyz::from(w),
plus_x_as_uvw: HighResolutionVoxelDelta::from(x.0, x.1, x.2),
plus_y_as_uvw: HighResolutionVoxelDelta::from(y.0, y.1, y.2),
plus_z_as_uvw: HighResolutionVoxelDelta::from(z.0, z.1, z.2),
}
}
pub fn default() -> &'static Self {
&aux_tables::ROTATIONS[0]
}
}