diff options
author | Alexander Gavrilov <angavrilov@gmail.com> | 2020-12-11 19:17:39 +0300 |
---|---|---|
committer | Alexander Gavrilov <angavrilov@gmail.com> | 2021-06-18 18:56:03 +0300 |
commit | 682a74e0909ba4e669a3f282b3bc5da0ae81e4da (patch) | |
tree | 85aecf8652ddc680973a8cf9eed3a5b60b8a36d7 /source/blender/blenloader | |
parent | aee04d496035c2b11b640a91b2e7eca86e878cf2 (diff) |
Armature: add B-Bone Y scale channel and extra flag fields to DNA.
In addition to the base bone transformation itself, B-Bones have
controls that affect transformation of its segments. For rotation
the features are quite complete, allowing to both reorient the
Bezier handles via properties, and to control them using custom
handle bones. However for scaling there are two deficiencies.
First, there are only X and Y scale factors (actually X and Z),
while lengthwise all segments have the same scaling. The ease
option merely affects the shape of the curve, and does not cause
actual scaling.
Second, scaling can only be controlled via properties, thus
requiring up to 6 drivers per joint between B-Bones to transfer
scaling factors from the handle bone. This is very inefficient.
Finally, the Z channels are confusingly called Y.
This commit adds a B-Bone Y Scale channel and extra B-Bone flag
fields to DNA with appropriate versioning (including for F-Curves
and drivers) in preparation to addressing these limitations.
Functionality is not changed, so the new fields are not used
until the following commits.
Differential Revision: https://developer.blender.org/D9870
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/intern/versioning_270.c | 8 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 8 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_300.c | 109 |
3 files changed, 117 insertions, 8 deletions
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 289092f7f19..776f6c54363 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -263,8 +263,8 @@ static void do_version_action_editor_properties_region(ListBase *regionbase) static void do_version_bones_super_bbone(ListBase *lb) { LISTBASE_FOREACH (Bone *, bone, lb) { - bone->scale_in_x = bone->scale_in_y = 1.0f; - bone->scale_out_x = bone->scale_out_y = 1.0f; + bone->scale_in_x = bone->scale_in_z = 1.0f; + bone->scale_out_x = bone->scale_out_z = 1.0f; do_version_bones_super_bbone(&bone->childbase); } @@ -1268,8 +1268,8 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain) if (ob->pose) { LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { /* see do_version_bones_super_bbone()... */ - pchan->scale_in_x = pchan->scale_in_y = 1.0f; - pchan->scale_out_x = pchan->scale_out_y = 1.0f; + pchan->scale_in_x = pchan->scale_in_z = 1.0f; + pchan->scale_out_x = pchan->scale_out_z = 1.0f; /* also make sure some legacy (unused for over a decade) flags are unset, * so that we can reuse them for stuff that matters now... diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index c9f0cb62fcb..bf8f7eeca5c 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -709,8 +709,8 @@ static void do_versions_area_ensure_tool_region(Main *bmain, static void do_version_bones_split_bbone_scale(ListBase *lb) { LISTBASE_FOREACH (Bone *, bone, lb) { - bone->scale_in_y = bone->scale_in_x; - bone->scale_out_y = bone->scale_out_x; + bone->scale_in_z = bone->scale_in_x; + bone->scale_out_z = bone->scale_out_x; do_version_bones_split_bbone_scale(&bone->childbase); } @@ -3969,8 +3969,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) LISTBASE_FOREACH (Object *, ob, &bmain->objects) { if (ob->pose) { LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { - pchan->scale_in_y = pchan->scale_in_x; - pchan->scale_out_y = pchan->scale_out_x; + pchan->scale_in_z = pchan->scale_in_x; + pchan->scale_out_z = pchan->scale_out_x; } } } diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 268598ccc51..bdefe51f635 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -25,12 +25,16 @@ #include "BLI_string.h" #include "BLI_utildefines.h" +#include "DNA_anim_types.h" +#include "DNA_armature_types.h" #include "DNA_brush_types.h" #include "DNA_genfile.h" #include "DNA_listBase.h" #include "DNA_modifier_types.h" #include "DNA_text_types.h" +#include "BKE_animsys.h" +#include "BKE_fcurve_driver.h" #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_node.h" @@ -38,6 +42,8 @@ #include "BLO_readfile.h" #include "readfile.h" +#include "MEM_guardedalloc.h" + static void sort_linked_ids(Main *bmain) { ListBase *lb; @@ -186,6 +192,83 @@ static void version_node_socket_name(bNodeTree *ntree, } } +static bool replace_bbone_len_scale_rnapath(char **p_old_path, int *p_index) +{ + char *old_path = *p_old_path; + + if (old_path == NULL) { + return false; + } + + int len = strlen(old_path); + + if (BLI_str_endswith(old_path, ".bbone_curveiny") || + BLI_str_endswith(old_path, ".bbone_curveouty")) { + old_path[len - 1] = 'z'; + return true; + } + + if (BLI_str_endswith(old_path, ".bbone_scaleinx") || + BLI_str_endswith(old_path, ".bbone_scaleiny") || + BLI_str_endswith(old_path, ".bbone_scaleoutx") || + BLI_str_endswith(old_path, ".bbone_scaleouty")) { + int index = (old_path[len - 1] == 'y' ? 2 : 0); + + old_path[len - 1] = 0; + + if (p_index) { + *p_index = index; + } + else { + *p_old_path = BLI_sprintfN("%s[%d]", old_path, index); + MEM_freeN(old_path); + } + + return true; + } + + return false; +} + +static void do_version_bbone_len_scale_fcurve_fix(FCurve *fcu) +{ + /* Update driver variable paths. */ + if (fcu->driver) { + LISTBASE_FOREACH (DriverVar *, dvar, &fcu->driver->variables) { + DRIVER_TARGETS_LOOPER_BEGIN (dvar) { + replace_bbone_len_scale_rnapath(&dtar->rna_path, NULL); + } + DRIVER_TARGETS_LOOPER_END; + } + } + + /* Update F-Curve's path. */ + replace_bbone_len_scale_rnapath(&fcu->rna_path, &fcu->array_index); +} + +static void do_version_bbone_len_scale_animdata_cb(ID *UNUSED(id), + AnimData *adt, + void *UNUSED(wrapper_data)) +{ + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->drivers) { + do_version_bbone_len_scale_fcurve_fix(fcu); + } +} + +static void do_version_bones_bbone_len_scale(ListBase *lb) +{ + LISTBASE_FOREACH (Bone *, bone, lb) { + if (bone->flag & BONE_ADD_PARENT_END_ROLL) { + bone->bbone_flag |= BBONE_ADD_PARENT_END_ROLL; + } + + copy_v3_fl3(bone->scale_in, bone->scale_in_x, 1.0f, bone->scale_in_z); + copy_v3_fl3(bone->scale_out, bone->scale_out_x, 1.0f, bone->scale_out_z); + + do_version_bones_bbone_len_scale(&bone->childbase); + } +} + /* NOLINTNEXTLINE: readability-function-size */ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) { @@ -259,5 +342,31 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + /* Initialize length-wise scale B-Bone settings. */ + if (!DNA_struct_elem_find(fd->filesdna, "Bone", "int", "bbone_flag")) { + /* Update armature data and pose channels. */ + LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) { + do_version_bones_bbone_len_scale(&arm->bonebase); + } + + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + if (ob->pose) { + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { + copy_v3_fl3(pchan->scale_in, pchan->scale_in_x, 1.0f, pchan->scale_in_z); + copy_v3_fl3(pchan->scale_out, pchan->scale_out_x, 1.0f, pchan->scale_out_z); + } + } + } + + /* Update action curves and drivers. */ + LISTBASE_FOREACH (bAction *, act, &bmain->actions) { + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &act->curves) { + do_version_bbone_len_scale_fcurve_fix(fcu); + } + } + + BKE_animdata_main_cb(bmain, do_version_bbone_len_scale_animdata_cb, NULL); + } } } |