1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use core::str::FromStr;
use std::hash::Hash;
use crate::*;
pub trait IsBuildable3D: Sized + Is3D + Eq + PartialEq + Ord + PartialOrd + Hash {
fn new(x: f64, y: f64, z: f64) -> Self;
fn from<P>(&mut self, other: &P)
where
P: Is3D;
#[inline(always)]
fn new_from<P>(other: &P) -> Self
where
P: Is3D,
{
Self::new(other.x(), other.y(), other.z())
}
fn multiply_m(&self, m: &Matrix4) -> Self {
let x = self.x() * m.data[0][0]
+ self.y() * m.data[0][1]
+ self.z() * m.data[0][2]
+ m.data[0][3];
let y = self.x() * m.data[1][0]
+ self.y() * m.data[1][1]
+ self.z() * m.data[1][2]
+ m.data[1][3];
let z = self.x() * m.data[2][0]
+ self.y() * m.data[2][1]
+ self.z() * m.data[2][2]
+ m.data[2][3];
Self::new(x, y, z)
}
fn normalized(&self) -> Result<Self> {
let l = self.abs();
if l.get() == 0.0 {
return Err(ErrorKind::NormalizeVecWithoutLength);
}
Ok(Self::new(
self.x() / l.get(),
self.y() / l.get(),
self.z() / l.get(),
))
}
#[inline(always)]
fn zero() -> Self {
Self::new(0.0, 0.0, 0.0)
}
fn parse(text: &str) -> Result<Self> {
let mut words = text.split(" ").skip_empty_string();
let x = f64::from_str(words.next().ok_or(ErrorKind::ParseError)?)?;
let y = f64::from_str(words.next().ok_or(ErrorKind::ParseError)?)?;
let z = f64::from_str(words.next().ok_or(ErrorKind::ParseError)?)?;
if words.next().is_none() {
Ok(Self::new(x, y, z))
} else {
Err(ErrorKind::ParseError)
}
}
fn center<P>(&self, other: &P) -> Self
where
P: Is3D,
{
Self::new(
0.5 * (self.x() + other.x()),
0.5 * (self.y() + other.y()),
0.5 * (self.z() + other.z()),
)
}
}