Changeset View
Changeset View
Standalone View
Standalone View
source/blender/alembic/intern/abc_util.cc
| Show All 33 Lines | |||||
| #include <algorithm> | #include <algorithm> | ||||
| extern "C" { | extern "C" { | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| } | } | ||||
| std::string get_id_name(Object *ob) | std::string get_id_name(const Object * const ob) | ||||
| { | { | ||||
| if (!ob) { | if (!ob) { | ||||
| return ""; | return ""; | ||||
| } | } | ||||
| return get_id_name(&ob->id); | 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::string name(id->name + 2); | ||||
| std::replace(name.begin(), name.end(), ' ', '_'); | std::replace(name.begin(), name.end(), ' ', '_'); | ||||
| std::replace(name.begin(), name.end(), '.', '_'); | std::replace(name.begin(), name.end(), '.', '_'); | ||||
| std::replace(name.begin(), name.end(), ':', '_'); | std::replace(name.begin(), name.end(), ':', '_'); | ||||
| return name; | return name; | ||||
| } | } | ||||
| 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); | std::string name = get_id_name(ob); | ||||
| Object *p = ob->parent; | Object *p = ob->parent; | ||||
| while (p) { | while (p) { | ||||
| name = get_id_name(p) + "/" + name; | name = get_id_name(p) + "/" + name; | ||||
| p = p->parent; | p = p->parent; | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | static void create_rotation_matrix( | ||||
| rot_y_mat[0][0] = cos(ry); | rot_y_mat[0][0] = cos(ry); | ||||
| rot_z_mat[0][0] = cos(rz); | rot_z_mat[0][0] = cos(rz); | ||||
| rot_z_mat[1][0] = -sin(rz); | rot_z_mat[1][0] = -sin(rz); | ||||
| rot_z_mat[0][1] = sin(rz); | rot_z_mat[0][1] = sin(rz); | ||||
| rot_z_mat[1][1] = cos(rz); | rot_z_mat[1][1] = cos(rz); | ||||
| } | } | ||||
| /* Recompute transform matrix of object in new coordinate system | /* Convert matrix from Z=up to Y=up or vice versa. Use yup_mat = zup_mat for in-place conversion. */ | ||||
| * (from Y-Up to Z-Up). */ | void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMode mode) | ||||
| void create_transform_matrix(float r_mat[4][4]) | |||||
| { | { | ||||
| 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 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(src_trans); | ||||
| zero_v3(scale); | zero_v3(dst_scale); | ||||
| zero_v3(src_scale); | |||||
| zero_v3(euler); | zero_v3(euler); | ||||
| unit_m3(rot); | unit_m3(src_rot); | ||||
| unit_m3(rot_mat); | unit_m3(dst_rot); | ||||
| unit_m4(scale_mat); | unit_m4(dst_scale_mat); | ||||
| unit_m4(transform_mat); | |||||
| unit_m4(invmat); | /* We assume there is no sheer component and no homogeneous scaling component. */ | ||||
| BLI_assert(fabs(src_mat[0][3]) < 2 * FLT_EPSILON); | |||||
| /* Compute rotation matrix. */ | 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); | |||||
dfelinto: please don't promote our floats to double ;) | |||||
| /* Extract location, rotation, and scale from matrix. */ | /* Extract translation, rotation, and scale form matrix. */ | ||||
| mat4_to_loc_rot_size(loc, rot, scale, r_mat); | mat4_to_loc_rot_size(src_trans, src_rot, src_scale, src_mat); | ||||
| /* Get euler angles from rotation matrix. */ | /* 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 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_ZUP_FROM_YUP); | |||||
| /* Concatenate rotation matrices. */ | /* Concatenate rotation matrices. */ | ||||
| mul_m3_m3m3(rot_mat, rot_mat, rot_y_mat); | mul_m3_m3m3(dst_rot, dst_rot, rot_y_mat); | ||||
| mul_m3_m3m3(rot_mat, rot_mat, rot_z_mat); | mul_m3_m3m3(dst_rot, dst_rot, rot_z_mat); | ||||
| mul_m3_m3m3(rot_mat, rot_mat, rot_x_mat); | mul_m3_m3m3(dst_rot, dst_rot, rot_x_mat); | ||||
| /* Add rotation matrix to transformation matrix. */ | mat3_to_eulO(euler, ROT_MODE_XYZ, dst_rot); | ||||
| copy_m4_m3(transform_mat, rot_mat); | |||||
| /* Start construction of dst_mat from rotation matrix */ | |||||
| /* Add translation to transformation matrix. */ | unit_m4(dst_mat); | ||||
| copy_zup_from_yup(transform_mat[3], loc); | copy_m4_m3(dst_mat, dst_rot); | ||||
| /* Create scale matrix. */ | /* Apply translation */ | ||||
| scale_mat[0][0] = scale[0]; | switch(mode) { | ||||
| scale_mat[1][1] = scale[2]; | case ABC_ZUP_FROM_YUP: | ||||
| scale_mat[2][2] = scale[1]; | 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. */ | /* Apply scale matrix. Swaps y and z, but does not | ||||
Done Inline ActionsBad code style, should indent "case", see https://wiki.blender.org/index.php/Dev:Doc/Code_Style dfelinto: Bad code style, should indent "case", see https://wiki.blender.org/index.php/Dev:Doc/Code_Style | |||||
| mul_m4_m4m4(transform_mat, transform_mat, scale_mat); | * 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, | void convert_matrix(const Imath::M44d &xform, Object *ob, float r_mat[4][4]) | ||||
| float r_mat[4][4], float scale, bool has_alembic_parent) | |||||
| { | { | ||||
| for (int i = 0; i < 4; ++i) { | for (int i = 0; i < 4; ++i) { | ||||
| for (int j = 0; j < 4; ++j) { | for (int j = 0; j < 4; ++j) { | ||||
| r_mat[i][j] = static_cast<float>(xform[i][j]); | r_mat[i][j] = static_cast<float>(xform[i][j]); | ||||
| } | } | ||||
| } | } | ||||
| if (ob->type == OB_CAMERA) { | if (ob->type == OB_CAMERA) { | ||||
| float cam_to_yup[4][4]; | float cam_to_yup[4][4]; | ||||
| axis_angle_to_mat4_single(cam_to_yup, 'X', M_PI_2); | axis_angle_to_mat4_single(cam_to_yup, 'X', M_PI_2); | ||||
| mul_m4_m4m4(r_mat, r_mat, cam_to_yup); | 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); | ||||
Done Inline Actionspossibly move to caller? dfelinto: possibly move to caller? | |||||
| 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); | |||||
| } | |||||
| } | } | ||||
| /* Recompute transform matrix of object in new coordinate system (from Z-Up to Y-Up). */ | /* Recompute transform matrix of object in new coordinate system | ||||
| void create_transform_matrix(Object *obj, float transform_mat[4][4]) | * (from Z-Up to Y-Up). */ | ||||
| void create_transform_matrix(Object *obj, float r_yup_mat[4][4]) | |||||
Done Inline Actionsconsider using r_ prefix for returning matrix dfelinto: consider using r_ prefix for returning matrix | |||||
| { | { | ||||
| float rot_mat[3][3], rot[3][3], scale_mat[4][4], invmat[4][4], mat[4][4]; | float zup_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); | |||||
| /* get local matrix. */ | /* 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) { | if (obj->parent) { | ||||
| invert_m4_m4(invmat, obj->parent->obmat); | /* Note that this produces another matrix than the local matrix, due to | ||||
| mul_m4_m4m4(mat, invmat, obj->obmat); | * 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 { | 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) | bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name) | ||||
| { | { | ||||
| if (!prop.valid()) { | if (!prop.valid()) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | #endif | ||||
| } | } | ||||
| else if (Alembic::AbcGeom::IFaceSet::matches(md)) { | else if (Alembic::AbcGeom::IFaceSet::matches(md)) { | ||||
| /* Pass, those are handled in the mesh reader. */ | /* Pass, those are handled in the mesh reader. */ | ||||
| } | } | ||||
| else if (Alembic::AbcGeom::ICurves::matches(md)) { | else if (Alembic::AbcGeom::ICurves::matches(md)) { | ||||
| reader = new AbcCurveReader(object, settings); | reader = new AbcCurveReader(object, settings); | ||||
| } | } | ||||
| else { | else { | ||||
| assert(false); | std::cerr << "Alembic: unknown how to handle objects of schema " | ||||
| << md.get("schemaObjTitle") | |||||
| << ", skipping object " | |||||
| << object.getFullName() << std::endl; | |||||
| } | } | ||||
| return reader; | return reader; | ||||
| } | } | ||||
please don't promote our floats to double ;)