Alembic: removed a lot of unnecessary & duplicate code from abc_util.cc

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.
This commit is contained in:
2017-02-15 15:20:23 +01:00
parent 1c3b6e042a
commit 06c25ace7b
2 changed files with 65 additions and 213 deletions

View 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);
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);
/* Add rotation matrix to transformation matrix. */
copy_m4_m3(transform_mat, rot_mat);
mat3_to_eulO(euler, ROT_MODE_XYZ, dst_rot);
/* Add translation to transformation matrix. */
copy_zup_from_yup(transform_mat[3], loc);
/* Start construction of dst_mat from rotation matrix */
unit_m4(dst_mat);
copy_m4_m3(dst_mat, dst_rot);
/* Create scale matrix. */
scale_mat[0][0] = scale[0];
scale_mat[1][1] = scale[2];
scale_mat[2][2] = scale[1];
/* 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)

View 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