opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
transform_functions.h
Go to the documentation of this file.
1#pragma once
2
15
16#include <stdexcept>
17
18namespace osc
19{
20 // returns a 3x3 transform matrix equivalent to the provided transform (ignores position)
21 constexpr Matrix3x3 matrix3x3_cast(const Transform& transform)
22 {
24
25 rv[0][0] *= transform.scale.x();
26 rv[0][1] *= transform.scale.x();
27 rv[0][2] *= transform.scale.x();
28
29 rv[1][0] *= transform.scale.y();
30 rv[1][1] *= transform.scale.y();
31 rv[1][2] *= transform.scale.y();
32
33 rv[2][0] *= transform.scale.z();
34 rv[2][1] *= transform.scale.z();
35 rv[2][2] *= transform.scale.z();
36
37 return rv;
38 }
39
40 // returns a 4x4 transform matrix equivalent to the provided transform
41 constexpr Matrix4x4 matrix4x4_cast(const Transform& transform)
42 {
44
45 rv[0][0] *= transform.scale.x();
46 rv[0][1] *= transform.scale.x();
47 rv[0][2] *= transform.scale.x();
48
49 rv[1][0] *= transform.scale.y();
50 rv[1][1] *= transform.scale.y();
51 rv[1][2] *= transform.scale.y();
52
53 rv[2][0] *= transform.scale.z();
54 rv[2][1] *= transform.scale.z();
55 rv[2][2] *= transform.scale.z();
56
57 rv[3][0] = transform.translation.x();
58 rv[3][1] = transform.translation.y();
59 rv[3][2] = transform.translation.z();
60
61 return rv;
62 }
63
64 // returns a 4x4 transform matrix equivalent to the inverse of the provided transform
66 {
69 const Matrix4x4 scaler = scale(identity<Matrix4x4>(), 1.0f/transform.scale);
70
71 return scaler * rotator * translator;
72 }
73
74 // returns a 3x3 normal matrix for the provided transform
75 constexpr Matrix3x3 normal_matrix(const Transform& transform)
76 {
77 return adjugate(transpose(matrix3x3_cast(transform)));
78 }
79
80 // returns a 4x4 normal matrix for the provided transform
81 constexpr Matrix4x4 normal_matrix_4x4(const Transform& transform)
82 {
83 return adjugate(transpose(matrix3x3_cast(transform)));
84 }
85
86 // returns `true` if `out` was updated with the decomposition of `m`
87 //
88 // - not all 4x4 matrices can be expressed as an `Transform` (e.g. those containing skews)
89 // - uses matrix decomposition to break up the provided matrix
91 {
94 return decompose(m, out.scale, out.rotation, out.translation, skew, perspective);
95 }
96
97 // returns a transform that *tries to* perform the equivalent transform as the provided `Matrix4x4`
98 //
99 // - not all 4x4 matrices can be expressed as an `Transform` (e.g. those containing skews)
100 // - uses matrix decomposition to break up the provided matrix
101 // - throws if decomposition of the provided matrix is not possible
103 {
105 if (not try_decompose_to_transform(m, rv)) {
106 throw std::runtime_error{"failed to decompose a matrix into scale, rotation, etc."};
107 }
108 return rv;
109 }
110
111 // Returns a vector that is the equivalent of applying `transform` to it, but ignoring
112 // the `position` (translation) component (i.e. vector transformation, as opposed
113 // to point transformation).
114 inline Vector3 transform_vector(const Transform& transform, const Vector3& vector)
115 {
116 return transform.rotation * (transform.scale * vector);
117 }
118
119 // Returns a vector that is the equivalent of applying the inverse of `transform`
120 // to it, but ignoring the `position` (translation) component (i.e. vector transformation,
121 // as opposed to point transformation).
122 inline Vector3 inverse_transform_vector(const Transform& transform, const Vector3& vector)
123 {
124 return (conjugate(transform.rotation) * vector) / transform.scale;
125 }
126
127 // returns a vector that is the equivalent of the provided vector after applying the transform
128 constexpr Vector3 transform_point(const Transform& transform, const Vector3& point)
129 {
130 return transform * point;
131 }
132
133 // returns a vector that is the equivalent of the provided vector after applying the inverse of the transform
134 constexpr Vector3 inverse_transform_point(const Transform& transform, Vector3 point)
135 {
136 point -= transform.translation;
137 point = conjugate(transform.rotation) * point;
138 point /= transform.scale;
139 return point;
140 }
141
142 // returns XYZ (pitch, yaw, roll) Euler angles for a one-by-one application of an
143 // intrinsic rotations.
144 //
145 // Each rotation is applied one-at-a-time, to the transformed space, so we have:
146 //
147 // x-y-z (initial)
148 // x'-y'-z' (after first rotation)
149 // x''-y''-z'' (after second rotation)
150 // x'''-y'''-z''' (after third rotation)
151 //
152 // Assuming we're doing an XYZ rotation, the first rotation rotates x, the second
153 // rotation rotates around y', and the third rotation rotates around z''
154 //
155 // see: https://en.wikipedia.org/wiki/Euler_angles#Conventions_by_intrinsic_rotations
156 inline EulerAngles extract_eulers_xyz(const Transform& transform)
157 {
158 return extract_eulers_xyz(matrix4x4_cast(transform.rotation));
159 }
160
161 // returns XYZ (pitch, yaw, roll) Euler angles for an extrinsic rotation
162 //
163 // in extrinsic rotations, each rotation happens about a *fixed* coordinate system, which
164 // is in contrast to intrinsic rotations, which happen in a coordinate system that's attached
165 // to a moving body (the thing being rotated)
166 //
167 // see: https://en.wikipedia.org/wiki/Euler_angles#Conventions_by_extrinsic_rotations
169 {
170 return to_euler_angles(transform.rotation);
171 }
172
173 // returns the provided transform, but rotated such that the given axis, as expressed
174 // in the original transform, will instead point along the new direction
189
190 // returns the provided transform, but rotated such that the given axis, as expressed
191 // in the original transform, will instead point towards the given point
192 //
193 // alternate explanation: "performs the shortest (angular) rotation of the given
194 // transform such that the given axis points towards a point in the same space"
196 const Transform& transform,
198 const Vector3& position)
199 {
200 return point_axis_along(transform, axis_index, normalize(position - transform.translation));
201 }
202
203 // returns the provided transform, but intrinsically rotated along the given axis by
204 // the given number of radians
206 const Transform& transform,
209 {
210 Vector3 ax{};
211 ax[axis_index] = 1.0f;
212 ax = transform.rotation * ax;
213
214 const Quaternion q = angle_axis(angle, ax);
215
216 return transform.with_rotation(normalize(q * transform.rotation));
217 }
218
219 // returns `true` if any element in `transform`'s `scale`, `rotation`, or
220 // `position` is NaN.
221 inline bool any_element_is_nan(const Transform& transform)
222 {
223 return any_of(isnan(transform.scale)) or any_of(isnan(transform.rotation)) or any_of(isnan(transform.translation));
224 }
225}
Definition angle.h:25
constexpr reference x()
Returns (*this)[0]
Definition vector.h:157
constexpr reference z()
Returns (*this)[2]
Definition vector.h:167
constexpr reference y()
Returns (*this)[1]
Definition vector.h:162
size_t size_type
Definition vector.h:66
Definition custom_decoration_generator.h:5
EulerAngles extract_eulers_xyz(const Quaternion &)
Transform point_axis_towards(const Transform &transform, Vector3::size_type axis_index, const Vector3 &position)
Definition transform_functions.h:195
constexpr Matrix< T, 3, 3 > adjugate(const Matrix< T, 3, 3 > &m)
Definition matrix_functions.h:481
constexpr Matrix4x4 normal_matrix_4x4(const Transform &transform)
Definition transform_functions.h:81
constexpr Matrix< T, 4, 4 > matrix4x4_cast(const Qua< T > &q)
Definition quaternion_functions.h:149
EulerAngles extract_extrinsic_eulers_xyz(const Transform &transform)
Definition transform_functions.h:168
Matrix< T, 4, 4 > translate(const Matrix< T, 4, 4 > &m, const Vector< T, 3 > &v)
Definition matrix_functions.h:118
Transform decompose_to_transform(const Matrix4x4 &m)
Definition transform_functions.h:102
Vector< RadiansT< T >, 3 > to_euler_angles(const Qua< T > &x)
Definition quaternion_functions.h:260
Vector3 transform_point(const Matrix4x4 &mat, const Vector3 &point)
Definition math_helpers.h:140
Transform point_axis_along(const Transform &transform, Vector3::size_type axis_index, const Vector3 &new_direction)
Definition transform_functions.h:175
Vector3 transform_vector(const Matrix4x4 &mat, const Vector3 &vector)
Definition math_helpers.h:145
constexpr Matrix< T, 3, 3 > matrix3x3_cast(const Qua< T > &q)
Definition quaternion_functions.h:119
Matrix< T, 4, 4 > perspective(Angle< T, Units > vertical_field_of_view, T aspect, T z_near, T z_far)
Definition matrix_functions.h:44
bool try_decompose_to_transform(const Matrix4x4 &m, Transform &out)
Definition transform_functions.h:90
bool any_element_is_nan(const Transform &transform)
Definition transform_functions.h:221
Qua< T > rotation(const Vector< T, 3 > &origin, const Vector< T, 3 > &destination)
Definition quaternion_functions.h:187
Vector3 inverse_transform_vector(const Transform &transform, const Vector3 &vector)
Definition transform_functions.h:122
constexpr U to(T &&value)
Definition conversion.h:56
Matrix< T, 3, 3 > normal_matrix(const Matrix< T, 4, 4 > &m)
Definition matrix_functions.h:502
constexpr Qua< T > conjugate(const Qua< T > &q)
Definition quaternion_functions.h:28
Vector< T, N > normalize(const Vector< T, N > &v)
Definition geometric_functions.h:74
bool isnan(T num)
Definition common_functions.h:319
Qua< T > angle_axis(Angle< T, Units > angle, VectorLike &&axis)
Definition quaternion_functions.h:170
constexpr bool any_of(const Vector< bool, N > &v)
Definition functors.h:56
Matrix4x4 inverse_matrix4x4_cast(const Transform &transform)
Definition transform_functions.h:65
constexpr Matrix4x4 identity< Matrix4x4 >()
Definition matrix4x4.h:390
Matrix< T, 4, 4 > scale(const Matrix< T, 4, 4 > &m, const Vector< T, 3 > &v)
Definition matrix_functions.h:78
Transform rotate_axis(const Transform &transform, Vector3::size_type axis_index, Radians angle)
Definition transform_functions.h:205
constexpr Matrix< T, 3, 3 > transpose(const Matrix< T, 3, 3 > &m)
Definition matrix_functions.h:234
bool decompose(const Matrix< T, 4, 4 > &model_matrix, Vector< T, 3 > &r_scale, Qua< T > &r_orientation, Vector< T, 3 > &r_translation, Vector< T, 3 > &r_skew, Vector< T, 4 > &r_perspective)
Definition matrix_functions.h:308
constexpr Vector3 inverse_transform_point(const Transform &transform, Vector3 point)
Definition transform_functions.h:134
Definition matrix.h:15
Definition transform.h:11
Vector3 translation
Definition transform.h:37
constexpr Transform with_rotation(const Quaternion &new_rotation) const
Definition transform.h:18
Quaternion rotation
Definition transform.h:36
Vector3 scale
Definition transform.h:35