Skip to content

Commit 9be65a0

Browse files
committed
changed quaternion struct name, brought in quaternion stuff from przemek's remove_core_matrix branch, added create from mat3x3
1 parent 8a6939f commit 9be65a0

File tree

3 files changed

+147
-17
lines changed

3 files changed

+147
-17
lines changed

include/nbl/builtin/hlsl/math/quaternions.hlsl

Lines changed: 134 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,152 @@ namespace hlsl
1414
namespace math
1515
{
1616

17+
template<typename T>
18+
struct truncated_quaternion
19+
{
20+
using this_t = truncated_quaternion<T>;
21+
using scalar_type = T;
22+
using data_type = vector<T, 3>;
23+
24+
static this_t create()
25+
{
26+
this_t q;
27+
q.data = data_type(0.0, 0.0, 0.0);
28+
return q;
29+
}
30+
31+
data_type data;
32+
};
33+
1734
template <typename T>
18-
struct quaternion_t
35+
struct quaternion
1936
{
20-
using this_t = quaternion_t<T>;
37+
using this_t = quaternion<T>;
2138
using scalar_type = T;
2239
using data_type = vector<T, 4>;
2340
using vector3_type = vector<T, 3>;
2441
using matrix_type = matrix<T, 3, 3>;
2542

26-
static this_t createFromTruncated(const vector3_type first3Components)
43+
static this_t create()
44+
{
45+
this_t q;
46+
q.data = data_type(0.0, 0.0, 0.0, 1.0);
47+
return q;
48+
}
49+
50+
static this_t create(scalar_type x, scalar_type y, scalar_type z, scalar_type w)
51+
{
52+
this_t q;
53+
q.data = data_type(x, y, z, w);
54+
return q;
55+
}
56+
57+
static this_t create(NBL_CONST_REF_ARG(this_t) other)
58+
{
59+
return other;
60+
}
61+
62+
static this_t create(scalar_type pitch, scalar_type yaw, scalar_type roll)
63+
{
64+
const scalar_type rollDiv2 = roll * scalar_type(0.5);
65+
const scalar_type sr = hlsl::sin(rollDiv2);
66+
const scalar_type cr = hlsl::cos(rollDiv2);
67+
68+
const scalar_type pitchDiv2 = pitch * scalar_type(0.5);
69+
const scalar_type sp = hlsl::sin(pitchDiv2);
70+
const scalar_type cp = hlsl::cos(pitchDiv2);
71+
72+
const scalar_type yawDiv2 = yaw * scalar_type(0.5);
73+
const scalar_type sy = hlsl::sin(yawDiv2);
74+
const scalar_type cy = hlsl::cos(yawDiv2);
75+
76+
this_t output;
77+
output.data[0] = cr * sp * cy + sr * cp * sy; // x
78+
output.data[1] = cr * cp * sy - sr * sp * cy; // y
79+
output.data[2] = sr * cp * cy - cr * sp * sy; // z
80+
output.data[3] = cr * cp * cy + sr * sp * sy; // w
81+
82+
return output;
83+
}
84+
85+
static this_t create(NBL_CONST_REF_ARG(matrix_type) m)
86+
{
87+
using AsUint = typename unsigned_integer_of_size<sizeof(scalar_type)>::type;
88+
const scalar_type m00 = m[0][0], m11 = m[1][1], m22 = m[2][2];
89+
const scalar_type neg_m00 = bit_cast<scalar_type>(bit_cast<AsUint>(m00)^0x80000000u);
90+
const scalar_type neg_m11 = bit_cast<scalar_type>(bit_cast<AsUint>(m11)^0x80000000u);
91+
const scalar_type neg_m22 = bit_cast<scalar_type>(bit_cast<AsUint>(m22)^0x80000000u);
92+
const data_type Qx = data_type(m00, m00, neg_m00, neg_m00);
93+
const data_type Qy = data_type(m11, neg_m11, m11, neg_m11);
94+
const data_type Qz = data_type(m22, neg_m22, neg_m22, m22);
95+
96+
const data_type tmp = hlsl::promote<data_type>(1.0) + Qx + Qy + Qz;
97+
const data_type invscales = hlsl::promote<data_type>(0.5) / hlsl::sqrt(tmp);
98+
const data_type scales = tmp * invscales * hlsl::promote<data_type>(0.5);
99+
100+
// TODO: speed this up
101+
this_t retval;
102+
if (tmp.x > scalar_type(0.0))
103+
{
104+
retval.data.x = (m[2][1] - m[1][2]) * invscales.x;
105+
retval.data.y = (m[0][2] - m[2][0]) * invscales.x;
106+
retval.data.z = (m[1][0] - m[0][1]) * invscales.x;
107+
retval.data.w = scales.x;
108+
}
109+
else
110+
{
111+
if (tmp.y > scalar_type(0.0))
112+
{
113+
retval.data.x = scales.y;
114+
retval.data.y = (m[0][1] + m[1][0]) * invscales.y;
115+
retval.data.z = (m[2][0] + m[0][2]) * invscales.y;
116+
retval.data.w = (m[2][1] - m[1][2]) * invscales.y;
117+
}
118+
else if (tmp.z > scalar_type(0.0))
119+
{
120+
retval.data.x = (m[0][1] + m[1][0]) * invscales.z;
121+
retval.data.y = scales.z;
122+
retval.data.z = (m[0][2] - m[2][0]) * invscales.z;
123+
retval.data.w = (m[1][2] + m[2][1]) * invscales.z;
124+
}
125+
else
126+
{
127+
retval.data.x = (m[0][2] + m[2][0]) * invscales.w;
128+
retval.data.y = (m[1][2] + m[2][1]) * invscales.w;
129+
retval.data.z = scales.w;
130+
retval.data.w = (m[1][0] - m[0][1]) * invscales.w;
131+
}
132+
}
133+
134+
retval.data = hlsl::normalize(retval.data);
135+
return retval;
136+
}
137+
138+
static this_t createFromTruncated(NBL_CONST_REF_ARG(truncated_quaternion<T>) first3Components)
27139
{
28140
this_t retval;
29-
retval.data.xyz = first3Components;
30-
retval.data.w = hlsl::sqrt(scalar_type(1.0) - hlsl::dot(first3Components, first3Components));
141+
retval.data.xyz = first3Components.data;
142+
retval.data.w = hlsl::sqrt(scalar_type(1.0) - hlsl::dot(first3Components.data, first3Components.data));
31143
return retval;
32144
}
33145

146+
this_t operator*(scalar_type scalar)
147+
{
148+
this_t output;
149+
output.data = data * scalar;
150+
return output;
151+
}
152+
153+
this_t operator*(NBL_CONST_REF_ARG(this_t) other)
154+
{
155+
return this_t::create(
156+
data.w * other.data.w - data.x * other.x - data.y * other.data.y - data.z * other.data.z,
157+
data.w * other.data.x + data.x * other.w + data.y * other.data.z - data.z * other.data.y,
158+
data.w * other.data.y - data.x * other.z + data.y * other.data.w + data.z * other.data.x,
159+
data.w * other.data.z + data.x * other.y - data.y * other.data.x + data.z * other.data.w
160+
);
161+
}
162+
34163
static this_t lerp(const this_t start, const this_t end, const scalar_type fraction, const scalar_type totalPseudoAngle)
35164
{
36165
using AsUint = typename unsigned_integer_of_size<sizeof(scalar_type)>::type;

include/nbl/builtin/hlsl/matrix_utils/transformation_matrix_utils.hlsl

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define _NBL_BUILTIN_HLSL_TRANSFORMATION_MATRIX_UTILS_INCLUDED_
33

44
#include <nbl/builtin/hlsl/cpp_compat.hlsl>
5+
#include <nbl/builtin/hlsl/math/quaternions.hlsl>
56

67
namespace nbl
78
{
@@ -125,28 +126,28 @@ inline matrix<T, 3, 4> buildCameraLookAtMatrixRH(
125126

126127
//! Replaces curent rocation and scale by rotation represented by quaternion `quat`, leaves 4th row and 4th colum unchanged
127128
template<typename T, uint32_t N>
128-
inline void setRotation(matrix<T, N, 4>& outMat, NBL_CONST_REF_ARG(core::quaternion) quat)
129+
inline void setRotation(matrix<T, N, 4>& outMat, NBL_CONST_REF_ARG(math::quaternion<T>) quat)
129130
{
130131
static_assert(N == 3 || N == 4);
131132

132133
outMat[0] = vector<T, 4>(
133-
1 - 2 * (quat.y * quat.y + quat.z * quat.z),
134-
2 * (quat.x * quat.y - quat.z * quat.w),
135-
2 * (quat.x * quat.z + quat.y * quat.w),
134+
1 - 2 * (quat.data.y * quat.data.y + quat.data.z * quat.data.z),
135+
2 * (quat.data.x * quat.data.y - quat.data.z * quat.data.w),
136+
2 * (quat.data.x * quat.data.z + quat.data.y * quat.data.w),
136137
outMat[0][3]
137138
);
138139

139140
outMat[1] = vector<T, 4>(
140-
2 * (quat.x * quat.y + quat.z * quat.w),
141-
1 - 2 * (quat.x * quat.x + quat.z * quat.z),
142-
2 * (quat.y * quat.z - quat.x * quat.w),
141+
2 * (quat.data.x * quat.data.y + quat.data.z * quat.data.w),
142+
1 - 2 * (quat.data.x * quat.data.x + quat.data.z * quat.data.z),
143+
2 * (quat.data.y * quat.data.z - quat.data.x * quat.data.w),
143144
outMat[1][3]
144145
);
145146

146147
outMat[2] = vector<T, 4>(
147-
2 * (quat.x * quat.z - quat.y * quat.w),
148-
2 * (quat.y * quat.z + quat.x * quat.w),
149-
1 - 2 * (quat.x * quat.x + quat.y * quat.y),
148+
2 * (quat.data.x * quat.data.z - quat.data.y * quat.data.w),
149+
2 * (quat.data.y * quat.data.z + quat.data.x * quat.data.w),
150+
1 - 2 * (quat.data.x * quat.data.x + quat.data.y * quat.data.y),
150151
outMat[2][3]
151152
);
152153
}

include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct SphericalTriangle
5151
{
5252
const scalar_type cosAngleAlongAC = ((v_ * q - u_ * p) * cos_vertices[0] - v_) / ((v_ * p + u_ * q) * sin_vertices[0]);
5353
if (nbl::hlsl::abs(cosAngleAlongAC) < 1.f)
54-
C_s += math::quaternion_t<scalar_type>::slerp_delta(tri.vertex0, tri.vertex2 * csc_b, cosAngleAlongAC);
54+
C_s += math::quaternion<scalar_type>::slerp_delta(tri.vertex0, tri.vertex2 * csc_b, cosAngleAlongAC);
5555
}
5656

5757
vector3_type retval = tri.vertex1;
@@ -61,7 +61,7 @@ struct SphericalTriangle
6161
{
6262
const scalar_type cosAngleAlongBC_s = nbl::hlsl::clamp(1.0 + cosBC_s * u.y - u.y, -1.f, 1.f);
6363
if (nbl::hlsl::abs(cosAngleAlongBC_s) < 1.f)
64-
retval += math::quaternion_t<scalar_type>::slerp_delta(tri.vertex1, C_s * csc_b_s, cosAngleAlongBC_s);
64+
retval += math::quaternion<scalar_type>::slerp_delta(tri.vertex1, C_s * csc_b_s, cosAngleAlongBC_s);
6565
}
6666
return retval;
6767
}

0 commit comments

Comments
 (0)