Blender  V2.93
BCMath.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 #include "BLI_utildefines.h"
21 
22 #include "BCMath.h"
23 #include "BlenderContext.h"
24 
25 void BCQuat::rotate_to(Matrix &mat_to)
26 {
27  Quat qd;
28  Matrix matd;
29  Matrix mati;
30  Matrix mat_from;
31 
32  quat_to_mat4(mat_from, q);
33 
34  /* Calculate the difference matrix matd between mat_from and mat_to */
35  invert_m4_m4(mati, mat_from);
36  mul_m4_m4m4(matd, mati, mat_to);
37 
38  mat4_to_quat(qd, matd);
39 
40  mul_qt_qtqt(q, qd, q); /* rotate to the final rotation to mat_to */
41 }
42 
44 {
45  set_transform(mat.matrix);
46 }
47 
48 BCMatrix::BCMatrix(Matrix &mat)
49 {
50  set_transform(mat);
51 }
52 
54 {
55  set_transform(ob);
56 }
57 
59 {
60  unit();
61 }
62 
63 BCMatrix::BCMatrix(BC_global_forward_axis global_forward_axis, BC_global_up_axis global_up_axis)
64 {
65  float mrot[3][3];
66  float mat[4][4];
68  BC_DEFAULT_FORWARD, BC_DEFAULT_UP, global_forward_axis, global_up_axis, mrot);
69 
71  mrot); /* TODO: Verify that mat3_from_axis_conversion() returns a transposed matrix */
72  copy_m4_m3(mat, mrot);
73  set_transform(mat);
74 }
75 
76 void BCMatrix::add_transform(const Matrix &mat, bool inverted)
77 {
78  add_transform(this->matrix, mat, this->matrix, inverted);
79 }
80 
81 void BCMatrix::add_transform(const BCMatrix &mat, bool inverted)
82 {
83  add_transform(this->matrix, mat.matrix, this->matrix, inverted);
84 }
85 
86 void BCMatrix::apply_transform(const BCMatrix &mat, bool inverted)
87 {
88  apply_transform(this->matrix, mat.matrix, this->matrix, inverted);
89 }
90 
91 void BCMatrix::add_transform(Matrix &to,
92  const Matrix &transform,
93  const Matrix &from,
94  bool inverted)
95 {
96  if (inverted) {
97  Matrix globinv;
98  invert_m4_m4(globinv, transform);
99  add_transform(to, globinv, from, /*inverted=*/false);
100  }
101  else {
102  mul_m4_m4m4(to, transform, from);
103  }
104 }
105 
107  const Matrix &transform,
108  const Matrix &from,
109  bool inverse)
110 {
111  Matrix globinv;
112  invert_m4_m4(globinv, transform);
113  if (inverse) {
114  add_transform(to, globinv, from, /*inverted=*/false);
115  }
116  else {
117  mul_m4_m4m4(to, transform, from);
118  mul_m4_m4m4(to, to, globinv);
119  }
120 }
121 
122 void BCMatrix::add_inverted_transform(Matrix &to, const Matrix &transform, const Matrix &from)
123 {
124  Matrix workmat;
125  invert_m4_m4(workmat, transform);
126  mul_m4_m4m4(to, workmat, from);
127 }
128 
130 {
131  Matrix lmat;
132 
133  BKE_object_matrix_local_get(ob, lmat);
134  copy_m4_m4(matrix, lmat);
135 
136  mat4_decompose(this->loc, this->q, this->size, lmat);
137  quat_to_compatible_eul(this->rot, ob->rot, this->q);
138 }
139 
140 void BCMatrix::set_transform(Matrix &mat)
141 {
142  copy_m4_m4(matrix, mat);
143  mat4_decompose(this->loc, this->q, this->size, mat);
144  quat_to_eul(this->rot, this->q);
145 }
146 
147 void BCMatrix::copy(Matrix &r, Matrix &a)
148 {
149  /* destination comes first: */
150  memcpy(r, a, sizeof(Matrix));
151 }
152 
153 void BCMatrix::transpose(Matrix &mat)
154 {
155  transpose_m4(mat);
156 }
157 
158 void BCMatrix::sanitize(Matrix &mat, int precision)
159 {
160  for (auto &row : mat) {
161  for (float &cell : row) {
162  double val = (double)cell;
163  val = double_round(val, precision);
164  cell = (float)val;
165  }
166  }
167 }
168 
169 void BCMatrix::sanitize(DMatrix &mat, int precision)
170 {
171  for (auto &row : mat) {
172  for (double &cell : row) {
173  cell = double_round(cell, precision);
174  }
175  }
176 }
177 
178 void BCMatrix::unit()
179 {
180  unit_m4(this->matrix);
181  mat4_decompose(this->loc, this->q, this->size, this->matrix);
182  quat_to_eul(this->rot, this->q);
183 }
184 
185 /* We need double here because the OpenCollada API needs it.
186  * precision = -1 indicates to not limit the precision. */
187 void BCMatrix::get_matrix(DMatrix &mat, const bool transposed, const int precision) const
188 {
189  for (int i = 0; i < 4; i++) {
190  for (int j = 0; j < 4; j++) {
191  float val = (transposed) ? matrix[j][i] : matrix[i][j];
192  if (precision >= 0) {
193  val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
194  }
195  mat[i][j] = val;
196  }
197  }
198 }
199 
200 void BCMatrix::get_matrix(Matrix &mat,
201  const bool transposed,
202  const int precision,
203  const bool inverted) const
204 {
205  for (int i = 0; i < 4; i++) {
206  for (int j = 0; j < 4; j++) {
207  float val = (transposed) ? matrix[j][i] : matrix[i][j];
208  if (precision >= 0) {
209  val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision);
210  }
211  mat[i][j] = val;
212  }
213  }
214 
215  if (inverted) {
216  invert_m4(mat);
217  }
218 }
219 
220 bool BCMatrix::in_range(const BCMatrix &other, float distance) const
221 {
222  for (int i = 0; i < 4; i++) {
223  for (int j = 0; j < 4; j++) {
224  if (fabs(other.matrix[i][j] - matrix[i][j]) > distance) {
225  return false;
226  }
227  }
228  }
229  return true;
230 }
231 
233 {
234  return loc;
235 }
236 
238 {
239  return rot;
240 }
241 
242 float (&BCMatrix::scale() const)[3]
243 {
244  return size;
245 }
246 
247 float (&BCMatrix::quat() const)[4]
248 {
249  return q;
250 }
typedef float(TangentPoint)[2]
void BKE_object_matrix_local_get(struct Object *ob, float r_mat[4][4])
Definition: object.c:3245
double double_round(double x, int ndigits)
Definition: math_base.c:47
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1187
void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
Definition: math_matrix.c:2265
void unit_m4(float m[4][4])
Definition: rct.c:1140
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:120
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void transpose_m3(float R[3][3])
Definition: math_matrix.c:1312
void transpose_m4(float R[4][4])
Definition: math_matrix.c:1358
void quat_to_eul(float eul[3], const float quat[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:65
void mat4_to_quat(float q[4], const float mat[4][4])
bool mat3_from_axis_conversion(int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3])
void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4])
void quat_to_mat4(float mat[4][4], const float q[4])
static const BC_global_forward_axis BC_DEFAULT_FORWARD
static const BC_global_up_axis BC_DEFAULT_UP
typedef double(DMatrix)[4][4]
BC_global_up_axis
Definition: BlenderTypes.h:38
BC_global_forward_axis
Definition: BlenderTypes.h:29
_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 GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
btMatrix3x3 inverse() const
Return the inverse of the matrix.
Definition: btTransform.h:182
static void transpose(Matrix &matrix)
Definition: BCMath.cpp:153
void apply_transform(Matrix &to, const Matrix &transform, const Matrix &from, const bool inverse=false)
Definition: BCMath.cpp:106
void get_matrix(DMatrix &matrix, const bool transposed=false, const int precision=-1) const
Definition: BCMath.cpp:187
float(& rotation() const)[3]
Definition: BCMath.cpp:237
void add_inverted_transform(Matrix &to, const Matrix &transform, const Matrix &from)
Definition: BCMath.cpp:122
void set_transform(Object *ob)
Definition: BCMath.cpp:129
float(& scale() const)[3]
Definition: BCMath.cpp:242
float(& location() const)[3]
Definition: BCMath.cpp:232
float(& quat() const)[4]
Definition: BCMath.cpp:247
BCMatrix()
Definition: BCMath.cpp:58
void add_transform(Matrix &to, const Matrix &transform, const Matrix &from, const bool inverted=false)
Definition: BCMath.cpp:91
static void sanitize(Matrix &matrix, int precision)
Definition: BCMath.cpp:158
bool in_range(const BCMatrix &other, float distance) const
Definition: BCMath.cpp:220
void rotate_to(Matrix &mat_to)
Definition: BCMath.cpp:25
StackEntry * from
#define rot(x, k)
static unsigned a[3]
Definition: RandGen.cpp:92
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
float rot[3]
ccl_device_inline float distance(const float2 &a, const float2 &b)
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float2 fabs(const float2 &a)