Blender V4.3
BLI_math_quaternion_types.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
11#include <ostream>
12
14#include "BLI_math_base.hh"
19
20namespace blender::math {
21
22/* -------------------------------------------------------------------- */
37template<typename T> struct QuaternionBase {
38 T w, x, y, z;
39
40 QuaternionBase() = default;
41
42 QuaternionBase(const T &new_w, const T &new_x, const T &new_y, const T &new_z)
43 : w(new_w), x(new_x), y(new_y), z(new_z){};
44
49 explicit QuaternionBase(const VecBase<T, 4> &vec) : QuaternionBase(UNPACK4(vec)){};
50
54 QuaternionBase(const T &real, const VecBase<T, 3> &imaginary)
55 : QuaternionBase(real, UNPACK3(imaginary)){};
56
60 {
61 return {1, 0, 0, 0};
62 }
63
66 {
67 return {0, 0, 0, 0};
68 }
69
75
78 explicit operator VecBase<T, 4>() const
79 {
80 return {this->w, this->x, this->y, this->z};
81 }
82
87 VecBase<T, 3> expmap() const;
88
93 AngleRadianBase<T> twist_angle(const Axis axis) const;
94
99 QuaternionBase twist(const Axis axis) const;
100
106 QuaternionBase swing(const Axis axis) const;
107
112 {
113 return *reinterpret_cast<const VecBase<T, 3> *>(&x);
114 }
116 {
117 return *reinterpret_cast<VecBase<T, 3> *>(&x);
118 }
119
131 QuaternionBase wrapped_around(const QuaternionBase &reference) const;
132
136 {
137 return {a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
138 a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
139 a.w * b.y + a.y * b.w + a.z * b.x - a.x * b.z,
140 a.w * b.z + a.z * b.w + a.x * b.y - a.y * b.x};
141 }
142
144 {
145 *this = *this * b;
146 return *this;
147 }
148
149 /* Scalar product. */
150 friend QuaternionBase operator*(const QuaternionBase &a, const T &b)
151 {
152 return {a.w * b, a.x * b, a.y * b, a.z * b};
153 }
154
155 /* Negate the quaternion. */
157 {
158 return {-a.w, -a.x, -a.y, -a.z};
159 }
160
162
164 {
165 return VecBase<T, 4>(*this).hash();
166 }
167
168 friend std::ostream &operator<<(std::ostream &stream, const QuaternionBase &rot)
169 {
170 return stream << "Quaternion" << static_cast<VecBase<T, 4>>(rot);
171 }
172};
173
176/* -------------------------------------------------------------------- */
188template<typename T> struct DualQuaternionBase {
193
198 /* TODO(fclem): Can this be replaced by a Mat3x3 ?
199 * It currently holds some translation in some cases. Is this wanted?
200 * This would save some flops all along the way. */
209
211
215 DualQuaternionBase(const QuaternionBase<T> &non_dual, const QuaternionBase<T> &dual);
216
221 const QuaternionBase<T> &dual,
222 const MatBase<T, 4, 4> &scale_mat);
223
230
236 DualQuaternionBase &operator*=(const T &t);
237
240
243 {
244 DualQuaternionBase dq = a;
245 dq *= t;
246 return dq;
247 }
248
251 {
252 DualQuaternionBase dq = a;
253 dq *= t;
254 return dq;
255 }
256
259 {
260 DualQuaternionBase dq = a;
261 dq += b;
262 return dq;
263 }
264
267
268 friend std::ostream &operator<<(std::ostream &stream, const DualQuaternionBase &rot)
269 {
270 stream << "DualQuaternion(\n";
271 stream << " .quat = " << rot.quat << "\n";
272 stream << " .trans = " << rot.trans << "\n";
273 if (rot.scale_weight != T(0)) {
274 stream << " .scale = " << rot.scale;
275 stream << " .scale_weight = " << rot.scale_weight << "\n";
276 }
277 stream << " .quat_weight = " << rot.quat_weight << "\n)\n";
278 return stream;
279 }
280};
281
286template<typename T> [[nodiscard]] inline bool is_normalized(const DualQuaternionBase<T> &dq)
287{
288 return dq.quat_weight == T(1);
289}
290
293/* -------------------------------------------------------------------- */
297template<typename U> struct AssertUnitEpsilon<QuaternionBase<U>> {
298 static constexpr U value = AssertUnitEpsilon<U>::value * 10;
299};
300
303/* -------------------------------------------------------------------- */
309template<typename T> struct TypeTraits {
311};
312template<> struct TypeTraits<float> {
314};
315
318
321} // namespace blender::math
#define BLI_STRUCT_EQUALITY_OPERATORS_4(Type, m1, m2, m3, m4)
#define UNPACK4(a)
#define UNPACK3(a)
typedef double(DMatrix)[4][4]
unsigned int U
Definition btGjkEpa3.h:78
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
#define rot(x, k)
#define T
bool is_normalized(const DualQuaternionBase< T > &dq)
std::ostream & operator<<(std::ostream &stream, EulerOrder order)
unsigned __int64 uint64_t
Definition stdint.h:90
friend DualQuaternionBase operator*(const DualQuaternionBase &a, const T &t)
DualQuaternionBase & operator*=(const T &t)
DualQuaternionBase & operator+=(const DualQuaternionBase &b)
friend DualQuaternionBase operator+(const DualQuaternionBase &a, const DualQuaternionBase &b)
friend DualQuaternionBase operator*(const T &t, const DualQuaternionBase &a)
BLI_STRUCT_EQUALITY_OPERATORS_5(DualQuaternionBase, quat, trans, quat_weight, scale_weight, scale) friend std
friend QuaternionBase operator*(const QuaternionBase &a, const T &b)
const VecBase< T, 3 > & imaginary_part() const
QuaternionBase swing(const Axis axis) const
AngleRadianBase< T > twist_angle(const Axis axis) const
friend std::ostream & operator<<(std::ostream &stream, const QuaternionBase &rot)
QuaternionBase(const T &real, const VecBase< T, 3 > &imaginary)
QuaternionBase(const T &new_w, const T &new_x, const T &new_y, const T &new_z)
friend QuaternionBase operator*(const QuaternionBase &a, const QuaternionBase &b)
QuaternionBase twist(const Axis axis) const
QuaternionBase wrapped_around(const QuaternionBase &reference) const
QuaternionBase(const VecBase< T, 4 > &vec)
QuaternionBase & operator*=(const QuaternionBase &b)
friend QuaternionBase operator-(const QuaternionBase &a)