OWL
Loading...
Searching...
No Matches
Quaternion.h
1// ======================================================================== //
2// Copyright 2018-2019 Ingo Wald //
3// //
4// Licensed under the Apache License, Version 2.0 (the "License"); //
5// you may not use this file except in compliance with the License. //
6// You may obtain a copy of the License at //
7// //
8// http://www.apache.org/licenses/LICENSE-2.0 //
9// //
10// Unless required by applicable law or agreed to in writing, software //
11// distributed under the License is distributed on an "AS IS" BASIS, //
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
13// See the License for the specific language governing permissions and //
14// limitations under the License. //
15// ======================================================================== //
16
17/* originally taken (and adapted) from ospray, under following license */
18
19// ======================================================================== //
20// Copyright 2009-2018 Intel Corporation //
21// //
22// Licensed under the Apache License, Version 2.0 (the "License"); //
23// you may not use this file except in compliance with the License. //
24// You may obtain a copy of the License at //
25// //
26// http://www.apache.org/licenses/LICENSE-2.0 //
27// //
28// Unless required by applicable law or agreed to in writing, software //
29// distributed under the License is distributed on an "AS IS" BASIS, //
30// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
31// See the License for the specific language governing permissions and //
32// limitations under the License. //
33// ======================================================================== //
34
35#pragma once
36
37#include "vec.h"
38
39namespace owl {
40 namespace common {
41
43 // Quaternion Struct
45
46 template<typename T>
48 {
49 typedef vec_t<T,3> Vector;
50
54
55 __both__ QuaternionT ( void ) { }
56 __both__ QuaternionT ( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; }
57 __both__ QuaternionT& operator=( const QuaternionT& other ) { r = other.r; i = other.i; j = other.j; k = other.k; return *this; }
58
59 __both__ QuaternionT( const T& r ) : r(r), i(zero), j(zero), k(zero) {}
60 __both__ explicit QuaternionT( const Vector& v ) : r(zero), i(v.x), j(v.y), k(v.z) {}
61 __both__ QuaternionT( const T& r, const T& i, const T& j, const T& k ) : r(r), i(i), j(j), k(k) {}
62 __both__ QuaternionT( const T& r, const Vector& v ) : r(r), i(v.x), j(v.y), k(v.z) {}
63
64 __inline QuaternionT( const Vector& vx, const Vector& vy, const Vector& vz );
65 __inline QuaternionT( const T& yaw, const T& pitch, const T& roll );
66
70
71#ifdef __CUDA_ARCH__
72 __both__ QuaternionT( const ZeroTy & ) : r(zero), i(zero), j(zero), k(zero) {}
73 __both__ QuaternionT( const OneTy & ) : r( one), i(zero), j(zero), k(zero) {}
74#else
75 __both__ QuaternionT( ZeroTy ) : r(zero), i(zero), j(zero), k(zero) {}
76 __both__ QuaternionT( OneTy ) : r( one), i(zero), j(zero), k(zero) {}
77#endif
78
80 static __both__ QuaternionT rotate(const Vector& u, const T& r) {
81 return QuaternionT<T>(cos(T(0.5)*r),sin(T(0.5)*r)*normalize(u));
82 }
83
85 __both__ const Vector v( ) const { return Vector(i, j, k); }
86
87 public:
88 T r, i, j, k;
89 };
90
91 template<typename T> __both__ QuaternionT<T> operator *( const T & a, const QuaternionT<T>& b ) { return QuaternionT<T>(a * b.r, a * b.i, a * b.j, a * b.k); }
92 template<typename T> __both__ QuaternionT<T> operator *( const QuaternionT<T>& a, const T & b ) { return QuaternionT<T>(a.r * b, a.i * b, a.j * b, a.k * b); }
93
95 // Unary Operators
97
98 template<typename T> __both__ QuaternionT<T> operator +( const QuaternionT<T>& a ) { return QuaternionT<T>(+a.r, +a.i, +a.j, +a.k); }
99 template<typename T> __both__ QuaternionT<T> operator -( const QuaternionT<T>& a ) { return QuaternionT<T>(-a.r, -a.i, -a.j, -a.k); }
100 template<typename T> __both__ QuaternionT<T> conj ( const QuaternionT<T>& a ) { return QuaternionT<T>(a.r, -a.i, -a.j, -a.k); }
101 template<typename T> __both__ T abs ( const QuaternionT<T>& a ) { return sqrt(a.r*a.r + a.i*a.i + a.j*a.j + a.k*a.k); }
102 template<typename T> __both__ QuaternionT<T> rcp ( const QuaternionT<T>& a ) { return conj(a)*rcp(a.r*a.r + a.i*a.i + a.j*a.j + a.k*a.k); }
103 template<typename T> __both__ QuaternionT<T> normalize ( const QuaternionT<T>& a ) { return a*rsqrt(a.r*a.r + a.i*a.i + a.j*a.j + a.k*a.k); }
104
106 // Binary Operators
108
109 template<typename T> __both__ QuaternionT<T> operator +( const T & a, const QuaternionT<T>& b ) { return QuaternionT<T>(a + b.r, b.i, b.j, b.k); }
110 template<typename T> __both__ QuaternionT<T> operator +( const QuaternionT<T>& a, const T & b ) { return QuaternionT<T>(a.r + b, a.i, a.j, a.k); }
111 template<typename T> __both__ QuaternionT<T> operator +( const QuaternionT<T>& a, const QuaternionT<T>& b ) { return QuaternionT<T>(a.r + b.r, a.i + b.i, a.j + b.j, a.k + b.k); }
112 template<typename T> __both__ QuaternionT<T> operator -( const T & a, const QuaternionT<T>& b ) { return QuaternionT<T>(a - b.r, -b.i, -b.j, -b.k); }
113 template<typename T> __both__ QuaternionT<T> operator -( const QuaternionT<T>& a, const T & b ) { return QuaternionT<T>(a.r - b, a.i, a.j, a.k); }
114 template<typename T> __both__ QuaternionT<T> operator -( const QuaternionT<T>& a, const QuaternionT<T>& b ) { return QuaternionT<T>(a.r - b.r, a.i - b.i, a.j - b.j, a.k - b.k); }
115
116 template<typename T> __both__ typename QuaternionT<T>::Vector operator *( const QuaternionT<T>& a, const typename QuaternionT<T>::Vector & b ) { return (a*QuaternionT<T>(b)*conj(a)).v(); }
117 template<typename T> __both__ QuaternionT<T> operator *( const QuaternionT<T>& a, const QuaternionT<T>& b ) {
118 return QuaternionT<T>(a.r*b.r - a.i*b.i - a.j*b.j - a.k*b.k,
119 a.r*b.i + a.i*b.r + a.j*b.k - a.k*b.j,
120 a.r*b.j - a.i*b.k + a.j*b.r + a.k*b.i,
121 a.r*b.k + a.i*b.j - a.j*b.i + a.k*b.r);
122 }
123 template<typename T> __both__ QuaternionT<T> operator /( const T & a, const QuaternionT<T>& b ) { return a*rcp(b); }
124 template<typename T> __both__ QuaternionT<T> operator /( const QuaternionT<T>& a, const T & b ) { return a*rcp(b); }
125 template<typename T> __both__ QuaternionT<T> operator /( const QuaternionT<T>& a, const QuaternionT<T>& b ) { return a*rcp(b); }
126
127 template<typename T> __both__ QuaternionT<T>& operator +=( QuaternionT<T>& a, const T & b ) { return a = a+b; }
128 template<typename T> __both__ QuaternionT<T>& operator +=( QuaternionT<T>& a, const QuaternionT<T>& b ) { return a = a+b; }
129 template<typename T> __both__ QuaternionT<T>& operator -=( QuaternionT<T>& a, const T & b ) { return a = a-b; }
130 template<typename T> __both__ QuaternionT<T>& operator -=( QuaternionT<T>& a, const QuaternionT<T>& b ) { return a = a-b; }
131 template<typename T> __both__ QuaternionT<T>& operator *=( QuaternionT<T>& a, const T & b ) { return a = a*b; }
132 template<typename T> __both__ QuaternionT<T>& operator *=( QuaternionT<T>& a, const QuaternionT<T>& b ) { return a = a*b; }
133 template<typename T> __both__ QuaternionT<T>& operator /=( QuaternionT<T>& a, const T & b ) { return a = a*rcp(b); }
134 template<typename T> __both__ QuaternionT<T>& operator /=( QuaternionT<T>& a, const QuaternionT<T>& b ) { return a = a*rcp(b); }
135
136 template<typename T> __both__ typename QuaternionT<T>::Vector
137 xfmPoint ( const QuaternionT<T>& a,
138 const typename QuaternionT<T>::Vector& b )
139 { return (a*QuaternionT<T>(b)*conj(a)).v(); }
140
141 template<typename T> __both__ typename QuaternionT<T>::Vector
142 xfmQuaternion( const QuaternionT<T>& a,
143 const typename QuaternionT<T>::Vector& b )
144 { return (a*QuaternionT<T>(b)*conj(a)).v(); }
145
146
147 template<typename T> __both__ typename QuaternionT<T>::Vector
148 xfmNormal( const QuaternionT<T>& a,
149 const typename QuaternionT<T>::Vector& b )
150 { return (a*QuaternionT<T>(b)*conj(a)).v(); }
151
155
156 template<typename T> __both__ bool operator ==( const QuaternionT<T>& a, const QuaternionT<T>& b ) { return a.r == b.r && a.i == b.i && a.j == b.j && a.k == b.k; }
157
158 template<typename T> __both__ bool operator !=( const QuaternionT<T>& a, const QuaternionT<T>& b ) { return a.r != b.r || a.i != b.i || a.j != b.j || a.k != b.k; }
159
160
164
165 template<typename T>
166 QuaternionT<T>::QuaternionT(const typename QuaternionT<T>::Vector& vx,
167 const typename QuaternionT<T>::Vector& vy,
168 const typename QuaternionT<T>::Vector& vz )
169 {
170 if ( vx.x + vy.y + vz.z >= T(zero) )
171 {
172 const T t = T(one) + (vx.x + vy.y + vz.z);
173 const T s = rsqrt(t)*T(0.5f);
174 r = t*s;
175 i = (vy.z - vz.y)*s;
176 j = (vz.x - vx.z)*s;
177 k = (vx.y - vy.x)*s;
178 }
179 else if ( vx.x >= max(vy.y, vz.z) )
180 {
181 const T t = (T(one) + vx.x) - (vy.y + vz.z);
182 const T s = rsqrt(t)*T(0.5f);
183 r = (vy.z - vz.y)*s;
184 i = t*s;
185 j = (vx.y + vy.x)*s;
186 k = (vz.x + vx.z)*s;
187 }
188 else if ( vy.y >= vz.z ) // if ( vy.y >= max(vz.z, vx.x) )
189 {
190 const T t = (T(one) + vy.y) - (vz.z + vx.x);
191 const T s = rsqrt(t)*T(0.5f);
192 r = (vz.x - vx.z)*s;
193 i = (vx.y + vy.x)*s;
194 j = t*s;
195 k = (vy.z + vz.y)*s;
196 }
197 else //if ( vz.z >= max(vy.y, vx.x) )
198 {
199 const T t = (T(one) + vz.z) - (vx.x + vy.y);
200 const T s = rsqrt(t)*T(0.5f);
201 r = (vx.y - vy.x)*s;
202 i = (vz.x + vx.z)*s;
203 j = (vy.z + vz.y)*s;
204 k = t*s;
205 }
206 }
207
208 template<typename T> QuaternionT<T>::QuaternionT( const T& yaw, const T& pitch, const T& roll )
209 {
210 const T cya = cos(yaw *T(0.5f));
211 const T cpi = cos(pitch*T(0.5f));
212 const T cro = cos(roll *T(0.5f));
213 const T sya = sin(yaw *T(0.5f));
214 const T spi = sin(pitch*T(0.5f));
215 const T sro = sin(roll *T(0.5f));
216 r = cro*cya*cpi + sro*sya*spi;
217 i = cro*cya*spi + sro*sya*cpi;
218 j = cro*sya*cpi - sro*cya*spi;
219 k = sro*cya*cpi - cro*sya*spi;
220 }
221
225
226 template<typename T> static std::ostream& operator<<(std::ostream& cout, const QuaternionT<T>& q) {
227 return cout << "{ r = " << q.r << ", i = " << q.i << ", j = " << q.j << ", k = " << q.k << " }";
228 }
229
231 typedef QuaternionT<float> Quaternion3f;
232 typedef QuaternionT<double> Quaternion3d;
233
234 } // ::owl::common
235} // ::owl
Definition: Quaternion.h:48
__both__ QuaternionT(ZeroTy)
Constants.
Definition: Quaternion.h:75
__both__ QuaternionT(void)
Construction.
Definition: Quaternion.h:55
__both__ const Vector v() const
Definition: Quaternion.h:85
static __both__ QuaternionT rotate(const Vector &u, const T &r)
Definition: Quaternion.h:80
Definition: vec.h:143
Definition: vec.h:33