Blender  V3.3
abc_axis_conversion.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "abc_axis_conversion.h"
8 
9 #include "BLI_assert.h"
10 #include "BLI_math_geom.h"
11 
12 #include "DNA_object_types.h"
13 
14 namespace blender::io::alembic {
15 
16 void create_swapped_rotation_matrix(float rot_x_mat[3][3],
17  float rot_y_mat[3][3],
18  float rot_z_mat[3][3],
19  const float euler[3],
20  AbcAxisSwapMode mode)
21 {
22  const float rx = euler[0];
23  float ry;
24  float rz;
25 
26  /* Apply transformation */
27  switch (mode) {
28  case ABC_ZUP_FROM_YUP:
29  ry = -euler[2];
30  rz = euler[1];
31  break;
32  case ABC_YUP_FROM_ZUP:
33  ry = euler[2];
34  rz = -euler[1];
35  break;
36  default:
37  ry = 0.0f;
38  rz = 0.0f;
39  BLI_assert(false);
40  break;
41  }
42 
43  unit_m3(rot_x_mat);
44  unit_m3(rot_y_mat);
45  unit_m3(rot_z_mat);
46 
47  rot_x_mat[1][1] = cos(rx);
48  rot_x_mat[2][1] = -sin(rx);
49  rot_x_mat[1][2] = sin(rx);
50  rot_x_mat[2][2] = cos(rx);
51 
52  rot_y_mat[2][2] = cos(ry);
53  rot_y_mat[0][2] = -sin(ry);
54  rot_y_mat[2][0] = sin(ry);
55  rot_y_mat[0][0] = cos(ry);
56 
57  rot_z_mat[0][0] = cos(rz);
58  rot_z_mat[1][0] = -sin(rz);
59  rot_z_mat[0][1] = sin(rz);
60  rot_z_mat[1][1] = cos(rz);
61 } // namespace
62  // alembicvoidcreate_swapped_rotation_matrix(floatrot_x_mat[3][3],floatrot_y_mat[3][3],floatrot_z_mat[3][3],constfloateuler[3],AbcAxisSwapModemode)
63 
64 void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode)
65 {
66  float dst_rot[3][3], src_rot[3][3], dst_scale_mat[4][4];
67  float rot_x_mat[3][3], rot_y_mat[3][3], rot_z_mat[3][3];
68  float src_trans[3], dst_scale[3], src_scale[3], euler[3];
69 
70  zero_v3(src_trans);
71  zero_v3(dst_scale);
72  zero_v3(src_scale);
73  zero_v3(euler);
74  unit_m3(src_rot);
75  unit_m3(dst_rot);
76  unit_m4(dst_scale_mat);
77 
78  /* TODO(Sybren): This code assumes there is no sheer component and no
79  * homogeneous scaling component, which is not always true when writing
80  * non-hierarchical (e.g. flat) objects (e.g. when parent has non-uniform
81  * scale and the child rotates). This is currently not taken into account
82  * when axis-swapping. */
83 
84  /* Extract translation, rotation, and scale form matrix. */
85  mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat);
86 
87  /* Get euler angles from rotation matrix. */
88  mat3_to_eulO(euler, ROT_MODE_XZY, src_rot);
89 
90  /* Create X, Y, Z rotation matrices from euler angles. */
91  create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode);
92 
93  /* Concatenate rotation matrices. */
94  mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat);
95  mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat);
96  mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat);
97 
98  mat3_to_eulO(euler, ROT_MODE_XZY, dst_rot);
99 
100  /* Start construction of dst_mat from rotation matrix */
101  unit_m4(dst_mat);
102  copy_m4_m3(dst_mat, dst_rot);
103 
104  /* Apply translation */
105  switch (mode) {
106  case ABC_ZUP_FROM_YUP:
107  copy_zup_from_yup(dst_mat[3], src_trans);
108  break;
109  case ABC_YUP_FROM_ZUP:
110  copy_yup_from_zup(dst_mat[3], src_trans);
111  break;
112  default:
113  BLI_assert(false);
114  }
115 
116  /* Apply scale matrix. Swaps y and z, but does not
117  * negate like translation does. */
118  dst_scale[0] = src_scale[0];
119  dst_scale[1] = src_scale[2];
120  dst_scale[2] = src_scale[1];
121 
122  size_to_mat4(dst_scale_mat, dst_scale);
123  mul_m4_m4m4(dst_mat, dst_mat, dst_scale_mat);
124 }
125 
127  float r_yup_mat[4][4],
128  AbcMatrixMode mode,
129  Object *proxy_from)
130 {
131  float zup_mat[4][4];
132 
133  /* get local or world matrix. */
134  if (mode == ABC_MATRIX_LOCAL && obj->parent) {
135  /* Note that this produces another matrix than the local matrix, due to
136  * constraints and modifiers as well as the obj->parentinv matrix. */
137  invert_m4_m4(obj->parent->imat, obj->parent->obmat);
138  mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
139  }
140  else {
141  copy_m4_m4(zup_mat, obj->obmat);
142  }
143 
144  if (proxy_from) {
145  mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat);
146  }
147 
148  copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
149 }
150 
151 } // namespace blender::io::alembic
#define BLI_assert(a)
Definition: BLI_assert.h:46
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void unit_m4(float m[4][4])
Definition: rct.c:1090
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:102
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
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:2224
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2111
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
void mat3_to_eulO(float eul[3], 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