Foundation
Loading...
Searching...
No Matches
Quaternion.hpp
Go to the documentation of this file.
1#pragma once
2#include "Math.hpp"
3namespace Foundation::Math
4{
5 // Packs quaternion to [UNORM XYZ, 2-bit max index]
6 inline float4 packQuaternionXYZPositionBit(quat const& q)
7 {
8 float4 Q(q.x, q.y, q.z, q.w);
9 float4 absQ(abs(Q.x), abs(Q.y), abs(Q.z), abs(Q.w));
10 float absMax = max(max(absQ.x, absQ.y), max(absQ.z, absQ.w));
11 uint maxIndex = 0;
12 if (absQ[0] == absMax)
13 maxIndex = 0;
14 if (absQ[1] == absMax)
15 maxIndex = 1;
16 if (absQ[2] == absMax)
17 maxIndex = 2;
18 if (absQ[3] == absMax)
19 maxIndex = 3;
20 if (Q[maxIndex] < 0) // ensure positive
21 Q = -Q;
22 float3 packed;
23 if (maxIndex == 0)
24 packed = Q.yzw();
25 if (maxIndex == 1)
26 packed = Q.xzw();
27 if (maxIndex == 2)
28 packed = Q.xyw();
29 else /* maxIndex == 3 */
30 packed = Q.xyz();
31 packed *= sqrt(2.0f); // e.g. (1,0,0,1), max bounds
32 packed = packed * 0.5f + 0.5f; // [-1,1] -> [0,1]
33 return float4(packed, maxIndex / 3.0f);
34 }
35
36 // Unpacks quaternion from [UNORM XYZ, 2-bit max index] to quat
37 inline quat unpackQuaternionXYZPositionBit(float4 const& packed)
38 {
39 uint maxIndex = packed.w * 3.0f;
40 float3 p = packed.xyz() * 2.0f - 1.0f; // [0,1] -> [-1,1]
41 p /= sqrt(2.0f);
42 float4 Q;
43 float maxValue = sqrt(max(.0f, 1 - p.x * p.x - p.y * p.y - p.z * p.z));
44 if (maxIndex == 0)
45 Q = float4(maxValue, p.xyz);
46 else if (maxIndex == 1)
47 Q = float4(p.x, maxValue, p.yz);
48 else if (maxIndex == 2)
49 Q = float4(p.xy, maxValue, p.z);
50 else /* maxIndex == 3 */
51 Q = float4(p.xyz, maxValue);
52 return quat(Q.x, Q.y, Q.z, Q.w);
53 }
54} // namespace Foundation::Math
Definition Decompose.hpp:4
quat unpackQuaternionXYZPositionBit(float4 const &packed)
Definition Quaternion.hpp:37
vec3 float3
Definition Math.hpp:26
float4 packQuaternionXYZPositionBit(quat const &q)
Definition Quaternion.hpp:6
vec4 float4
Definition Math.hpp:25