Blender  V2.93
abc_axis_conversion.cc
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 
21 #include "abc_axis_conversion.h"
22 
23 #include "BLI_assert.h"
24 #include "BLI_math_geom.h"
25 
26 #include "DNA_object_types.h"
27 
28 namespace blender::io::alembic {
29 
30 void create_swapped_rotation_matrix(float rot_x_mat[3][3],
31  float rot_y_mat[3][3],
32  float rot_z_mat[3][3],
33  const float euler[3],
34  AbcAxisSwapMode mode)
35 {
36  const float rx = euler[0];
37  float ry;
38  float rz;
39 
40  /* Apply transformation */
41  switch (mode) {
42  case ABC_ZUP_FROM_YUP:
43  ry = -euler[2];
44  rz = euler[1];
45  break;
46  case ABC_YUP_FROM_ZUP:
47  ry = euler[2];
48  rz = -euler[1];
49  break;
50  default:
51  ry = 0.0f;
52  rz = 0.0f;
53  BLI_assert(false);
54  break;
55  }
56 
57  unit_m3(rot_x_mat);
58  unit_m3(rot_y_mat);
59  unit_m3(rot_z_mat);
60 
61  rot_x_mat[1][1] = cos(rx);
62  rot_x_mat[2][1] = -sin(rx);
63  rot_x_mat[1][2] = sin(rx);
64  rot_x_mat[2][2] = cos(rx);
65 
66  rot_y_mat[2][2] = cos(ry);
67  rot_y_mat[0][2] = -sin(ry);
68  rot_y_mat[2][0] = sin(ry);
69  rot_y_mat[0][0] = cos(ry);
70 
71  rot_z_mat[0][0] = cos(rz);
72  rot_z_mat[1][0] = -sin(rz);
73  rot_z_mat[0][1] = sin(rz);
74  rot_z_mat[1][1] = cos(rz);
75 } // namespace
76  // alembicvoidcreate_swapped_rotation_matrix(floatrot_x_mat[3][3],floatrot_y_mat[3][3],floatrot_z_mat[3][3],constfloateuler[3],AbcAxisSwapModemode)
77 
78 /* Convert matrix from Z=up to Y=up or vice versa.
79  * Use yup_mat = zup_mat for in-place conversion. */
80 void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode)
81 {
82  float dst_rot[3][3], src_rot[3][3], dst_scale_mat[4][4];
83  float rot_x_mat[3][3], rot_y_mat[3][3], rot_z_mat[3][3];
84  float src_trans[3], dst_scale[3], src_scale[3], euler[3];
85 
86  zero_v3(src_trans);
87  zero_v3(dst_scale);
88  zero_v3(src_scale);
89  zero_v3(euler);
90  unit_m3(src_rot);
91  unit_m3(dst_rot);
92  unit_m4(dst_scale_mat);
93 
94  /* TODO(Sybren): This code assumes there is no sheer component and no
95  * homogeneous scaling component, which is not always true when writing
96  * non-hierarchical (e.g. flat) objects (e.g. when parent has non-uniform
97  * scale and the child rotates). This is currently not taken into account
98  * when axis-swapping. */
99 
100  /* Extract translation, rotation, and scale form matrix. */
101  mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat);
102 
103  /* Get euler angles from rotation matrix. */
104  mat3_to_eulO(euler, ROT_MODE_XZY, src_rot);
105 
106  /* Create X, Y, Z rotation matrices from euler angles. */
107  create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode);
108 
109  /* Concatenate rotation matrices. */
110  mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat);
111  mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat);
112  mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat);
113 
114  mat3_to_eulO(euler, ROT_MODE_XZY, dst_rot);
115 
116  /* Start construction of dst_mat from rotation matrix */
117  unit_m4(dst_mat);
118  copy_m4_m3(dst_mat, dst_rot);
119 
120  /* Apply translation */
121  switch (mode) {
122  case ABC_ZUP_FROM_YUP:
123  copy_zup_from_yup(dst_mat[3], src_trans);
124  break;
125  case ABC_YUP_FROM_ZUP:
126  copy_yup_from_zup(dst_mat[3], src_trans);
127  break;
128  default:
129  BLI_assert(false);
130  }
131 
132  /* Apply scale matrix. Swaps y and z, but does not
133  * negate like translation does. */
134  dst_scale[0] = src_scale[0];
135  dst_scale[1] = src_scale[2];
136  dst_scale[2] = src_scale[1];
137 
138  size_to_mat4(dst_scale_mat, dst_scale);
139  mul_m4_m4m4(dst_mat, dst_mat, dst_scale_mat);
140 }
141 
142 /* Recompute transform matrix of object in new coordinate system
143  * (from Z-Up to Y-Up). */
145  float r_yup_mat[4][4],
146  AbcMatrixMode mode,
147  Object *proxy_from)
148 {
149  float zup_mat[4][4];
150 
151  /* get local or world matrix. */
152  if (mode == ABC_MATRIX_LOCAL && obj->parent) {
153  /* Note that this produces another matrix than the local matrix, due to
154  * constraints and modifiers as well as the obj->parentinv matrix. */
155  invert_m4_m4(obj->parent->imat, obj->parent->obmat);
156  mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
157  }
158  else {
159  copy_m4_m4(zup_mat, obj->obmat);
160  }
161 
162  if (proxy_from) {
163  mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat);
164  }
165 
166  copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
167 }
168 
169 } // namespace blender::io::alembic
#define BLI_assert(a)
Definition: BLI_assert.h:58
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
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 mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
Definition: math_matrix.c:2236
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2118
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
void mat3_to_eulO(float eul[3], const short order, const float mat[3][3])
MINLINE void zero_v3(float r[3])
@ ROT_MODE_XZY
Object is a sort of wrapper for general info.
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:319
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
void create_swapped_rotation_matrix(float rot_x_mat[3][3], float rot_y_mat[3][3], float rot_z_mat[3][3], const float euler[3], AbcAxisSwapMode mode)
BLI_INLINE void copy_yup_from_zup(float yup[3], const float zup[3])
void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode)
BLI_INLINE void copy_zup_from_yup(float zup[3], const float yup[3])
void create_transform_matrix(Object *obj, float r_yup_mat[4][4], AbcMatrixMode mode, Object *proxy_from)
float imat[4][4]
float obmat[4][4]
struct Object * parent