Blender  V3.3
BLI_float4x4.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
5 #include "BLI_math_matrix.h"
6 #include "BLI_math_vec_types.hh"
7 #include "BLI_math_vector.h"
8 #include "BLI_math_vector.hh"
9 
10 namespace blender {
11 
12 struct float4x4 {
13  float values[4][4];
14 
15  float4x4() = default;
16 
17  float4x4(const float *matrix)
18  {
19  memcpy(values, matrix, sizeof(float) * 16);
20  }
21 
22  float4x4(const float matrix[4][4]) : float4x4(static_cast<const float *>(matrix[0]))
23  {
24  }
25 
26  /* Assumes an XYZ euler order. */
27  static float4x4 from_loc_eul_scale(const float3 location,
28  const float3 rotation,
29  const float3 scale)
30  {
31  float4x4 mat;
32  loc_eul_size_to_mat4(mat.values, location, rotation, scale);
33  return mat;
34  }
35 
36  static float4x4 from_location(const float3 location)
37  {
39  copy_v3_v3(mat.values[3], location);
40  return mat;
41  }
42 
43  static float4x4 from_normalized_axis_data(const float3 location,
44  const float3 forward,
45  const float3 up)
46  {
47  BLI_ASSERT_UNIT_V3(forward);
49 
50  /* Negate the cross product so that the resulting matrix has determinant 1 (instead of -1).
51  * Without the negation, the result would be a so called improper rotation. That means it
52  * contains a reflection. Such an improper rotation matrix could not be converted to another
53  * representation of a rotation such as euler angles. */
54  const float3 cross = -math::cross(forward, up);
55 
56  float4x4 matrix;
57  matrix.values[0][0] = forward.x;
58  matrix.values[1][0] = cross.x;
59  matrix.values[2][0] = up.x;
60  matrix.values[3][0] = location.x;
61 
62  matrix.values[0][1] = forward.y;
63  matrix.values[1][1] = cross.y;
64  matrix.values[2][1] = up.y;
65  matrix.values[3][1] = location.y;
66 
67  matrix.values[0][2] = forward.z;
68  matrix.values[1][2] = cross.z;
69  matrix.values[2][2] = up.z;
70  matrix.values[3][2] = location.z;
71 
72  matrix.values[0][3] = 0.0f;
73  matrix.values[1][3] = 0.0f;
74  matrix.values[2][3] = 0.0f;
75  matrix.values[3][3] = 1.0f;
76 
77  return matrix;
78  }
79 
80  static float4x4 identity()
81  {
82  float4x4 mat;
83  unit_m4(mat.values);
84  return mat;
85  }
86 
87  operator float *()
88  {
89  return &values[0][0];
90  }
91 
92  operator const float *() const
93  {
94  return &values[0][0];
95  }
96 
97  float *operator[](const int64_t index)
98  {
99  BLI_assert(index >= 0);
100  BLI_assert(index < 4);
101  return &values[index][0];
102  }
103 
104  const float *operator[](const int64_t index) const
105  {
106  BLI_assert(index >= 0);
107  BLI_assert(index < 4);
108  return &values[index][0];
109  }
110 
111  using c_style_float4x4 = float[4][4];
113  {
114  return values;
115  }
116 
117  const c_style_float4x4 &ptr() const
118  {
119  return values;
120  }
121 
122  friend float4x4 operator*(const float4x4 &a, const float4x4 &b)
123  {
125  mul_m4_m4m4(result.values, a.values, b.values);
126  return result;
127  }
128 
129  void operator*=(const float4x4 &other)
130  {
131  mul_m4_m4_post(values, other.values);
132  }
133 
138  friend float3 operator*(const float4x4 &m, const float3 &v)
139  {
140  float3 result;
141  mul_v3_m4v3(result, m.values, v);
142  return result;
143  }
144 
145  friend float3 operator*(const float4x4 &m, const float (*v)[3])
146  {
147  return m * float3(v);
148  }
149 
150  friend bool operator==(const float4x4 &a, const float4x4 &b)
151  {
152  return equals_m4m4(a.ptr(), b.ptr());
153  }
154 
155  friend bool operator!=(const float4x4 &a, const float4x4 &b)
156  {
157  return !(a == b);
158  }
159 
161  {
162  return float3(values[3]);
163  }
164 
165  /* Assumes XYZ rotation order. */
166  float3 to_euler() const
167  {
168  float3 euler;
169  mat4_to_eul(euler, values);
170  return euler;
171  }
172 
173  float3 scale() const
174  {
175  float3 scale;
177  return scale;
178  }
179 
180  void apply_scale(const float scale)
181  {
182  values[0][0] *= scale;
183  values[0][1] *= scale;
184  values[0][2] *= scale;
185  values[1][0] *= scale;
186  values[1][1] *= scale;
187  values[1][2] *= scale;
188  values[2][0] *= scale;
189  values[2][1] *= scale;
190  values[2][2] *= scale;
191  }
192 
194  {
196  invert_m4_m4(result.values, values);
197  return result;
198  }
199 
204  {
205  BLI_assert(values[0][3] == 0.0f && values[1][3] == 0.0f && values[2][3] == 0.0f &&
206  values[3][3] == 1.0f);
207  return this->inverted();
208  }
209 
211  {
213  transpose_m4_m4(result.values, values);
214  return result;
215  }
216 
218  {
219  return this->inverted_affine().transposed();
220  }
221 
222  struct float3x3_ref {
223  const float4x4 &data;
224 
225  friend float3 operator*(const float3x3_ref &m, const float3 &v)
226  {
227  float3 result;
229  return result;
230  }
231  };
232 
234  {
235  return {*this};
236  }
237 
238  static float4x4 interpolate(const float4x4 &a, const float4x4 &b, float t)
239  {
240  float result[4][4];
241  interp_m4_m4m4(result, a.values, b.values, t);
242  return result;
243  }
244 
245  bool is_negative() const
246  {
247  return is_negative_m4(ptr());
248  }
249 
250  uint64_t hash() const
251  {
252  uint64_t h = 435109;
253  for (int i = 0; i < 16; i++) {
254  float value = (static_cast<const float *>(values[0]))[i];
255  h = h * 33 + *reinterpret_cast<const uint32_t *>(&value);
256  }
257  return h;
258  }
259 
260  friend std::ostream &operator<<(std::ostream &stream, const float4x4 &mat)
261  {
262  char fchar[16];
263  stream << "(\n";
264  for (int i = 0; i < 4; i++) {
265  stream << "(";
266  for (int j = 0; j < 4; j++) {
267  snprintf(fchar, sizeof(fchar), "%11.6f", mat[j][i]);
268  stream << fchar;
269  if (i != 3) {
270  stream << ", ";
271  }
272  }
273  stream << ")\n";
274  }
275  stream << ")\n";
276  return stream;
277  }
278 };
279 
280 } // namespace blender
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_ASSERT_UNIT_V3(v)
void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], float t)
Definition: math_matrix.c:2481
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void transpose_m4_m4(float R[4][4], const float M[4][4])
Definition: math_matrix.c:1403
void unit_m4(float m[4][4])
Definition: rct.c:1090
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
Definition: math_matrix.c:2531
bool is_negative_m4(const float mat[4][4])
Definition: math_matrix.c:2509
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3])
Definition: math_matrix.c:2547
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2138
void mul_m4_m4_post(float R[4][4], const float B[4][4])
Definition: math_matrix.c:380
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:800
void mat4_to_eul(float eul[3], const float mat[4][4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define snprintf
Definition: BLI_winstuff.h:53
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
ATTR_WARN_UNUSED_RESULT const BMVert * v
static unsigned a[3]
Definition: RandGen.cpp:78
vec_base< T, 3 > cross(const vec_base< T, 3 > &a, const vec_base< T, 3 > &b)
vec_base< float, 3 > float3
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
unsigned int uint32_t
Definition: stdint.h:80
__int64 int64_t
Definition: stdint.h:89
unsigned __int64 uint64_t
Definition: stdint.h:90
friend float3 operator*(const float3x3_ref &m, const float3 &v)
float3 scale() const
c_style_float4x4 & ptr()
float4x4 inverted_transposed_affine() const
friend float3 operator*(const float4x4 &m, const float3 &v)
void apply_scale(const float scale)
friend bool operator==(const float4x4 &a, const float4x4 &b)
static float4x4 from_normalized_axis_data(const float3 location, const float3 forward, const float3 up)
Definition: BLI_float4x4.hh:43
float4x4 inverted_affine() const
static float4x4 from_loc_eul_scale(const float3 location, const float3 rotation, const float3 scale)
Definition: BLI_float4x4.hh:27
friend std::ostream & operator<<(std::ostream &stream, const float4x4 &mat)
float[4][4] c_style_float4x4
uint64_t hash() const
float values[4][4]
Definition: BLI_float4x4.hh:13
float4x4(const float matrix[4][4])
Definition: BLI_float4x4.hh:22
float4x4()=default
float * operator[](const int64_t index)
Definition: BLI_float4x4.hh:97
friend bool operator!=(const float4x4 &a, const float4x4 &b)
void operator*=(const float4x4 &other)
float3 translation() const
static float4x4 identity()
Definition: BLI_float4x4.hh:80
friend float4x4 operator*(const float4x4 &a, const float4x4 &b)
friend float3 operator*(const float4x4 &m, const float(*v)[3])
float4x4(const float *matrix)
Definition: BLI_float4x4.hh:17
static float4x4 from_location(const float3 location)
Definition: BLI_float4x4.hh:36
float4x4 inverted() const
static float4x4 interpolate(const float4x4 &a, const float4x4 &b, float t)
float3 to_euler() const
const float * operator[](const int64_t index) const
float3x3_ref ref_3x3() const
bool is_negative() const
const c_style_float4x4 & ptr() const
float4x4 transposed() const