use parse_display::{Display, FromStr};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
pub enum Axis {
Y = 1,
Z = 2,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
#[serde(rename_all = "snake_case")]
#[display(style = "snake_case")]
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
pub enum Direction {
Positive = 1,
Negative = -1,
}
impl std::ops::Mul for Direction {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
match self as i32 * rhs as i32 {
1 => Direction::Positive,
-1 => Direction::Negative,
_ => unreachable!(),
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
#[display("({axis}, {direction})")]
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
pub struct AxisDirectionPair {
pub axis: Axis,
pub direction: Direction,
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
#[display("forward: {forward}, up: {up}")]
#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
pub struct System {
pub forward: AxisDirectionPair,
pub up: AxisDirectionPair,
}
pub const KITTYCAD: &System = &System {
forward: AxisDirectionPair {
axis: Axis::Y,
direction: Direction::Negative,
},
up: AxisDirectionPair {
axis: Axis::Z,
direction: Direction::Positive,
},
};
pub const OPENGL: &System = &System {
forward: AxisDirectionPair {
axis: Axis::Z,
direction: Direction::Positive,
},
up: AxisDirectionPair {
axis: Axis::Y,
direction: Direction::Positive,
},
};
pub const VULKAN: &System = &System {
forward: AxisDirectionPair {
axis: Axis::Z,
direction: Direction::Positive,
},
up: AxisDirectionPair {
axis: Axis::Y,
direction: Direction::Negative,
},
};
#[inline]
pub fn transform(a: [f32; 3], from: &System, to: &System) -> [f32; 3] {
let mut b = a;
b[to.forward.axis as usize] =
(from.forward.direction * to.forward.direction) as i32 as f32 * a[from.forward.axis as usize];
b[to.up.axis as usize] = (from.up.direction * to.up.direction) as i32 as f32 * a[from.up.axis as usize];
b
}