diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2021-11-11 19:51:38 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2021-11-12 16:36:22 +0300 |
commit | b4cfe80547244e69017bb9c8432a4b18c21b5a6b (patch) | |
tree | d755d8fbe10634f2763fd66426df75824b76b382 /source/blender/blenkernel/intern/action_test.cc | |
parent | 5f7d5c0809104bf702dff4be1b706c6841095fda (diff) |
Assets: Store Action sub-type in asset metadata
Blender 3.0 will only support single-frame Actions in the pose library.
The goal of this patch is to lay the groundwork for making it possible
for the Asset Browser to reject/hide "animation snippet" Action assets.
Determining whether an Action has one or more frames (i.e. whether it
has a single pose or animation) requires inspecting the Action itself,
and thus loading the data-block itself. This would make it impossible to
quickly determine from the asset browser.
To solve this, the Action is inspected before saving, and a
`"is_single_frame"` boolean (well, 0/1 integer) IDProperty is added.
Reviewed by: Severin
Differential Revision: https://developer.blender.org/D13202
Diffstat (limited to 'source/blender/blenkernel/intern/action_test.cc')
-rw-r--r-- | source/blender/blenkernel/intern/action_test.cc | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/action_test.cc b/source/blender/blenkernel/intern/action_test.cc index c02eca966ad..c0d9a4c6055 100644 --- a/source/blender/blenkernel/intern/action_test.cc +++ b/source/blender/blenkernel/intern/action_test.cc @@ -24,6 +24,8 @@ #include "BLI_listbase.h" +#include "MEM_guardedalloc.h" + #include "testing/testing.h" namespace blender::bke::tests { @@ -141,4 +143,97 @@ TEST(action_groups, ReconstructGroupsWithReordering) EXPECT_EQ(groupDcurve2.next, nullptr); } +namespace { + +/* Allocate fcu->bezt, and also return a unique_ptr to it for easily freeing the memory. */ +std::unique_ptr<BezTriple[]> allocate_keyframes(FCurve *fcu, const size_t num_keyframes) +{ + auto bezt_uptr = std::make_unique<BezTriple[]>(num_keyframes); + fcu->bezt = bezt_uptr.get(); + return bezt_uptr; +} + +/* Append keyframe, assumes that fcu->bezt is allocated and has enough space. */ +void add_keyframe(FCurve *fcu, float x, float y) +{ + /* The insert_keyframe functions are in the editors, so we cannot link to those here. */ + BezTriple the_keyframe; + memset(&the_keyframe, 0, sizeof(the_keyframe)); + + /* Copied from insert_vert_fcurve() in keyframing.c. */ + the_keyframe.vec[0][0] = x - 1.0f; + the_keyframe.vec[0][1] = y; + the_keyframe.vec[1][0] = x; + the_keyframe.vec[1][1] = y; + the_keyframe.vec[2][0] = x + 1.0f; + the_keyframe.vec[2][1] = y; + + memcpy(&fcu->bezt[fcu->totvert], &the_keyframe, sizeof(the_keyframe)); + fcu->totvert++; +} + +} // namespace + +TEST(action_assets, BKE_action_has_single_frame) +{ + /* NULL action. */ + EXPECT_FALSE(BKE_action_has_single_frame(nullptr)) << "NULL Action cannot have a single frame."; + + /* No FCurves. */ + { + const bAction empty = {nullptr}; + EXPECT_FALSE(BKE_action_has_single_frame(&empty)) + << "Action without FCurves cannot have a single frame."; + } + + /* One curve with one key. */ + { + FCurve fcu = {nullptr}; + std::unique_ptr<BezTriple[]> bezt = allocate_keyframes(&fcu, 1); + add_keyframe(&fcu, 1.0f, 2.0f); + + bAction action = {nullptr}; + BLI_addtail(&action.curves, &fcu); + + EXPECT_TRUE(BKE_action_has_single_frame(&action)) + << "Action with one FCurve and one key should have single frame."; + } + + /* Two curves with one key each. */ + { + FCurve fcu1 = {nullptr}; + FCurve fcu2 = {nullptr}; + std::unique_ptr<BezTriple[]> bezt1 = allocate_keyframes(&fcu1, 1); + std::unique_ptr<BezTriple[]> bezt2 = allocate_keyframes(&fcu2, 1); + add_keyframe(&fcu1, 1.0f, 327.0f); + add_keyframe(&fcu2, 1.0f, 47.0f); /* Same X-coordinate as the other one. */ + + bAction action = {nullptr}; + BLI_addtail(&action.curves, &fcu1); + BLI_addtail(&action.curves, &fcu2); + + EXPECT_TRUE(BKE_action_has_single_frame(&action)) + << "Two FCurves with keys on the same frame should have single frame."; + + /* Modify the 2nd curve so it's keyed on a different frame. */ + fcu2.bezt[0].vec[1][0] = 2.0f; + EXPECT_FALSE(BKE_action_has_single_frame(&action)) + << "Two FCurves with keys on different frames should have animation."; + } + + /* One curve with two keys. */ + { + FCurve fcu = {nullptr}; + std::unique_ptr<BezTriple[]> bezt = allocate_keyframes(&fcu, 2); + add_keyframe(&fcu, 1.0f, 2.0f); + add_keyframe(&fcu, 2.0f, 2.5f); + + bAction action = {nullptr}; + BLI_addtail(&action.curves, &fcu); + + EXPECT_FALSE(BKE_action_has_single_frame(&action)) + << "Action with one FCurve and two keys must have animation."; + } +} + } // namespace blender::bke::tests |