skia_safe/core/
point3.rs

1use crate::{prelude::*, private::is_finite, scalar};
2use skia_bindings::SkPoint3;
3use std::ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign};
4
5pub type Vector3 = Point3;
6pub type Color3f = Point3;
7
8#[repr(C)]
9#[derive(Copy, Clone, PartialEq, Default, Debug)]
10pub struct Point3 {
11    pub x: scalar,
12    pub y: scalar,
13    pub z: scalar,
14}
15
16native_transmutable!(SkPoint3, Point3, point3_layout);
17
18impl From<(scalar, scalar, scalar)> for Point3 {
19    fn from((x, y, z): (scalar, scalar, scalar)) -> Self {
20        Self::new(x, y, z)
21    }
22}
23
24impl Neg for Point3 {
25    type Output = Self;
26    fn neg(self) -> Self::Output {
27        Self::new(-self.x, -self.y, -self.z)
28    }
29}
30
31impl Add for Point3 {
32    type Output = Self;
33    fn add(self, rhs: Self) -> Self::Output {
34        Self::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
35    }
36}
37
38impl AddAssign for Point3 {
39    fn add_assign(&mut self, rhs: Point3) {
40        *self = *self + rhs;
41    }
42}
43
44impl Sub for Point3 {
45    type Output = Self;
46    fn sub(self, rhs: Self) -> Self::Output {
47        Self::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
48    }
49}
50
51impl SubAssign for Point3 {
52    fn sub_assign(&mut self, rhs: Point3) {
53        *self = *self - rhs;
54    }
55}
56
57impl Mul<Point3> for scalar {
58    type Output = Point3;
59
60    fn mul(self, p: Point3) -> Self::Output {
61        Point3::new(self * p.x, self * p.y, self * p.z)
62    }
63}
64
65impl Point3 {
66    pub const fn new(x: scalar, y: scalar, z: scalar) -> Self {
67        Self { x, y, z }
68    }
69
70    pub fn set(&mut self, x: scalar, y: scalar, z: scalar) {
71        *self = Self::new(x, y, z);
72    }
73
74    pub fn length_xyz(x: scalar, y: scalar, z: scalar) -> scalar {
75        unsafe { SkPoint3::Length(x, y, z) }
76    }
77
78    pub fn length(&self) -> scalar {
79        unsafe { SkPoint3::Length(self.x, self.y, self.z) }
80    }
81
82    pub fn normalize(&mut self) -> bool {
83        unsafe { self.native_mut().normalize() }
84    }
85
86    #[must_use]
87    pub fn normalized(&self) -> Option<Self> {
88        let mut normalized = *self;
89        unsafe { normalized.native_mut().normalize() }.if_true_some(normalized)
90    }
91
92    // TODO: with_scale()?
93    #[must_use]
94    pub fn scaled(&self, scale: scalar) -> Self {
95        Self::new(scale * self.x, scale * self.y, scale * self.z)
96    }
97
98    pub fn scale(&mut self, value: scalar) {
99        *self = self.scaled(value);
100    }
101
102    pub fn is_finite(&self) -> bool {
103        is_finite(&[self.x, self.y, self.z])
104    }
105
106    pub fn dot_product(a: Self, b: Self) -> scalar {
107        a.x * b.x + a.y * b.y + a.z * b.z
108    }
109
110    pub fn dot(&self, vec: Self) -> scalar {
111        Self::dot_product(*self, vec)
112    }
113
114    #[allow(clippy::many_single_char_names)]
115    pub fn cross_product(a: Self, b: Self) -> Self {
116        let x = a.y * b.z - a.z * b.y;
117        let y = a.z * b.x - a.x * b.z;
118        let z = a.x * b.y - a.y * b.x;
119        Self { x, y, z }
120    }
121
122    #[must_use]
123    pub fn cross(&self, vec: Self) -> Self {
124        Self::cross_product(*self, vec)
125    }
126}