diff options
Diffstat (limited to 'source/blender/blenkernel/intern/action.c')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 7403b7f2109..842902b51ed 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -51,6 +51,7 @@ #include "BKE_anim_visualization.h" #include "BKE_animsys.h" #include "BKE_armature.h" +#include "BKE_asset.h" #include "BKE_constraint.h" #include "BKE_deform.h" #include "BKE_fcurve.h" @@ -286,6 +287,30 @@ static void action_blend_read_expand(BlendExpander *expander, ID *id) } } +static IDProperty *action_asset_type_property(const bAction *action) +{ + const bool is_single_frame = !BKE_action_has_single_frame(action); + + IDPropertyTemplate idprop = {0}; + idprop.i = is_single_frame; + + IDProperty *property = IDP_New(IDP_INT, &idprop, "is_single_frame"); + return property; +} + +static void action_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_data) +{ + bAction *action = (bAction *)asset_ptr; + BLI_assert(GS(action->id.name) == ID_AC); + + IDProperty *action_type = action_asset_type_property(action); + BKE_asset_metadata_idprop_ensure(asset_data, action_type); +} + +AssetTypeInfo AssetType_AC = { + /* pre_save_fn */ action_asset_pre_save, +}; + IDTypeInfo IDType_ID_AC = { .id_code = ID_AC, .id_filter = FILTER_ID_AC, @@ -312,6 +337,8 @@ IDTypeInfo IDType_ID_AC = { .blend_read_undo_preserve = NULL, .lib_override_apply_post = NULL, + + .asset_type_info = &AssetType_AC, }; /* ***************** Library data level operations on action ************** */ @@ -1418,6 +1445,47 @@ bool action_has_motion(const bAction *act) return false; } +bool BKE_action_has_single_frame(const struct bAction *act) +{ + if (act == NULL || BLI_listbase_is_empty(&act->curves)) { + return false; + } + + bool found_key = false; + float found_key_frame = 0.0f; + + LISTBASE_FOREACH (FCurve *, fcu, &act->curves) { + switch (fcu->totvert) { + case 0: + /* No keys, so impossible to come to a conclusion on this curve alone. */ + continue; + case 1: + /* Single key, which is the complex case, so handle below. */ + break; + default: + /* Multiple keys, so there is animation. */ + return false; + } + + const float this_key_frame = fcu->bezt != NULL ? fcu->bezt[0].vec[1][0] : fcu->fpt[0].vec[0]; + if (!found_key) { + found_key = true; + found_key_frame = this_key_frame; + continue; + } + + /* The graph editor rounds to 1/1000th of a frame, so it's not necessary to be really precise + * with these comparisons. */ + if (!compare_ff(found_key_frame, this_key_frame, 0.001f)) { + /* This key differs from the already-found key, so this Action represents animation. */ + return false; + } + } + + /* There is only a single frame if we found at least one key. */ + return found_key; +} + /* Calculate the extents of given action */ void calc_action_range(const bAction *act, float *start, float *end, short incl_modifiers) { |