octoon_math/
quat.rs

1use std::fmt;
2use std::fmt::Debug;
3use std::ops::{Add, Sub, Mul, Div, Neg};
4use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign};
5use crate::vec::{Vec, Math, Interpolation};
6use crate::vec3::Vec3;
7use crate::vec4::Vec4;
8use crate::consts::{Zero, One};
9
10#[derive(Debug, Copy, Clone, Default, Hash, Eq, PartialEq)]
11pub struct Quat<T>
12{
13	pub x:T,
14	pub y:T,
15	pub z:T,
16	pub w:T,
17}
18
19impl<T> Neg for Quat<T> where T:Neg<Output=T>
20{
21	type Output = Self;
22
23	fn neg(self) -> Self
24	{
25		Self
26		{
27			x: -self.x,
28			y: -self.y,
29			z: -self.z,
30			w: -self.w
31		}
32	}
33}
34
35impl<T> Add for Quat<T>  where T:Add<Output=T>
36{
37	type Output = Self;
38
39	fn add(self, other: Self) -> Self
40	{
41		Self
42		{
43			x: self.x + other.x, 
44			y: self.y + other.y, 
45			z: self.z + other.z,
46			w: self.w + other.w,
47		}
48	}
49}
50
51impl<T> Sub for Quat<T> where T:Sub<Output=T>
52{
53	type Output = Self;
54
55	fn sub(self, other: Self) -> Self
56	{
57		Self
58		{
59			x: self.x - other.x, 
60			y: self.y - other.y, 
61			z: self.z - other.z,
62			w: self.w - other.w,
63		}
64	}
65}
66
67impl<T> Mul<T> for Quat<T> where T:Mul<Output=T> + Copy
68{
69	type Output = Self;
70
71	fn mul(self, s: T) -> Self
72	{
73		Self
74		{
75			x:self.x * s,
76			y:self.y * s,
77			z:self.z * s,
78			w:self.w * s,
79		}
80	}
81}
82
83impl<T> Mul for Quat<T> where T:Mul<Output=T>
84{
85	type Output = Self;
86
87	fn mul(self, other: Self) -> Self
88	{
89		Self
90		{
91			x: self.x * other.x, 
92			y: self.y * other.y, 
93			z: self.z * other.z,
94			w: self.w * other.w,
95		}
96	}
97}
98
99impl<T> Div<T> for Quat<T> where T:Div<Output=T> + Copy
100{
101	type Output = Self;
102
103	fn div(self, s: T) -> Self
104	{
105		Self
106		{
107			x:self.x / s,
108			y:self.y / s,
109			z:self.z / s,
110			w:self.w / s,
111		}
112	}
113}
114
115impl<T> Div for Quat<T> where T:Div<Output=T>
116{
117	type Output = Self;
118
119	fn div(self, other: Self) -> Self
120	{
121		Self
122		{
123			x: self.x / other.x, 
124			y: self.y / other.y, 
125			z: self.z / other.z,
126			w: self.w / other.w,
127		}
128	}
129}
130
131impl<T> AddAssign for Quat<T> where T: AddAssign<T>
132{
133	fn add_assign(&mut self, other: Self)
134	{
135		self.x += other.x;
136		self.y += other.y; 
137		self.z += other.z; 
138		self.w += other.w; 
139	}
140}
141
142impl<T> SubAssign for Quat<T> where T: SubAssign<T>
143{
144	fn sub_assign(&mut self, other: Self)
145	{
146		self.x -= other.x;
147		self.y -= other.y; 
148		self.z -= other.z;
149		self.w -= other.w;
150	}
151}
152
153impl<T> MulAssign<T> for Quat<T> where T: MulAssign<T> + Copy
154{
155	fn mul_assign(&mut self, s: T)
156	{
157		self.x *= s;
158		self.y *= s;
159		self.z *= s;
160		self.w *= s;
161	}
162}
163
164impl<T> MulAssign for Quat<T> where T: MulAssign<T>
165{
166	fn mul_assign(&mut self, other: Self)
167	{
168		self.x *= other.x;
169		self.y *= other.y; 
170		self.z *= other.z;
171		self.w *= other.w;
172	}
173}
174
175impl<'a, T> MulAssign<&'a T> for Quat<T> where T:MulAssign<T> + Copy
176{
177	fn mul_assign(&mut self, other: &'a T)
178	{
179		self.x *= *other;
180		self.y *= *other;
181		self.z *= *other;
182		self.w *= *other;
183	}
184}
185
186impl<T> DivAssign<T> for Quat<T> where T: DivAssign<T> + Copy
187{
188	fn div_assign(&mut self, s: T)
189	{
190		self.x /= s;
191		self.y /= s;
192		self.z /= s;
193		self.w /= s;
194	}
195}
196
197impl<T> DivAssign for Quat<T> where T: DivAssign<T>
198{
199	fn div_assign(&mut self, other: Self)
200	{
201		self.x /= other.x;
202		self.y /= other.y; 
203		self.z /= other.z;
204		self.w /= other.w;
205	}
206}
207
208impl<'a, T> DivAssign<&'a T> for Quat<T> where T:DivAssign<T> + Copy
209{
210	fn div_assign(&mut self, s: &'a T)
211	{
212		self.x /= *s;
213		self.y /= *s;
214		self.z /= *s;
215		self.w /= *s;
216	}
217}
218
219impl<T> Quat<T> where T:Copy
220{
221	/// Creates a new Quat from multiple components
222	pub fn new(x: T, y: T, z: T, w: T) -> Self { Self { x, y, z, w } }
223
224	pub fn len() -> usize 
225	{
226		return 4; 
227	}
228
229	pub fn to_tuple(&self) -> (T, T, T, T)
230	{
231		(self.x, self.y, self.z, self.w)
232	}
233}
234
235impl<T> Quat<T> where T:Vec+Math
236{
237	pub fn rotation_x(theta:T) -> Self
238	{
239		let theta_half = theta * T::onehalf();
240
241		Self
242		{
243			w:theta_half.cos(),
244			x:theta_half.sin(),
245			y:T::zero(),
246			z:T::zero(),
247		}
248	}
249
250	pub fn rotation_y(theta:T) -> Self
251	{
252		let theta_half = theta * T::onehalf();
253
254		Self
255		{
256			w:theta_half.cos(),
257			x:T::zero(),
258			y:theta_half.sin(),
259			z:T::zero(),
260		}
261	}
262
263	pub fn rotation_z(theta:T) -> Self
264	{
265		let theta_half = theta * T::onehalf();
266
267		Self
268		{
269			w:theta_half.cos(),
270			x:T::zero(),
271			y:T::zero(),
272			z:theta_half.sin(),
273		}
274	}
275
276	pub fn rotation(axis:&Vec3<T>, theta:T) -> Self
277	{
278		let (s, c) = (theta * T::onehalf()).sincos();
279
280		Self
281		{
282			w:c,
283			x:axis.x * s,
284			y:axis.y * s,
285			z:axis.z * s,
286		}
287	}
288
289	pub fn direction(a:&Vec3<T>, b:&Vec3<T>) -> Self
290	{
291		let axis = a.cross(*b);
292		let cos_angle = a.dot(*b);
293
294		let t0 = T::one() + cos_angle;
295		let t1 = (t0 + t0).rsqrt();
296		let t2 = (t0 + t0) * t1 * T::onehalf();
297
298		Self
299		{
300			x:axis.x * t1,
301			y:axis.y * t1,
302			z:axis.z * t1,
303			w:t2,
304		}
305	}
306
307	pub fn euler_xyz(euler:&Vec3<T>) -> Self
308	{
309		let p = (euler.x * T::onehalf()).sincos();
310		let h = (euler.y * T::onehalf()).sincos();
311		let b = (euler.z * T::onehalf()).sincos();
312
313		let sp = p.0; let sb = b.0; let sh = h.0;
314		let cp = p.1; let cb = b.1; let ch = h.1;
315
316		Self
317		{
318			w:cp * ch * cb + sp * sh * sb,
319			x:sp * ch * cb - cp * sh * sb,
320			y:cp * sh * cb + sp * ch * sb,
321			z:cp * ch * sb - sp * sh * cb,
322		}
323	}
324
325	pub fn euler_zxy(euler:&Vec3<T>) -> Self
326	{
327		let p = (euler.x * T::onehalf()).sincos();
328		let h = (euler.y * T::onehalf()).sincos();
329		let b = (euler.z * T::onehalf()).sincos();
330
331		let sp = p.0; let sb = b.0; let sh = h.0;
332		let cp = p.1; let cb = b.1; let ch = h.1;
333
334		Self
335		{
336			w:cp * ch * cb + sp * sh * sb,
337			x:cp * sh * cb + sp * ch * sb,
338			y:cp * ch * sb - sp * sh * cb,
339			z:sp * ch * cb - cp * sh * sb,
340		}
341	}
342
343	pub fn dot(&self, b: Self) -> T 
344	{
345		return self.x * b.x + self.y * b.y + self.z * b.z + self.w * b.w;
346	}
347	
348	pub fn cross(&self, b: Self) -> Self 
349	{
350		Self
351		{
352			x:self.w * b.x + self.x * b.w + self.z * b.y - self.y * b.z,
353			y:self.w * b.y + self.y * b.w + self.x * b.z - self.z * b.x,
354			z:self.w * b.z + self.z * b.w + self.y * b.x - self.x * b.y,
355			w:self.w * b.w - self.x * b.x - self.y * b.y - self.z * b.z,
356		}
357	}
358	
359	pub fn length2(&self) -> T 
360	{
361		return self.dot(*self);
362	}
363	
364	pub fn length(&self) -> T 
365	{
366		return self.length2().sqrt();
367	}
368	
369	pub fn distance(&self, b: Self) -> T 
370	{
371		return (*self - b).length();
372	}
373
374	pub fn normalize(&self) -> Self 
375	{
376		let mag_sq = self.length2();
377		if mag_sq.gt(T::zero())
378		{
379			let inv_sqrt = T::one() / mag_sq.sqrt();
380			return *self * inv_sqrt;
381		}
382
383		return *self;
384	}
385
386	pub fn axis(&self) -> Vec3<T>
387	{
388		let sin_theta_over2_sq = T::one() - self.w * self.w;
389		if sin_theta_over2_sq.le(T::zero())
390		{
391			return Vec3::new(T::one(), T::zero(), T::zero());
392		}
393
394		let v = Vec3::new(self.x, self.y, self.z);
395		let inv_sqrt = T::one() / sin_theta_over2_sq.sqrt();
396
397		return v * Vec3::new(inv_sqrt, inv_sqrt, inv_sqrt);
398	}
399
400	pub fn angle(&self) -> T
401	{
402		self.w.acos() * T::two()
403	}
404
405	pub fn conjugate(&self) -> Self
406	{
407		Self
408		{ 
409			x: -self.x, 
410			y: -self.y,
411			z: -self.z,
412			w:  self.w
413		}
414	}
415
416	pub fn inverse(&self) -> Self
417	{
418		self.conjugate()
419	}
420}
421
422impl<T> Math for Quat<T> where T:Copy + Math
423{
424	fn abs(self) -> Self
425	{
426		let mx = self.x.abs();
427		let my = self.y.abs();
428		let mz = self.z.abs();
429		let mw = self.w.abs();
430		Self { x: mx, y: my, z: mz, w:mw }
431	}
432
433	fn recip(self) -> Self
434	{
435		let mx = self.x.recip();
436		let my = self.y.recip();
437		let mz = self.z.recip();
438		let mw = self.w.recip();
439		Self { x: mx, y: my, z: mz, w:mw }
440	}
441
442	fn sqrt(self) -> Self
443	{
444		let mx = self.x.sqrt();
445		let my = self.y.sqrt();
446		let mz = self.z.sqrt();
447		let mw = self.w.sqrt();
448		Self { x: mx, y: my, z: mz, w:mw }
449	}
450
451	fn rsqrt(self) -> Self
452	{
453		let mx = self.x.rsqrt();
454		let my = self.y.rsqrt();
455		let mz = self.z.rsqrt();
456		let mw = self.w.rsqrt();
457		Self { x: mx, y: my, z: mz, w:mw }
458	}
459
460	fn sin(self) -> Self
461	{
462		let mx = self.x.sin();
463		let my = self.y.sin();
464		let mz = self.z.sin();
465		let mw = self.w.sin();
466		Self { x: mx, y: my, z: mz, w:mw }
467	}
468
469	fn cos(self) -> Self
470	{
471		let mx = self.x.cos();
472		let my = self.y.cos();
473		let mz = self.z.cos();
474		let mw = self.w.cos();
475		Self { x: mx, y: my, z: mz, w:mw }
476	}
477
478	fn tan(self) -> Self
479	{
480		let mx = self.x.tan();
481		let my = self.y.tan();
482		let mz = self.z.tan();
483		let mw = self.w.tan();
484		Self { x: mx, y: my, z: mz, w:mw }
485	}
486
487	fn sincos(self) -> (Quat<T>, Quat<T>)
488	{
489		let mx = self.x.sincos();
490		let my = self.y.sincos();
491		let mz = self.z.sincos();
492		let mw = self.w.sincos();
493		(
494			Self { x: mx.0, y: my.0, z: mz.0, w: mw.0 },
495			Self { x: mx.1, y: my.1, z: mz.1, w: mw.1 }
496		)
497	}
498
499	fn acos(self) -> Self
500	{
501		let mx = self.x.acos();
502		let my = self.y.acos();
503		let mz = self.z.acos();
504		let mw = self.w.acos();
505		Self { x: mx, y: my, z: mz, w:mw }
506	}
507
508	fn asin(self) -> Self
509	{
510		let mx = self.x.asin();
511		let my = self.y.asin();
512		let mz = self.z.asin();
513		let mw = self.w.asin();
514		Self { x: mx, y: my, z: mz, w:mw }
515	}
516
517	fn atan(self) -> Self
518	{
519		let mx = self.x.atan();
520		let my = self.y.atan();
521		let mz = self.z.atan();
522		let mw = self.w.atan();
523		Self { x: mx, y: my, z: mz, w:mw }
524	}
525
526	fn exp(self) -> Self
527	{
528		let mx = self.x.exp();
529		let my = self.y.exp();
530		let mz = self.z.exp();
531		let mw = self.w.exp();
532		Self { x: mx, y: my, z: mz, w:mw }
533	}
534
535	fn exp2(self) -> Self
536	{
537		let mx = self.x.exp2();
538		let my = self.y.exp2();
539		let mz = self.z.exp2();
540		let mw = self.w.exp2();
541		Self { x: mx, y: my, z: mz, w:mw }
542	}
543
544	fn log(self, _rhs: Self) -> Self
545	{
546		let mx = self.x.log(_rhs.x);
547		let my = self.y.log(_rhs.y);
548		let mz = self.z.log(_rhs.z);
549		let mw = self.w.log(_rhs.w);
550		Self { x: mx, y: my, z: mz, w:mw }
551	}
552
553	fn log2(self) -> Self
554	{
555		let mx = self.x.log2();
556		let my = self.y.log2();
557		let mz = self.z.log2();
558		let mw = self.w.log2();
559		Self { x: mx, y: my, z: mz, w:mw }
560	}
561
562	fn log10(self) -> Self
563	{
564		let mx = self.x.log10();
565		let my = self.y.log10();
566		let mz = self.z.log10();
567		let mw = self.w.log10();
568		Self { x: mx, y: my, z: mz, w:mw }
569	}
570
571	fn to_radians(self) -> Self
572	{
573		let mx = self.x.to_radians();
574		let my = self.y.to_radians();
575		let mz = self.z.to_radians();
576		let mw = self.w.to_radians();
577		Self { x: mx, y: my, z: mz, w:mw }
578	}
579
580	fn to_degrees(self) -> Self
581	{
582		let mx = self.x.to_degrees();
583		let my = self.y.to_degrees();
584		let mz = self.z.to_degrees();
585		let mw = self.w.to_degrees();
586		Self { x: mx, y: my, z: mz, w:mw }
587	}
588
589	fn min(self, _rhs: Self) -> Self
590	{
591		let mx = self.x.min(_rhs.x);
592		let my = self.y.min(_rhs.y);
593		let mz = self.z.min(_rhs.z);
594		let mw = self.w.min(_rhs.x);
595		Self { x: mx, y: my, z: mz, w:mw }
596	}
597
598	fn max(self, _rhs: Self) -> Self
599	{
600		let mx = self.x.max(_rhs.x);
601		let my = self.y.max(_rhs.y);
602		let mz = self.z.max(_rhs.z);
603		let mw = self.w.max(_rhs.w);
604		Self { x: mx, y: my, z: mz, w:mw }
605	}
606
607	fn saturate(self) -> Self
608	{
609		let mx = self.x.saturate();
610		let my = self.y.saturate();
611		let mz = self.z.saturate();
612		let mw = self.w.saturate();
613		Self { x: mx, y: my, z: mz, w: mw }
614	}
615
616	#[inline]
617	fn snorm2unorm(self) -> Self
618	{
619		let mx = self.x.snorm2unorm();
620		let my = self.y.snorm2unorm();
621		let mz = self.z.snorm2unorm();
622		let mw = self.w.snorm2unorm();
623		Self { x: mx, y: my, z: mz, w: mw }
624	}
625
626	#[inline]
627	fn unorm2snorm(self) -> Self
628	{
629		let mx = self.x.unorm2snorm();
630		let my = self.y.unorm2snorm();
631		let mz = self.z.unorm2snorm();
632		let mw = self.w.unorm2snorm();
633		Self { x: mx, y: my, z: mz, w: mw }
634	}
635	
636	fn clamp(self, minval: Self, maxval: Self) -> Self
637	{
638		let mx = self.x.clamp(minval.x, maxval.x);
639		let my = self.y.clamp(minval.y, maxval.y);
640		let mz = self.z.clamp(minval.z, maxval.z);
641		let mw = self.w.clamp(minval.w, maxval.w);
642		Self { x: mx, y: my, z: mz, w:mw }
643	}
644}
645
646impl<T> Interpolation<T> for Quat<T> where T: Copy + One + Mul<Output=T> + Add<Output=T> + Sub<Output=T>
647{
648	#[inline(always)]
649	fn lerp(self, b: Self, t: T) -> Self 
650	{
651		return self*(T::one() - t) + b*t;
652	}
653}
654
655impl<T> Zero for Quat<T> where T:Zero
656{
657	#[inline(always)]
658	fn zero() -> Self
659	{
660		Self
661		{ 
662			x: T::zero(), y: T::zero(), z: T::zero(), w: T::zero() 
663		}
664	}
665}
666
667impl<T> One for Quat<T> where T:One
668{
669	#[inline(always)]
670	fn one() -> Self
671	{
672		Self
673		{ 
674			x: T::one(), y: T::one(), z: T::one(), w: T::one() 
675		}
676	}
677}
678
679impl<T> fmt::Display for Quat<T> where T:Debug
680{
681	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
682	{
683		write!(f, "({:?}, {:?}, {:?}, {:?})", self.x, self.y, self.z, self.w)
684	}
685}
686
687impl<T> fmt::Binary for Quat<T> where T:Vec + Math
688{
689	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
690	{
691		let len = self.length();
692		let decimals = f.precision().unwrap_or(3);
693		let string = format!("{:.*?}", decimals, len);
694		f.pad_integral(true, "", &string)
695	}
696}
697
698impl<T> From<Vec4<T>> for Quat<T> where T:Copy + Div<Output=T>
699{
700	fn from(v:Vec4<T>) -> Self
701	{
702		Self
703		{
704			x:v.x,
705			y:v.y,
706			z:v.z,
707			w:v.w
708		}
709	}
710}
711
712impl<T> From<[T;4]> for Quat<T> where T:Copy + Div<Output=T>
713{
714	fn from(v:[T;4]) -> Self
715	{
716		Self
717		{
718			x:v[0],
719			y:v[1],
720			z:v[2],
721			w:v[3],
722		}
723	}
724}
725
726impl<T> From<(T,T,T,T)> for Quat<T> where T:Copy + Div<Output=T>
727{
728	fn from(v:(T,T,T,T)) -> Self
729	{
730		Self
731		{
732			x:v.0,
733			y:v.1,
734			z:v.2,
735			w:v.3
736		}
737	}
738}
739
740impl<T> AsRef<Quat<T>> for Quat<T>
741{
742	fn as_ref(&self) -> &Quat<T>
743	{
744		self
745	}
746}
747
748impl<T> AsMut<Quat<T>> for Quat<T>
749{
750	fn as_mut(&mut self) -> &mut Quat<T>
751	{
752		self
753	}
754}