diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-05-08 10:52:22 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-05-08 13:19:43 +0300 |
commit | 163a48f2035bbb40e6d437c7522f587d690456f6 (patch) | |
tree | 80dbf6cdaf686a4fd5e128c73807955e6764f316 /source | |
parent | 298356a9c0befa503a8eea6f168f6cdc5a950ac8 (diff) |
Cleanup: Alembic, moved axis conversion functions into their own files
The long-term goal is to move code out of `abc_util.{h,cc}` into either
files with better, more concrete names, or simply into the one file
where they are used.
No functional changes.
Diffstat (limited to 'source')
14 files changed, 277 insertions, 211 deletions
diff --git a/source/blender/io/alembic/CMakeLists.txt b/source/blender/io/alembic/CMakeLists.txt index cbcdfaf4b77..6de7d327d4e 100644 --- a/source/blender/io/alembic/CMakeLists.txt +++ b/source/blender/io/alembic/CMakeLists.txt @@ -41,6 +41,7 @@ set(INC_SYS ) set(SRC + intern/abc_axis_conversion.cc intern/abc_customdata.cc intern/abc_exporter.cc intern/abc_reader_archive.cc @@ -65,6 +66,7 @@ set(SRC intern/alembic_capi.cc ABC_alembic.h + intern/abc_axis_conversion.h intern/abc_customdata.h intern/abc_exporter.h intern/abc_reader_archive.h diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.cc b/source/blender/io/alembic/intern/abc_axis_conversion.cc new file mode 100644 index 00000000000..17db5e9c99f --- /dev/null +++ b/source/blender/io/alembic/intern/abc_axis_conversion.cc @@ -0,0 +1,166 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/** \file + * \ingroup Alembic + */ + +#include "abc_axis_conversion.h" + +extern "C" { +#include "BLI_assert.h" +#include "DNA_object_types.h" + +#include "BLI_math_geom.h" +} + +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) +{ + const float rx = euler[0]; + float ry; + float rz; + + /* Apply transformation */ + switch (mode) { + case ABC_ZUP_FROM_YUP: + ry = -euler[2]; + rz = euler[1]; + break; + case ABC_YUP_FROM_ZUP: + ry = euler[2]; + rz = -euler[1]; + break; + default: + ry = 0.0f; + rz = 0.0f; + BLI_assert(false); + break; + } + + unit_m3(rot_x_mat); + unit_m3(rot_y_mat); + unit_m3(rot_z_mat); + + rot_x_mat[1][1] = cos(rx); + rot_x_mat[2][1] = -sin(rx); + rot_x_mat[1][2] = sin(rx); + rot_x_mat[2][2] = cos(rx); + + rot_y_mat[2][2] = cos(ry); + rot_y_mat[0][2] = -sin(ry); + rot_y_mat[2][0] = sin(ry); + rot_y_mat[0][0] = cos(ry); + + rot_z_mat[0][0] = cos(rz); + rot_z_mat[1][0] = -sin(rz); + rot_z_mat[0][1] = sin(rz); + rot_z_mat[1][1] = cos(rz); +} + +/* 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 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 src_trans[3], dst_scale[3], src_scale[3], euler[3]; + + zero_v3(src_trans); + zero_v3(dst_scale); + zero_v3(src_scale); + zero_v3(euler); + unit_m3(src_rot); + unit_m3(dst_rot); + unit_m4(dst_scale_mat); + + /* TODO(Sybren): This code assumes there is no sheer component and no + * homogeneous scaling component, which is not always true when writing + * non-hierarchical (e.g. flat) objects (e.g. when parent has non-uniform + * scale and the child rotates). This is currently not taken into account + * when axis-swapping. */ + + /* 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_XZY, src_rot); + + /* Create X, Y, Z rotation matrices from euler angles. */ + create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode); + + /* Concatenate rotation matrices. */ + mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat); + mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat); + mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat); + + mat3_to_eulO(euler, ROT_MODE_XZY, 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); + } + + /* 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]; + + size_to_mat4(dst_scale_mat, dst_scale); + mul_m4_m4m4(dst_mat, dst_mat, dst_scale_mat); +} + +/* Recompute transform matrix of object in new coordinate system + * (from Z-Up to Y-Up). */ +void create_transform_matrix(Object *obj, + float r_yup_mat[4][4], + AbcMatrixMode mode, + Object *proxy_from) +{ + float zup_mat[4][4]; + + /* get local or world matrix. */ + if (mode == ABC_MATRIX_LOCAL && obj->parent) { + /* 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(zup_mat, obj->obmat); + } + + if (proxy_from) { + mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat); + } + + copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP); +} diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.h b/source/blender/io/alembic/intern/abc_axis_conversion.h new file mode 100644 index 00000000000..4faed822fc8 --- /dev/null +++ b/source/blender/io/alembic/intern/abc_axis_conversion.h @@ -0,0 +1,99 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2016 Kévin Dietrich & Blender Foundation. + * All rights reserved. + */ +#pragma once + +/** \file + * \ingroup Alembic + */ + +struct Object; + +#ifdef _MSC_VER +# define ABC_INLINE static __forceinline +#else +# define ABC_INLINE static inline +#endif + +/* TODO(kevin): for now keeping these transformations hardcoded to make sure + * everything works properly, and also because Alembic is almost exclusively + * used in Y-up software, but eventually they'll be set by the user in the UI + * like other importers/exporters do, to support other axis. */ + +/* Copy from Y-up to Z-up. */ + +ABC_INLINE void copy_zup_from_yup(float zup[3], const float yup[3]) +{ + const float old_yup1 = yup[1]; /* in case zup == yup */ + zup[0] = yup[0]; + zup[1] = -yup[2]; + zup[2] = old_yup1; +} + +ABC_INLINE void copy_zup_from_yup(short zup[3], const short yup[3]) +{ + const short old_yup1 = yup[1]; /* in case zup == yup */ + zup[0] = yup[0]; + zup[1] = -yup[2]; + zup[2] = old_yup1; +} + +/* Copy from Z-up to Y-up. */ + +ABC_INLINE void copy_yup_from_zup(float yup[3], const float zup[3]) +{ + const float old_zup1 = zup[1]; /* in case yup == zup */ + yup[0] = zup[0]; + yup[1] = zup[2]; + yup[2] = -old_zup1; +} + +ABC_INLINE void copy_yup_from_zup(short yup[3], const short zup[3]) +{ + const short old_zup1 = zup[1]; /* in case yup == zup */ + yup[0] = zup[0]; + yup[1] = zup[2]; + 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; + +/* Create a rotation matrix for each axis from euler angles. + * Euler angles are swapped to change coordinate system. */ +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); + +void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode); + +typedef enum { + ABC_MATRIX_WORLD = 1, + ABC_MATRIX_LOCAL = 2, +} AbcMatrixMode; + +void create_transform_matrix(Object *obj, + float r_transform_mat[4][4], + AbcMatrixMode mode, + Object *proxy_from); diff --git a/source/blender/io/alembic/intern/abc_reader_curves.cc b/source/blender/io/alembic/intern/abc_reader_curves.cc index 1be164c7c94..9fdc8b2b93f 100644 --- a/source/blender/io/alembic/intern/abc_reader_curves.cc +++ b/source/blender/io/alembic/intern/abc_reader_curves.cc @@ -22,6 +22,7 @@ */ #include "abc_reader_curves.h" +#include "abc_axis_conversion.h" #include "abc_reader_transform.h" #include "abc_util.h" diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index ec74fb2137e..a5c893a262a 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -19,6 +19,7 @@ */ #include "abc_reader_mesh.h" +#include "abc_axis_conversion.h" #include "abc_reader_transform.h" #include "abc_util.h" diff --git a/source/blender/io/alembic/intern/abc_reader_nurbs.cc b/source/blender/io/alembic/intern/abc_reader_nurbs.cc index 0ada10baba5..a57a1f55608 100644 --- a/source/blender/io/alembic/intern/abc_reader_nurbs.cc +++ b/source/blender/io/alembic/intern/abc_reader_nurbs.cc @@ -19,6 +19,7 @@ */ #include "abc_reader_nurbs.h" +#include "abc_axis_conversion.h" #include "abc_reader_transform.h" #include "abc_util.h" diff --git a/source/blender/io/alembic/intern/abc_reader_object.cc b/source/blender/io/alembic/intern/abc_reader_object.cc index 4e6db2dd85c..c40421da8c2 100644 --- a/source/blender/io/alembic/intern/abc_reader_object.cc +++ b/source/blender/io/alembic/intern/abc_reader_object.cc @@ -19,6 +19,7 @@ */ #include "abc_reader_object.h" +#include "abc_axis_conversion.h" #include "abc_util.h" extern "C" { diff --git a/source/blender/io/alembic/intern/abc_util.cc b/source/blender/io/alembic/intern/abc_util.cc index b26ef8b3b76..6b27c389363 100644 --- a/source/blender/io/alembic/intern/abc_util.cc +++ b/source/blender/io/alembic/intern/abc_util.cc @@ -20,6 +20,7 @@ #include "abc_util.h" +#include "abc_axis_conversion.h" #include "abc_reader_camera.h" #include "abc_reader_curves.h" #include "abc_reader_mesh.h" @@ -121,144 +122,6 @@ void split(const std::string &s, const char delim, std::vector<std::string> &tok } } -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) -{ - const float rx = euler[0]; - float ry; - float rz; - - /* Apply transformation */ - switch (mode) { - case ABC_ZUP_FROM_YUP: - ry = -euler[2]; - rz = euler[1]; - break; - case ABC_YUP_FROM_ZUP: - ry = euler[2]; - rz = -euler[1]; - break; - default: - ry = 0.0f; - rz = 0.0f; - BLI_assert(false); - break; - } - - unit_m3(rot_x_mat); - unit_m3(rot_y_mat); - unit_m3(rot_z_mat); - - rot_x_mat[1][1] = cos(rx); - rot_x_mat[2][1] = -sin(rx); - rot_x_mat[1][2] = sin(rx); - rot_x_mat[2][2] = cos(rx); - - rot_y_mat[2][2] = cos(ry); - rot_y_mat[0][2] = -sin(ry); - rot_y_mat[2][0] = sin(ry); - rot_y_mat[0][0] = cos(ry); - - rot_z_mat[0][0] = cos(rz); - rot_z_mat[1][0] = -sin(rz); - rot_z_mat[0][1] = sin(rz); - rot_z_mat[1][1] = cos(rz); -} - -/* 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 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 src_trans[3], dst_scale[3], src_scale[3], euler[3]; - - zero_v3(src_trans); - zero_v3(dst_scale); - zero_v3(src_scale); - zero_v3(euler); - unit_m3(src_rot); - unit_m3(dst_rot); - unit_m4(dst_scale_mat); - - /* TODO(Sybren): This code assumes there is no sheer component and no - * homogeneous scaling component, which is not always true when writing - * non-hierarchical (e.g. flat) objects (e.g. when parent has non-uniform - * scale and the child rotates). This is currently not taken into account - * when axis-swapping. */ - - /* 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_XZY, src_rot); - - /* Create X, Y, Z rotation matrices from euler angles. */ - create_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode); - - /* Concatenate rotation matrices. */ - mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat); - mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat); - mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat); - - mat3_to_eulO(euler, ROT_MODE_XZY, 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); - } - - /* 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]; - - size_to_mat4(dst_scale_mat, dst_scale); - mul_m4_m4m4(dst_mat, dst_mat, dst_scale_mat); -} - -/* Recompute transform matrix of object in new coordinate system - * (from Z-Up to Y-Up). */ -void create_transform_matrix(Object *obj, - float r_yup_mat[4][4], - AbcMatrixMode mode, - Object *proxy_from) -{ - float zup_mat[4][4]; - - /* get local or world matrix. */ - if (mode == ABC_MATRIX_LOCAL && obj->parent) { - /* 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(zup_mat, obj->obmat); - } - - if (proxy_from) { - mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat); - } - - copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP); -} - bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name) { if (!prop.valid()) { diff --git a/source/blender/io/alembic/intern/abc_util.h b/source/blender/io/alembic/intern/abc_util.h index 0b3462c2132..57b4d9800a5 100644 --- a/source/blender/io/alembic/intern/abc_util.h +++ b/source/blender/io/alembic/intern/abc_util.h @@ -56,15 +56,6 @@ Imath::M44d convert_matrix_datatype(float mat[4][4]); /* Convert from Alembic to float matrix representations. Does NOT convert from Y-up to Z-up. */ void convert_matrix_datatype(const Imath::M44d &xform, float r_mat[4][4]); -typedef enum { - ABC_MATRIX_WORLD = 1, - ABC_MATRIX_LOCAL = 2, -} AbcMatrixMode; -void create_transform_matrix(Object *obj, - float r_transform_mat[4][4], - AbcMatrixMode mode, - Object *proxy_from); - void split(const std::string &s, const char delim, std::vector<std::string> &tokens); template<class TContainer> bool begins_with(const TContainer &input, const TContainer &match) @@ -115,66 +106,6 @@ float get_weight_and_index(float time, AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSettings &settings); -/* ************************** */ - -/* TODO(kevin): for now keeping these transformations hardcoded to make sure - * everything works properly, and also because Alembic is almost exclusively - * used in Y-up software, but eventually they'll be set by the user in the UI - * like other importers/exporters do, to support other axis. */ - -/* Copy from Y-up to Z-up. */ - -ABC_INLINE void copy_zup_from_yup(float zup[3], const float yup[3]) -{ - const float old_yup1 = yup[1]; /* in case zup == yup */ - zup[0] = yup[0]; - zup[1] = -yup[2]; - zup[2] = old_yup1; -} - -ABC_INLINE void copy_zup_from_yup(short zup[3], const short yup[3]) -{ - const short old_yup1 = yup[1]; /* in case zup == yup */ - zup[0] = yup[0]; - zup[1] = -yup[2]; - zup[2] = old_yup1; -} - -/* Copy from Z-up to Y-up. */ - -ABC_INLINE void copy_yup_from_zup(float yup[3], const float zup[3]) -{ - const float old_zup1 = zup[1]; /* in case yup == zup */ - yup[0] = zup[0]; - yup[1] = zup[2]; - yup[2] = -old_zup1; -} - -ABC_INLINE void copy_yup_from_zup(short yup[3], const short zup[3]) -{ - const short old_zup1 = zup[1]; /* in case yup == zup */ - yup[0] = zup[0]; - yup[1] = zup[2]; - 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; - -/* Create a rotation matrix for each axis from euler angles. - * Euler angles are swapped to change coordinate system. */ -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); - -void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode); - /* *************************** */ #undef ABC_DEBUG_TIME diff --git a/source/blender/io/alembic/intern/abc_writer_curves.cc b/source/blender/io/alembic/intern/abc_writer_curves.cc index 3ab9b365a72..8cb40c4ffab 100644 --- a/source/blender/io/alembic/intern/abc_writer_curves.cc +++ b/source/blender/io/alembic/intern/abc_writer_curves.cc @@ -22,6 +22,7 @@ */ #include "abc_writer_curves.h" +#include "abc_axis_conversion.h" #include "abc_reader_curves.h" #include "abc_writer_transform.h" diff --git a/source/blender/io/alembic/intern/abc_writer_hair.cc b/source/blender/io/alembic/intern/abc_writer_hair.cc index f29d195f2ff..dd1203de835 100644 --- a/source/blender/io/alembic/intern/abc_writer_hair.cc +++ b/source/blender/io/alembic/intern/abc_writer_hair.cc @@ -19,7 +19,7 @@ */ #include "abc_writer_hair.h" -#include "abc_util.h" +#include "abc_axis_conversion.h" #include "abc_writer_transform.h" #include <cstdio> diff --git a/source/blender/io/alembic/intern/abc_writer_mesh.cc b/source/blender/io/alembic/intern/abc_writer_mesh.cc index 546ccc9f2ce..38939d15c85 100644 --- a/source/blender/io/alembic/intern/abc_writer_mesh.cc +++ b/source/blender/io/alembic/intern/abc_writer_mesh.cc @@ -19,7 +19,7 @@ */ #include "abc_writer_mesh.h" -#include "abc_util.h" +#include "abc_axis_conversion.h" #include "abc_writer_transform.h" extern "C" { diff --git a/source/blender/io/alembic/intern/abc_writer_nurbs.cc b/source/blender/io/alembic/intern/abc_writer_nurbs.cc index d643f5482c0..3521c62075f 100644 --- a/source/blender/io/alembic/intern/abc_writer_nurbs.cc +++ b/source/blender/io/alembic/intern/abc_writer_nurbs.cc @@ -19,7 +19,7 @@ */ #include "abc_writer_nurbs.h" -#include "abc_util.h" +#include "abc_axis_conversion.h" #include "abc_writer_transform.h" extern "C" { diff --git a/source/blender/io/alembic/intern/abc_writer_transform.cc b/source/blender/io/alembic/intern/abc_writer_transform.cc index d7bcc46d96f..18f4487cf05 100644 --- a/source/blender/io/alembic/intern/abc_writer_transform.cc +++ b/source/blender/io/alembic/intern/abc_writer_transform.cc @@ -19,7 +19,7 @@ */ #include "abc_writer_transform.h" -#include "abc_util.h" +#include "abc_axis_conversion.h" #include <OpenEXR/ImathBoxAlgo.h> |