Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@stuvel.eu>2017-04-07 18:28:22 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2017-04-07 18:28:22 +0300
commit063bae4fcc079d0ba7b7f86d327179df36a95146 (patch)
treef484ae3d53406ecc01f90189665defb4b1f73b13 /source/blender/alembic/intern/abc_util.cc
parent711ac03fa14a0087d72e2429140357f6748b6972 (diff)
parent43a910abce50963d12c0ccde596347459d921b9a (diff)
Merge branch 'master' into blender2.8
# Conflicts: # source/blender/alembic/intern/abc_exporter.h # source/blender/alembic/intern/abc_util.cc
Diffstat (limited to 'source/blender/alembic/intern/abc_util.cc')
-rw-r--r--source/blender/alembic/intern/abc_util.cc321
1 files changed, 85 insertions, 236 deletions
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index 41cc53b0716..b99be718c18 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -42,7 +42,7 @@ extern "C" {
#include "PIL_time.h"
}
-std::string get_id_name(Object *ob)
+std::string get_id_name(const Object * const ob)
{
if (!ob) {
return "";
@@ -51,7 +51,7 @@ std::string get_id_name(Object *ob)
return get_id_name(&ob->id);
}
-std::string get_id_name(ID *id)
+std::string get_id_name(const ID * const id)
{
std::string name(id->name + 2);
std::replace(name.begin(), name.end(), ' ', '_');
@@ -61,7 +61,6 @@ std::string get_id_name(ID *id)
return name;
}
-
/**
* @brief get_object_dag_path_name returns the name under which the object
* will be exported in the Alembic file. It is of the form
@@ -71,7 +70,7 @@ std::string get_id_name(ID *id)
* @param dupli_parent
* @return
*/
-std::string get_object_dag_path_name(Object *ob, Object *dupli_parent)
+std::string get_object_dag_path_name(const Object * const ob, Object *dupli_parent)
{
std::string name = get_id_name(ob);
@@ -121,15 +120,28 @@ void split(const std::string &s, const char delim, std::vector<std::string> &tok
}
}
-/* Create a rotation matrix for each axis from euler angles.
- * Euler angles are swaped to change coordinate system. */
-static void create_rotation_matrix(
+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], const bool to_yup)
+ float rot_z_mat[3][3], const float euler[3],
+ AbcAxisSwapMode mode)
{
const float rx = euler[0];
- const float ry = (to_yup) ? euler[2] : -euler[2];
- const float rz = (to_yup) ? -euler[1] : euler[1];
+ 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:
+ BLI_assert(false);
+ }
unit_m3(rot_x_mat);
unit_m3(rot_y_mat);
@@ -151,58 +163,70 @@ 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). */
-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(fabs(src_mat[0][3]) < 2 * FLT_EPSILON);
+ BLI_assert(fabs(src_mat[1][3]) < 2 * FLT_EPSILON);
+ BLI_assert(fabs(src_mat[2][3]) < 2 * FLT_EPSILON);
+ BLI_assert(fabs(src_mat[3][3] - 1.0f) < 2 * FLT_EPSILON);
- /* 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_XZY, 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_swapped_rotation_matrix(rot_x_mat, rot_y_mat, rot_z_mat, euler, mode);
/* 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_z_mat);
+ mul_m3_m3m3(dst_rot, dst_rot, rot_y_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_XZY, 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,
- float r_mat[4][4], float scale, bool has_alembic_parent)
+void convert_matrix(const Imath::M44d &xform, Object *ob, float r_mat[4][4])
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
@@ -216,207 +240,29 @@ void convert_matrix(const Imath::M44d &xform, Object *ob,
mul_m4_m4m4(r_mat, r_mat, cam_to_yup);
}
- create_transform_matrix(r_mat);
-
- if (ob->parent) {
- mul_m4_m4m4(r_mat, ob->parent->obmat, r_mat);
- }
- /* TODO(kevin) */
- else if (!has_alembic_parent) {
- /* Only apply scaling to root objects, parenting will propagate it. */
- float scale_mat[4][4];
- scale_m4_fl(scale_mat, scale);
- mul_m4_m4m4(r_mat, r_mat, scale_mat);
- mul_v3_fl(r_mat[3], scale);
- }
+ copy_m44_axis_swap(r_mat, r_mat, ABC_ZUP_FROM_YUP);
}
-/* 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 r_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);
+ copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
}
else {
- copy_m4_m4(mat, obj->obmat);
+ copy_m44_axis_swap(r_yup_mat, obj->obmat, ABC_YUP_FROM_ZUP);
}
-
- /* 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);
}
bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
@@ -509,7 +355,10 @@ AbcObjectReader *create_reader(const Alembic::AbcGeom::IObject &object, ImportSe
reader = new AbcCurveReader(object, settings);
}
else {
- assert(false);
+ std::cerr << "Alembic: unknown how to handle objects of schema "
+ << md.get("schemaObjTitle")
+ << ", skipping object "
+ << object.getFullName() << std::endl;
}
return reader;