@@ -40,6 +40,8 @@ struct quaternion
4040 using vector3_type = vector <T, 3 >;
4141 using matrix_type = matrix <T, 3 , 3 >;
4242
43+ using AsUint = typename unsigned_integer_of_size<sizeof (scalar_type)>::type;
44+
4345 static this_t create ()
4446 {
4547 this_t q;
@@ -66,7 +68,7 @@ struct quaternion
6668 this_t q;
6769 const scalar_type sinTheta = hlsl::sin (angle * 0.5 );
6870 const scalar_type cosTheta = hlsl::cos (angle * 0.5 );
69- q.data = data_type (axis.x * sinTheta, axis.y * sinTheta, axis.z * sinTheta, cosTheta);
71+ q.data = data_type (axis * sinTheta, cosTheta);
7072 return q;
7173 }
7274
@@ -96,7 +98,6 @@ struct quaternion
9698
9799 static this_t create (NBL_CONST_REF_ARG (matrix_type) m)
98100 {
99- using AsUint = typename unsigned_integer_of_size<sizeof (scalar_type)>::type;
100101 const scalar_type m00 = m[0 ][0 ], m11 = m[1 ][1 ], m22 = m[2 ][2 ];
101102 const scalar_type neg_m00 = bit_cast<scalar_type>(bit_cast<AsUint>(m00)^0x80000000u);
102103 const scalar_type neg_m11 = bit_cast<scalar_type>(bit_cast<AsUint>(m11)^0x80000000u);
@@ -147,7 +148,7 @@ struct quaternion
147148 return retval;
148149 }
149150
150- static this_t createFromTruncated (NBL_CONST_REF_ARG (truncated_quaternion<T>) first3Components)
151+ static this_t create (NBL_CONST_REF_ARG (truncated_quaternion<T>) first3Components)
151152 {
152153 this_t retval;
153154 retval.data.xyz = first3Components.data;
@@ -174,7 +175,6 @@ struct quaternion
174175
175176 static this_t lerp (const this_t start, const this_t end, const scalar_type fraction, const scalar_type totalPseudoAngle)
176177 {
177- using AsUint = typename unsigned_integer_of_size<sizeof (scalar_type)>::type;
178178 const AsUint negationMask = hlsl::bit_cast<AsUint>(totalPseudoAngle) & AsUint (0x80000000u);
179179 const data_type adjEnd = hlsl::bit_cast<scalar_type>(hlsl::bit_cast<AsUint>(end.data) ^ negationMask);
180180
@@ -208,6 +208,13 @@ struct quaternion
208208 return retval;
209209 }
210210
211+ vector3_type transformVector (const vector3_type v)
212+ {
213+ scalar_type scale = hlsl::length (data);
214+ vector3_type direction = data.xyz;
215+ return v * scale + hlsl::cross (direction, v * data.w + hlsl::cross (direction, v)) * scalar_type (2.0 );
216+ }
217+
211218 matrix_type constructMatrix ()
212219 {
213220 matrix_type mat;
@@ -235,13 +242,53 @@ struct quaternion
235242 return precompPart * cosAngle + hlsl::cross (planeNormal, precompPart);
236243 }
237244
245+ this_t inverse ()
246+ {
247+ this_t retval;
248+ retval.data.x = bit_cast<scalar_type>(bit_cast<AsUint>(data.x)^0x80000000u);
249+ retval.data.y = bit_cast<scalar_type>(bit_cast<AsUint>(data.y)^0x80000000u);
250+ retval.data.z = bit_cast<scalar_type>(bit_cast<AsUint>(data.z)^0x80000000u);
251+ retval.data.w = data.w;
252+ return retval;
253+ }
254+
255+ static this_t normalize (NBL_CONST_REF_ARG (this_t) q)
256+ {
257+ this_t retval;
258+ retval.data = hlsl::normalize (q.data);
259+ return retval;
260+ }
261+
238262 data_type data;
239263};
240264
241265}
242266
243267namespace impl
244268{
269+
270+ template<typename T>
271+ struct static_cast_helper<math::quaternion<T>, math::truncated_quaternion<T> >
272+ {
273+ static inline math::quaternion<T> cast (math::truncated_quaternion<T> q)
274+ {
275+ return math::quaternion<T>::create (q);
276+ }
277+ };
278+
279+ template<typename T>
280+ struct static_cast_helper<math::truncated_quaternion<T>, math::quaternion<T> >
281+ {
282+ static inline math::truncated_quaternion<T> cast (math::quaternion<T> q)
283+ {
284+ math::truncated_quaternion<T> t;
285+ t.data.x = t.data.x;
286+ t.data.y = t.data.y;
287+ t.data.z = t.data.z;
288+ return t;
289+ }
290+ };
291+
245292template<typename T>
246293struct static_cast_helper<matrix <T,3 ,3 >, math::quaternion<T> >
247294{
0 commit comments