Alembic: removed a lot of unnecessary & duplicate code from abc_util.cc
authorSybren A. Stüvel <sybren@stuvel.eu>
Wed, 15 Feb 2017 14:20:23 +0000 (15:20 +0100)
committerSybren A. Stüvel <sybren@stuvel.eu>
Thu, 6 Apr 2017 14:04:31 +0000 (16:04 +0200)
create_transform_matrix(float[4][4]) did mostly the same as
create_transform_matrix(Object *, float[4][4]), but more elegant.
However, the former has some inconsistencies with the latter (which
are now merged and made explicit, turned out one was for z-up→y-up
while the other was for y-up→z-up), and was renamed to
copy_m44_axis_swap(...) to convey its purpose more clearly.

Furthermore, "loc" has been renamed to "trans", as matrices don't
store locations but translations; and more variables now have a src_
or dst_ prefix to denote whether they contain a matrix/vector in the
source or destination axis orientation.

source/blender/alembic/intern/abc_util.cc
source/blender/alembic/intern/abc_util.h

index 68306af1e42bf1454bb01cf1037983fb5c99801e..8b6b2a47e4ac048f10eb75afa4794a73ae91585b 100644 (file)
@@ -162,57 +162,68 @@ static void create_rotation_matrix(
        rot_z_mat[1][1] = cos(rz);
 }
 
-/* Recompute transform matrix of object in new coordinate system
- * (from Y-Up to Z-Up).
- *
- * Note that r_mat is used as both input and output parameter.
- */
-void create_transform_matrix(float r_mat[4][4])
+/* Convert matrix from Z=up to Y=up or vice versa. Use yup_mat = zup_mat for in-place conversion. */
+void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode)
 {
-       float rot_mat[3][3], rot[3][3], scale_mat[4][4], invmat[4][4], transform_mat[4][4];
+       float dst_rot[3][3], src_rot[3][3], dst_scale_mat[4][4];
        float rot_x_mat[3][3], rot_y_mat[3][3], rot_z_mat[3][3];
-       float loc[3], scale[3], euler[3];
+       float src_trans[3], dst_scale[3], src_scale[3], euler[3];
 
-       zero_v3(loc);
-       zero_v3(scale);
+       zero_v3(src_trans);
+       zero_v3(dst_scale);
+       zero_v3(src_scale);
        zero_v3(euler);
-       unit_m3(rot);
-       unit_m3(rot_mat);
-       unit_m4(scale_mat);
-       unit_m4(transform_mat);
-       unit_m4(invmat);
+       unit_m3(src_rot);
+       unit_m3(dst_rot);
+       unit_m4(dst_scale_mat);
 
-       /* Compute rotation matrix. */
+       /* We assume there is no sheer component and no homogeneous scaling component. */
+       BLI_assert(src_mat[0][3] == 0.0);
+       BLI_assert(src_mat[1][3] == 0.0);
+       BLI_assert(src_mat[2][3] == 0.0);
+       BLI_assert(src_mat[3][3] == 1.0);
 
-       /* Extract location, rotation, and scale from matrix. */
-       mat4_to_loc_rot_size(loc, rot, scale, r_mat);
+       /* Extract translation, rotation, and scale form matrix. */
+       mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat);
 
        /* Get euler angles from rotation matrix. */
-       mat3_to_eulO(euler, ROT_MODE_XYZ, rot);
+       mat3_to_eulO(euler, ROT_MODE_XYZ, src_rot);
 
        /* Create X, Y, Z rotation matrices from euler angles. */
-       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, false);
+       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler,
+                              mode == ABC_YUP_FROM_ZUP);
 
        /* Concatenate rotation matrices. */
-       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-
-       /* Add rotation matrix to transformation matrix. */
-       copy_m4_m3(transform_mat, rot_mat);
-
-       /* Add translation to transformation matrix. */
-       copy_zup_from_yup(transform_mat[3], loc);
-
-       /* Create scale matrix. */
-       scale_mat[0][0] = scale[0];
-       scale_mat[1][1] = scale[2];
-       scale_mat[2][2] = scale[1];
+       mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat);
+       mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat);
+       mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat);
+
+       mat3_to_eulO(euler, ROT_MODE_XYZ, dst_rot);
+
+       /* Start construction of dst_mat from rotation matrix */
+       unit_m4(dst_mat);
+       copy_m4_m3(dst_mat, dst_rot);
+
+       /* Apply translation */
+       switch(mode) {
+       case ABC_ZUP_FROM_YUP:
+               copy_zup_from_yup(dst_mat[3], src_trans);
+               break;
+       case ABC_YUP_FROM_ZUP:
+               copy_yup_from_zup(dst_mat[3], src_trans);
+               break;
+       default:
+               BLI_assert(false);
+       }
 
