1use parse_display::{Display, FromStr};
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
11#[serde(rename_all = "snake_case")]
12#[display(style = "snake_case")]
13#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
14#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
15#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
16pub enum Axis {
17 Y = 1,
19 Z = 2,
21}
22
23#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
25#[serde(rename_all = "snake_case")]
26#[display(style = "snake_case")]
27#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
28#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
29#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass_enum)]
30pub enum Direction {
31 Positive = 1,
33 Negative = -1,
35}
36
37impl std::ops::Mul for Direction {
38 type Output = Self;
39 fn mul(self, rhs: Self) -> Self::Output {
40 match self as i32 * rhs as i32 {
41 1 => Direction::Positive,
42 -1 => Direction::Negative,
43 _ => unreachable!(),
44 }
45 }
46}
47
48#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
50#[display("({axis}, {direction})")]
51#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
52#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
53#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
54pub struct AxisDirectionPair {
55 pub axis: Axis,
57
58 pub direction: Direction,
60}
61
62#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Serialize, Deserialize, JsonSchema, Display, FromStr)]
70#[display("forward: {forward}, up: {up}")]
71#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS))]
72#[cfg_attr(feature = "ts-rs", ts(export_to = "ModelingCmd.ts"))]
73#[cfg_attr(feature = "python", pyo3::pyclass, pyo3_stub_gen::derive::gen_stub_pyclass)]
74pub struct System {
75 pub forward: AxisDirectionPair,
77 pub up: AxisDirectionPair,
79}
80
81pub const KITTYCAD: &System = &System {
87 forward: AxisDirectionPair {
89 axis: Axis::Y,
90 direction: Direction::Negative,
91 },
92 up: AxisDirectionPair {
94 axis: Axis::Z,
95 direction: Direction::Positive,
96 },
97};
98
99pub const OPENGL: &System = &System {
105 forward: AxisDirectionPair {
107 axis: Axis::Z,
108 direction: Direction::Positive,
109 },
110 up: AxisDirectionPair {
112 axis: Axis::Y,
113 direction: Direction::Positive,
114 },
115};
116
117pub const VULKAN: &System = &System {
123 forward: AxisDirectionPair {
125 axis: Axis::Z,
126 direction: Direction::Positive,
127 },
128 up: AxisDirectionPair {
130 axis: Axis::Y,
131 direction: Direction::Negative,
132 },
133};
134
135#[inline]
175pub fn transform(a: [f32; 3], from: &System, to: &System) -> [f32; 3] {
176 let mut b = a;
177 b[to.forward.axis as usize] =
178 (from.forward.direction * to.forward.direction) as i32 as f32 * a[from.forward.axis as usize];
179 b[to.up.axis as usize] = (from.up.direction * to.up.direction) as i32 as f32 * a[from.up.axis as usize];
180 b
181}