use std::ops::{Index, IndexMut, AddAssign, SubAssign, MulAssign, DivAssign, Add, Sub, Mul, Div};
use std::fmt::{Debug, Formatter, Result};
use crate::usize2::USize2;
pub struct USize3 {
pub x: usize,
pub y: usize,
pub z: usize,
}
impl USize3 {
pub fn new_default() -> USize3 {
return USize3 {
x: 0,
y: 0,
z: 0,
};
}
pub fn new(x_: usize, y_: usize, z_: usize) -> USize3 {
return USize3 {
x: x_,
y: y_,
z: z_,
};
}
pub fn new_vec(v: USize2, z_: usize) -> USize3 {
return USize3 {
x: v.x,
y: v.y,
z: z_,
};
}
pub fn new_lst(lst: [usize; 3]) -> USize3 {
return USize3 {
x: lst[0],
y: lst[1],
z: lst[2],
};
}
}
impl USize3 {
pub fn set_scalar(&mut self, s: usize) {
self.x = s;
self.y = s;
self.z = s;
}
pub fn set_scalar3(&mut self, x: usize, y: usize, z: usize) {
self.x = x;
self.y = y;
self.z = z;
}
pub fn set_vec(&mut self, pt: USize2, z: usize) {
self.x = pt.x;
self.y = pt.y;
self.z = z;
}
pub fn set_lst(&mut self, lst: [usize; 3]) {
self.x = lst[0];
self.y = lst[1];
self.z = lst[2];
}
pub fn set_self(&mut self, v: USize3) {
self.x = v.x;
self.y = v.y;
self.z = v.z;
}
pub fn set_zero(&mut self) {
self.x = 0;
self.y = 0;
self.z = 0;
}
}
impl USize3 {
pub fn add_scalar(&self, v: usize) -> USize3 {
return USize3::new(self.x + v, self.y + v, self.z + v);
}
pub fn add_vec(&self, v: USize3) -> USize3 {
return USize3::new(self.x + v.x, self.y + v.y, self.z + v.z);
}
pub fn sub_scalar(&self, v: usize) -> USize3 {
return USize3::new(self.x - v, self.y - v, self.z - v);
}
pub fn sub_vec(&self, v: USize3) -> USize3 {
return USize3::new(self.x - v.x, self.y - v.y, self.z - v.z);
}
pub fn mul_scalar(&self, v: usize) -> USize3 {
return USize3::new(self.x * v, self.y * v, self.z * v);
}
pub fn mul_vec(&self, v: USize3) -> USize3 {
return USize3::new(self.x * v.x, self.y * v.y, self.z * v.z);
}
pub fn div_scalar(&self, v: usize) -> USize3 {
return USize3::new(self.x / v, self.y / v, self.z / v);
}
pub fn div_vec(&self, v: USize3) -> USize3 {
return USize3::new(self.x / v.x, self.y / v.y, self.z / v.z);
}
}
impl USize3 {
pub fn rsub_scalar(&self, v: usize) -> USize3 {
return USize3::new(v - self.x, v - self.y, v - self.z);
}
pub fn rsub_vec(&self, v: USize3) -> USize3 {
return USize3::new(v.x - self.x, v.y - self.y, v.z - self.z);
}
pub fn rdiv_scalar(&self, v: usize) -> USize3 {
return USize3::new(v / self.x, v / self.y, v / self.z);
}
pub fn rdiv_vec(&self, v: USize3) -> USize3 {
return USize3::new(v.x / self.x, v.y / self.y, v.z / self.z);
}
}
impl USize3 {
pub fn iadd_scalar(&mut self, v: usize) {
self.x = self.x + v;
self.y = self.y + v;
self.z = self.z + v;
}
pub fn iadd_vec(&mut self, v: USize3) {
self.x = self.x + v.x;
self.y = self.y + v.y;
self.z = self.z + v.z;
}
pub fn isub_scalar(&mut self, v: usize) {
self.x = self.x - v;
self.y = self.y - v;
self.z = self.z - v;
}
pub fn isub_vec(&mut self, v: USize3) {
self.x = self.x - v.x;
self.y = self.y - v.y;
self.z = self.z - v.z;
}
pub fn imul_scalar(&mut self, v: usize) {
self.x = self.x * v;
self.y = self.y * v;
self.z = self.z * v;
}
pub fn imul_vec(&mut self, v: USize3) {
self.x = self.x * v.x;
self.y = self.y * v.y;
self.z = self.z * v.z;
}
pub fn idiv_scalar(&mut self, v: usize) {
self.x = self.x / v;
self.y = self.y / v;
self.z = self.z / v;
}
pub fn idiv_vec(&mut self, v: USize3) {
self.x = self.x / v.x;
self.y = self.y / v.y;
self.z = self.z / v.z;
}
}
impl USize3 {
pub fn at(&self, i: usize) -> &usize {
match i {
0 => return &self.x,
1 => return &self.y,
2 => return &self.z,
_ => { panic!() }
}
}
pub fn at_mut(&mut self, i: usize) -> &mut usize {
match i {
0 => return &mut self.x,
1 => return &mut self.y,
2 => return &mut self.z,
_ => { panic!() }
}
}
pub fn sum(&self) -> usize {
return self.x + self.y + self.z;
}
pub fn min(&self) -> usize {
return usize::min(usize::min(self.x, self.y), self.z);
}
pub fn max(&self) -> usize {
return usize::max(usize::max(self.x, self.y), self.z);
}
pub fn dominant_axis(&self) -> usize {
return match self.x > self.y {
true => match self.x > self.z {
true => 0,
false => 2
}
false => match self.y > self.z {
true => 1,
false => 2
}
};
}
pub fn subminant_axis(&self) -> usize {
return match self.x < self.y {
true => match self.x < self.z {
true => 0,
false => 2
}
false => match self.y < self.z {
true => 1,
false => 2
}
};
}
pub fn is_equal(&self, other: &USize3) -> bool {
return self.x == other.x && self.y == other.y && self.z == other.z;
}
}
impl Clone for USize3 {
fn clone(&self) -> Self {
return USize3 {
x: self.x,
y: self.y,
z: self.z,
};
}
}
impl Copy for USize3 {}
impl Index<usize> for USize3 {
type Output = usize;
fn index(&self, index: usize) -> &Self::Output {
return self.at(index);
}
}
impl IndexMut<usize> for USize3 {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
return self.at_mut(index);
}
}
impl AddAssign<usize> for USize3 {
fn add_assign(&mut self, rhs: usize) {
self.iadd_scalar(rhs);
}
}
impl AddAssign for USize3 {
fn add_assign(&mut self, rhs: Self) {
self.iadd_vec(rhs);
}
}
impl SubAssign<usize> for USize3 {
fn sub_assign(&mut self, rhs: usize) {
self.isub_scalar(rhs);
}
}
impl SubAssign for USize3 {
fn sub_assign(&mut self, rhs: Self) {
self.isub_vec(rhs);
}
}
impl MulAssign<usize> for USize3 {
fn mul_assign(&mut self, rhs: usize) {
self.imul_scalar(rhs);
}
}
impl MulAssign for USize3 {
fn mul_assign(&mut self, rhs: Self) {
self.imul_vec(rhs);
}
}
impl DivAssign<usize> for USize3 {
fn div_assign(&mut self, rhs: usize) {
self.idiv_scalar(rhs);
}
}
impl DivAssign for USize3 {
fn div_assign(&mut self, rhs: Self) {
self.idiv_vec(rhs);
}
}
impl PartialEq for USize3 {
fn eq(&self, other: &Self) -> bool {
return self.is_equal(other);
}
}
impl Eq for USize3 {}
impl Add<usize> for USize3 {
type Output = USize3;
fn add(self, rhs: usize) -> Self::Output {
return self.add_scalar(rhs);
}
}
impl Add for USize3 {
type Output = USize3;
fn add(self, rhs: Self) -> Self::Output {
return self.add_vec(rhs);
}
}
impl Sub<usize> for USize3 {
type Output = USize3;
fn sub(self, rhs: usize) -> Self::Output {
return self.sub_scalar(rhs);
}
}
impl Sub for USize3 {
type Output = USize3;
fn sub(self, rhs: Self) -> Self::Output {
return self.sub_vec(rhs);
}
}
impl Mul<usize> for USize3 {
type Output = USize3;
fn mul(self, rhs: usize) -> Self::Output {
return self.mul_scalar(rhs);
}
}
impl Mul for USize3 {
type Output = USize3;
fn mul(self, rhs: Self) -> Self::Output {
return self.mul_vec(rhs);
}
}
impl Div<usize> for USize3 {
type Output = USize3;
fn div(self, rhs: usize) -> Self::Output {
return self.div_scalar(rhs);
}
}
impl Div for USize3 {
type Output = USize3;
fn div(self, rhs: Self) -> Self::Output {
return self.div_vec(rhs);
}
}
impl Debug for USize3 {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_tuple("")
.field(&self.x)
.field(&self.y)
.field(&self.z)
.finish()
}
}
pub fn min(a: &USize3, b: &USize3) -> USize3 {
return USize3::new(usize::min(a.x, b.x),
usize::min(a.y, b.y),
usize::min(a.z, b.z));
}
pub fn max(a: &USize3, b: &USize3) -> USize3 {
return USize3::new(usize::max(a.x, b.x),
usize::max(a.y, b.y),
usize::max(a.z, b.z));
}
pub fn clamp(v: &USize3, low: &USize3, high: &USize3) -> USize3 {
return USize3::new(usize::clamp(v.x, low.x, high.x),
usize::clamp(v.y, low.y, high.y),
usize::clamp(v.z, low.z, high.z));
}