2 (in-package :cl-tuples
)
4 (def-tuple-type quaternion
5 :tuple-element-type fast-float
9 (export-tuple-operations quaternion
)
11 (def-tuple-type angle-axis
12 :tuple-element-type fast-float
13 :initial-element
0.0f0
16 (export-tuple-operations angle-axis
)
18 ;; need conjugate, angle-axis conversion, slerp
20 (def-tuple-op quaternion-conjugate
*
21 ((q quaternion
(x y z w
)))
22 (quaternion-values* (- x
) (- y
) (- z
) w
))
24 (def-tuple-op quaternion-scale
*
25 ((q quaternion
(x y z w
))
27 "Multiply a quat by a scalar"
30 (* s x
) (* s y
) (* s z
) (* s w
))))
32 (def-tuple-op quaternion-norm
*
33 ((q quaternion
(x y z w
)))
35 (sqrt (+ (* x x
) (* y y
) (* z z
) (* w w
)))))
39 (def-tuple-op quaternion-unitize
*
40 ((q quaternion
(x y z w
)))
41 "Ensure a quaternion is a unit"
45 (/ 1.0 (sqrt (+ (* x x
) (* y y
) (* z z
) (* w w
)))))))
46 (quaternion-values* (* x
1/mag
) (* y
1/mag
) (* z
1/mag
) (* w
1/mag
)))))
48 (def-tuple-op quaternion-sum
*
49 ((q0 quaternion
(x0 y0 z0 w0
))
50 (q1 quaternion
(x1 y1 z1 w1
)))
51 "Sum the components of two quaternions"
53 (quaternion-values* (+ x0 x1
) (+ y0 y1
) (+ z0 z1
) (+ w0 w1
))))
55 (def-tuple-op quaternion-dot
*
56 ((quaternion-lhs quaternion
(x0 y0 z0 w0
))
57 (quaternion-rhs quaternion
(x1 y1 z1 w1
)))
58 "Dot product of two quaternions."
60 (+ (* x0 x1
) (* y0 y1
) (* z0 z1
) (* w0 w1
))))
62 (def-tuple-op quaternion-inverse
*
63 ((q quarternion
(x y z w
)))
64 "Inverse of quaternion"
68 (sqrt (+ (* x x
) (* y y
) (* z z
) (* w w
)))))
70 (the single-float
(/ 1.0 (* mag mag
)))))
71 (declare (single-float mag2
))
72 (quaternion-values* (/ x mag2
) (/ y mag2
) (/ z mag2
) (/ w mag2
)))))
75 (def-tuple-op quaternion-product
*
76 ((q-lhs quaternion
(x1 y1 z1 w1
))
77 (q-rhs quaternion
(x2 y2 z2 w2
)))
78 "Multiple of two quaternions"
80 (quaternion-values* (- (+ (* w1 x2
) (* x1 w2
) (* y1 z2
)) (* z1 y2
))
81 (- (+ (* w1 y2
) (* y1 w2
) (* z1 x2
)) (* x1 z2
))
82 (- (+ (* w1 z2
) (* x1 y2
) (* z1 w2
)) (* y1 x2
))
83 (- (* w1 w2
) (* x1 x2
) (* y1 y2
) (* z1 z2
)))))
85 (def-tuple-op quaternion-matrix33
*
86 ((q quaternion
(x y z w
)))
87 "Convert a quaternion to a 3x3 rotation matrix."
90 (- 1 (* 2 y y
) (* 2 z z
)) (- (* 2 x y
) (* 2 w z
)) (+ (* 2 x z
) (* 2 w y
))
91 (+ (* 2 x y
) (* 2 w z
)) (- 1 (* 2 x x
) (* 2 z z
)) (- (* 2 y z
) (* 2 w x
))
92 (- (* 2 x z
) (* 2 w y
)) (+ (* 2 y z
) (* 2 w x
)) (- 1 (* 2 x x
) (* 2 y y
)))))
95 (def-tuple-op angle-axis-quaternion
*
96 ((aa angle-axis
(x y z a
)))
97 "Convert an angle-axis tuple to a quaternion tuple"
99 (quaternion-values* (* x
(sin (* 0.5 a
)))
100 (* y
(sin (* 0.5 a
)))
101 (* z
(sin (* 0.5 a
)))
106 (def-tuple-op quaternion-transform-vector3d
*
107 ((vector vector3d
(vx vy vz
))
108 (quat quaternion
(qx qy qz qw
)))
109 "Transform a 3d vector with a quaternion"
114 (quaternion-values* qx qy qz qw
)
115 (quaternion-values* vx vy vz
0.0))
116 (quaternion-conjugate (quaternion-values* qx qy qz qw
)))
118 (vector3d-values* rx ry rz
))))
121 (def-tuple-op vector3d-quaternion
*
122 ((vector vector3d
(vx vy vz
)))
123 "Convert a 3d vector into q auqt for angular velocity purposes"
125 (quaternion-values* vx vy vz
0.0)))