-       /* Add scale to transformation matrix. */
-       mul_m4_m4m4(transform_mat, transform_mat, scale_mat);
+       /* Apply scale matrix. Swaps y and z, but does not
+        * negate like translation does. */
+       dst_scale[0] = src_scale[0];
+       dst_scale[1] = src_scale[2];
+       dst_scale[2] = src_scale[1];
 
-       copy_m4_m4(r_mat, transform_mat);
+       size_to_mat4(dst_scale_mat, dst_scale);
+       mul_m4_m4m4(dst_mat, dst_mat, dst_scale_mat);
 }
 
 void convert_matrix(const Imath::M44d &xform, Object *ob,
@@ -230,7 +241,7 @@ void convert_matrix(const Imath::M44d &xform, Object *ob,
                mul_m4_m4m4(r_mat, r_mat, cam_to_yup);
        }
 
-       create_transform_matrix(r_mat);
+       copy_m44_axis_swap(r_mat, r_mat, ABC_ZUP_FROM_YUP);
 
        if (!has_alembic_parent) {
                /* Only apply scaling to root objects, parenting will propagate it. */
@@ -241,195 +252,28 @@ void convert_matrix(const Imath::M44d &xform, Object *ob,
        }
 }
 
-/* Recompute transform matrix of object in new coordinate system (from Z-Up to Y-Up). */
-void create_transform_matrix(Object *obj, float transform_mat[4][4])
+/* Recompute transform matrix of object in new coordinate system
+ * (from Z-Up to Y-Up). */
+void create_transform_matrix(Object *obj, float yup_mat[4][4])
 {
-       float rot_mat[3][3], rot[3][3], scale_mat[4][4], invmat[4][4], mat[4][4];
-       float rot_x_mat[3][3], rot_y_mat[3][3], rot_z_mat[3][3];
-       float loc[3], scale[3], euler[3];
-
-       zero_v3(loc);
-       zero_v3(scale);
-       zero_v3(euler);
-       unit_m3(rot);
-       unit_m3(rot_mat);
-       unit_m4(scale_mat);
-       unit_m4(transform_mat);
-       unit_m4(invmat);
-       unit_m4(mat);
+       float zup_mat[4][4];
 
        /* get local matrix. */
        /* TODO Sybren: when we're exporting as "flat", i.e. non-hierarchial,
         * we should export the world matrix even when the object has a parent
         * Blender Object. */
        if (obj->parent) {
-               invert_m4_m4(invmat, obj->parent->obmat);
-               mul_m4_m4m4(mat, invmat, obj->obmat);
+               /* Note that this produces another matrix than the local matrix, due to
+                * constraints and modifiers as well as the obj->parentinv matrix. */
+               invert_m4_m4(obj->parent->imat, obj->parent->obmat);
+               mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
        }
        else {
-               copy_m4_m4(mat, obj->obmat);
+               copy_m4_m4(zup_mat, obj->obmat);
        }
 
-       /* Compute rotation matrix. */
-       switch (obj->rotmode) {
-               case ROT_MODE_AXISANGLE:
-               {
-                       /* Get euler angles from axis angle rotation. */
-                       axis_angle_to_eulO(euler, ROT_MODE_XYZ, obj->rotAxis, obj->rotAngle);
-
-                       /* Create X, Y, Z rotation matrices from euler angles. */
-                       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, true);
-
-                       /* Concatenate rotation matrices. */
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-
-                       /* Extract location and scale from matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       break;
-               }
-               case ROT_MODE_QUAT:
-               {
-                       float q[4];
-                       copy_v4_v4(q, obj->quat);
-
-                       /* Swap axis. */
-                       q[2] = obj->quat[3];
-                       q[3] = -obj->quat[2];
-
-                       /* Compute rotation matrix from quaternion. */
-                       quat_to_mat3(rot_mat, q);
-
-                       /* Extract location and scale from matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       break;
-               }
-               case ROT_MODE_XYZ:
-               {
-                       /* Extract location, rotation, and scale form matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       /* Get euler angles from rotation matrix. */
-                       mat3_to_eulO(euler, ROT_MODE_XYZ, rot);
-
-                       /* Create X, Y, Z rotation matrices from euler angles. */
-                       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, true);
-
-                       /* Concatenate rotation matrices. */
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-
-                       break;
-               }
-               case ROT_MODE_XZY:
-               {
-                       /* Extract location, rotation, and scale form matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       /* Get euler angles from rotation matrix. */
-                       mat3_to_eulO(euler, ROT_MODE_XZY, rot);
-
-                       /* Create X, Y, Z rotation matrices from euler angles. */
-                       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, true);
-
-                       /* Concatenate rotation matrices. */
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-
-                       break;
-               }
-               case ROT_MODE_YXZ:
-               {
-                       /* Extract location, rotation, and scale form matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       /* Get euler angles from rotation matrix. */
-                       mat3_to_eulO(euler, ROT_MODE_YXZ, rot);
-
-                       /* Create X, Y, Z rotation matrices from euler angles. */
-                       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, true);
-
-                       /* Concatenate rotation matrices. */
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-
-                       break;
-               }
-               case ROT_MODE_YZX:
-               {
-                       /* Extract location, rotation, and scale form matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       /* Get euler angles from rotation matrix. */
-                       mat3_to_eulO(euler, ROT_MODE_YZX, rot);
-
-                       /* Create X, Y, Z rotation matrices from euler angles. */
-                       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, true);
-
-                       /* Concatenate rotation matrices. */
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-
-                       break;
-               }
-               case ROT_MODE_ZXY:
-               {
-                       /* Extract location, rotation, and scale form matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       /* Get euler angles from rotation matrix. */
-                       mat3_to_eulO(euler, ROT_MODE_ZXY, rot);
-
-                       /* Create X, Y, Z rotation matrices from euler angles. */
-                       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, true);
-
-                       /* Concatenate rotation matrices. */
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-
-                       break;
-               }
-               case ROT_MODE_ZYX:
-               {
-                       /* Extract location, rotation, and scale form matrix. */
-                       mat4_to_loc_rot_size(loc, rot, scale, mat);
-
-                       /* Get euler angles from rotation matrix. */
-                       mat3_to_eulO(euler, ROT_MODE_ZYX, rot);
-
-                       /* Create X, Y, Z rotation matrices from euler angles. */
-                       create_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, true);
-
-                       /* Concatenate rotation matrices. */
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat);
-                       mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat);
-
-                       break;
-               }
-       }
-
-       /* Add rotation matrix to transformation matrix. */
-       copy_m4_m3(transform_mat, rot_mat);
-
-       /* Add translation to transformation matrix. */
-       copy_yup_from_zup(transform_mat[3], loc);
-
-       /* Create scale matrix. */
-       scale_mat[0][0] = scale[0];
-       scale_mat[1][1] = scale[2];
-       scale_mat[2][2] = scale[1];
 
