From 48a3f97b23501fd33f6e400b7682ea4cb2988a8a Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 8 Dec 2018 09:17:57 +0300 Subject: RNA: provide access to bone parent transform math from Python. Applying the effect of bone parent is much more complicated than simple matrix multiplication because of the various flags like Inherit Scale. Thus it is reasonable to provide access to this math from Python for complicated rest pose related manipulations. The simple case of this is handled by Object.convert_space, so the new method is only needed for complex tasks. Differential Revision: https://developer.blender.org/D4053 --- source/blender/makesrna/intern/rna_armature_api.c | 55 +++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'source/blender/makesrna/intern/rna_armature_api.c') diff --git a/source/blender/makesrna/intern/rna_armature_api.c b/source/blender/makesrna/intern/rna_armature_api.c index 55caac973d8..cc311fbe1d2 100644 --- a/source/blender/makesrna/intern/rna_armature_api.c +++ b/source/blender/makesrna/intern/rna_armature_api.c @@ -42,6 +42,8 @@ #include +#include "DNA_armature_types.h" + #include "BLI_math_vector.h" #include "BKE_armature.h" @@ -57,6 +59,32 @@ static float rna_Bone_do_envelope(Bone *bone, float *vec) bone->rad_tail * scale, bone->dist * scale); } +static void rna_Bone_convert_local_to_pose(Bone *bone, float *r_matrix, float *matrix, float *matrix_local, float *parent_matrix, float *parent_matrix_local, bool invert) +{ + BoneParentTransform bpt; + float offs_bone[4][4]; + float (*bone_arm_mat)[4] = (float (*)[4])matrix_local; + float (*parent_pose_mat)[4] = (float (*)[4])parent_matrix; + float (*parent_arm_mat)[4] = (float (*)[4])parent_matrix_local; + + if (is_zero_m4(parent_pose_mat) || is_zero_m4(parent_arm_mat)) { + /* No parent case. */ + BKE_calc_bone_parent_transform(bone->flag, bone_arm_mat, NULL, NULL, &bpt); + } + else { + invert_m4_m4(offs_bone, parent_arm_mat); + mul_m4_m4m4(offs_bone, offs_bone, bone_arm_mat); + + BKE_calc_bone_parent_transform(bone->flag, offs_bone, parent_arm_mat, parent_pose_mat, &bpt); + } + + if (invert) { + BKE_invert_bone_parent_transform(&bpt); + } + + BKE_apply_bone_parent_transform(&bpt, (float (*)[4])matrix, (float (*)[4])r_matrix); +} + static void rna_Bone_MatrixFromAxisRoll(float *axis, float roll, float *r_matrix) { vec_roll_to_mat3(axis, roll, (float (*)[3])r_matrix); @@ -103,6 +131,33 @@ void RNA_api_bone(StructRNA *srna) parm = RNA_def_float(func, "factor", 0, -FLT_MAX, FLT_MAX, "Factor", "Envelope factor", -FLT_MAX, FLT_MAX); RNA_def_function_return(func, parm); + func = RNA_def_function(srna, "convert_local_to_pose", "rna_Bone_convert_local_to_pose"); + RNA_def_function_ui_description(func, + "Transform a matrix from Local to Pose space (or back), taking " + "into account options like Inherit Scale and Local Location. " + "Unlike Object.convert_space, this uses custom rest and pose " + "matrices provided by the caller. If the parent matrices are " + "omitted, the bone is assumed to have no parent."); + parm = RNA_def_property(func, "matrix_return", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(parm, "", "The transformed matrix"); + RNA_def_function_output(func, parm); + parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(parm, "", "The matrix to transform"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_property(func, "matrix_local", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(parm, "", "The custom rest matrix of this bone (Bone.matrix_local)"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_property(func, "parent_matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(parm, "", "The custom pose matrix of the parent bone (PoseBone.matrix)"); + parm = RNA_def_property(func, "parent_matrix_local", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(parm, "", "The custom rest matrix of the parent bone (Bone.matrix_local)"); + parm = RNA_def_boolean(func, "invert", false, "", "Convert from Pose to Local space"); + /* Conversions between Matrix and Axis + Roll representations. */ func = RNA_def_function(srna, "MatrixFromAxisRoll", "rna_Bone_MatrixFromAxisRoll"); RNA_def_function_ui_description(func, "Convert the axis + roll representation to a matrix"); -- cgit v1.2.3