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