commonlibsse_ng\re\h/
hkVector4.rs1use crate::re::NiPoint3::NiPoint3;
2use crate::re::hkSseMathTypes::hkQuadReal;
3use core::arch::x86_64::{
4 __m128, _mm_add_ps, _mm_cvtss_f32, _mm_div_ps, _mm_hadd_ps, _mm_mul_ps, _mm_set1_ps,
5 _mm_setr_ps, _mm_setzero_ps, _mm_sub_ps,
6};
7use core::ops::{Add, Div, Mul, Sub};
8
9#[repr(C)]
16#[derive(Debug, Clone, Copy)]
17pub struct hkVector4 {
18 pub quad: hkQuadReal,
21}
22
23const _: () = {
25 assert!(core::mem::offset_of!(hkVector4, quad) == 0x0);
26 assert!(core::mem::size_of::<hkVector4>() == 0x10);
27};
28
29impl hkVector4 {
30 #[inline]
32 pub fn new() -> Self {
33 unsafe { Self { quad: _mm_setzero_ps() } }
34 }
35
36 #[inline]
38 pub fn from_scalar(x: f32) -> Self {
39 unsafe { Self { quad: _mm_set1_ps(x) } }
40 }
41
42 #[inline]
44 pub fn from_components(x: f32, y: f32, z: f32, w: f32) -> Self {
45 unsafe { Self { quad: _mm_setr_ps(x, y, z, w) } }
46 }
47
48 #[inline]
50 pub fn from_ni_point3(point: NiPoint3) -> Self {
51 unsafe { Self { quad: _mm_setr_ps(point.x, point.y, point.z, 0.0) } }
52 }
53
54 #[inline]
56 pub fn IsEqual(&self, pt: Self, epsilon: f32) -> bool {
57 let diff = self.sub(pt);
58 diff.SqrLength4() < epsilon * epsilon
59 }
60
61 #[inline]
63 pub fn Cross(&self, pt: Self) -> Self {
64 let x1 = self.get_component(0);
65 let y1 = self.get_component(1);
66 let z1 = self.get_component(2);
67 let x2 = pt.get_component(0);
68 let y2 = pt.get_component(1);
69 let z2 = pt.get_component(2);
70 Self::from_components(
71 y1.mul_add(z2, -(z1 * y2)),
72 z1.mul_add(x2, -(x1 * z2)),
73 x1.mul_add(y2, -(y1 * x2)),
74 0.0,
75 )
76 }
77
78 #[inline]
80 pub fn Dot3(&self, pt: Self) -> f32 {
81 let prod = self.mul(pt);
82 prod.get_component(0) + prod.get_component(1) + prod.get_component(2)
83 }
84
85 #[inline]
87 pub fn Dot4(&self, pt: Self) -> f32 {
88 unsafe {
89 let prod = _mm_mul_ps(self.quad, pt.quad);
90 let sum1 = _mm_hadd_ps(prod, prod); let sum2 = _mm_hadd_ps(sum1, sum1); _mm_cvtss_f32(sum2) }
94 }
95
96 #[inline]
98 pub fn GetDistance3(&self, pt: Self) -> f32 {
99 self.GetSquaredDistance3(pt).sqrt()
100 }
101
102 #[inline]
104 pub fn GetSquaredDistance3(&self, pt: Self) -> f32 {
105 let diff = self.sub(pt);
106 diff.SqrLength3()
107 }
108
109 #[inline]
111 pub fn Length3(&self) -> f32 {
112 self.SqrLength3().sqrt()
113 }
114
115 #[inline]
117 pub fn SqrLength3(&self) -> f32 {
118 let x = self.get_component(0);
119 let y = self.get_component(1);
120 let z = self.get_component(2);
121 z.mul_add(z, x.mul_add(x, y * y))
122 }
123
124 #[inline]
126 pub fn Length4(&self) -> f32 {
127 self.SqrLength4().sqrt()
128 }
129
130 #[inline]
132 pub fn SqrLength4(&self) -> f32 {
133 unsafe {
134 let sq = _mm_mul_ps(self.quad, self.quad);
135 let sum1 = _mm_hadd_ps(sq, sq);
136 let sum2 = _mm_hadd_ps(sum1, sum1);
137 _mm_cvtss_f32(sum2)
138 }
139 }
140
141 #[inline]
143 pub fn get_component(&self, index: usize) -> f32 {
144 unsafe {
145 let arr = core::mem::transmute::<__m128, [f32; 4]>(self.quad);
146 arr[index]
147 }
148 }
149
150 #[inline]
152 pub fn set_component(&mut self, index: usize, value: f32) {
153 unsafe {
154 let mut arr = core::mem::transmute::<__m128, [f32; 4]>(self.quad);
155 arr[index] = value;
156 self.quad = core::mem::transmute::<[f32; 4], __m128>(arr);
157 }
158 }
159}
160
161impl Default for hkVector4 {
162 #[inline]
163 fn default() -> Self {
164 Self::new()
165 }
166}
167
168impl From<hkQuadReal> for hkVector4 {
169 #[inline]
170 fn from(quad: hkQuadReal) -> Self {
171 Self { quad }
172 }
173}
174
175impl From<NiPoint3> for hkVector4 {
176 #[inline]
177 fn from(point: NiPoint3) -> Self {
178 Self::from_ni_point3(point)
179 }
180}
181
182impl core::ops::Add for hkVector4 {
184 type Output = Self;
185 #[inline]
186 fn add(self, rhs: Self) -> Self::Output {
187 unsafe { Self { quad: _mm_add_ps(self.quad, rhs.quad) } }
188 }
189}
190
191impl core::ops::Sub for hkVector4 {
192 type Output = Self;
193 #[inline]
194 fn sub(self, rhs: Self) -> Self::Output {
195 unsafe { Self { quad: _mm_sub_ps(self.quad, rhs.quad) } }
196 }
197}
198
199impl core::ops::Mul for hkVector4 {
200 type Output = Self;
201 #[inline]
202 fn mul(self, rhs: Self) -> Self::Output {
203 unsafe { Self { quad: _mm_mul_ps(self.quad, rhs.quad) } }
204 }
205}
206
207impl core::ops::Div for hkVector4 {
208 type Output = Self;
209 #[inline]
210 fn div(self, rhs: Self) -> Self::Output {
211 unsafe { Self { quad: _mm_div_ps(self.quad, rhs.quad) } }
212 }
213}
214
215impl core::ops::AddAssign for hkVector4 {
216 #[inline]
217 fn add_assign(&mut self, rhs: Self) {
218 self.quad = self.add(rhs).quad;
219 }
220}
221
222impl core::ops::SubAssign for hkVector4 {
223 #[inline]
224 fn sub_assign(&mut self, rhs: Self) {
225 self.quad = self.sub(rhs).quad;
226 }
227}
228
229impl core::ops::MulAssign for hkVector4 {
230 #[inline]
231 fn mul_assign(&mut self, rhs: Self) {
232 self.quad = self.mul(rhs).quad;
233 }
234}
235
236impl core::ops::DivAssign for hkVector4 {
237 #[inline]
238 fn div_assign(&mut self, rhs: Self) {
239 self.quad = self.div(rhs).quad;
240 }
241}