-       /* Add scale to transformation matrix. */
-       mul_m4_m4m4(transform_mat, transform_mat, scale_mat);
+       copy_m44_axis_swap(yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
 }
 
 bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
index 8c9a8fac812e7498e4c3b105f2a5b4649eb6e29e..3a5d5e914af2f1e0832b4425b0d622d025aa4738 100644 (file)
@@ -52,7 +52,6 @@ bool object_selected(Object *ob);
 bool parent_selected(Object *ob);
 
 Imath::M44d convert_matrix(float mat[4][4]);
-void create_transform_matrix(float r_mat[4][4]);
 void create_transform_matrix(Object *obj, float transform_mat[4][4]);
 
 void split(const std::string &s, const char delim, std::vector<std::string> &tokens);
@@ -150,6 +149,15 @@ ABC_INLINE void copy_yup_from_zup(short yup[3], const short zup[3])
        yup[2] = -old_zup1;
 }
 
+/* Names are given in (dst, src) order, just like
+ * the parameters of copy_m44_axis_swap() */
+typedef enum {
+       ABC_ZUP_FROM_YUP = 1,
+       ABC_YUP_FROM_ZUP = 2,
+} AbcAxisSwapMode;
+
+void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode);
+
 /* *************************** */
 
 #undef ABC_DEBUG_TIME