Anim: Fix pose library flipping with slotted Actions
Building the F-Curve cache used for pose flipping now also works with slotted Actions. Like the pose library itself, it only considers the first slot of the pose asset. Multi-slot pose assets are not supported. Pull Request: https://projects.blender.org/blender/blender/pulls/128992
This commit is contained in:
@@ -49,6 +49,14 @@ ChannelBag &channelbag_ensure(Action &action);
|
||||
Vector<const FCurve *> fcurves_all(const bAction *action);
|
||||
Vector<FCurve *> fcurves_all(bAction *action);
|
||||
|
||||
/**
|
||||
* Return the F-Curves for the first slot of this Action.
|
||||
*
|
||||
* This works for both legacy and layered Actions. For the former, it will
|
||||
* return all F-Curves in the Action.
|
||||
*/
|
||||
Vector<FCurve *> fcurves_first_slot(bAction *action);
|
||||
|
||||
/**
|
||||
* Return the F-Curves for this specific slot handle.
|
||||
*
|
||||
|
||||
@@ -124,6 +124,23 @@ Vector<const FCurve *> fcurves_all(const bAction *action)
|
||||
const ChannelBag>(action->wrap());
|
||||
}
|
||||
|
||||
Vector<FCurve *> fcurves_first_slot(bAction *action)
|
||||
{
|
||||
if (!action) {
|
||||
return {};
|
||||
}
|
||||
Action &action_wrap = action->wrap();
|
||||
|
||||
if (action_wrap.is_action_legacy()) {
|
||||
return fcurves_all(action);
|
||||
}
|
||||
|
||||
if (action_wrap.slots().is_empty()) {
|
||||
return {};
|
||||
}
|
||||
return fcurves_for_action_slot(action, action_wrap.slot(0)->handle);
|
||||
}
|
||||
|
||||
/* Lots of template args to support transparent non-const and const versions. */
|
||||
template<typename ActionType,
|
||||
typename FCurveType,
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
*/
|
||||
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
|
||||
#include "DNA_curve_types.h"
|
||||
|
||||
struct ChannelDriver;
|
||||
@@ -348,7 +350,7 @@ int BKE_fcurve_bezt_binarysearch_index(const BezTriple array[],
|
||||
/**
|
||||
* Cached f-curve look-ups, use when this needs to be done many times.
|
||||
*/
|
||||
FCurvePathCache *BKE_fcurve_pathcache_create(ListBase *list);
|
||||
FCurvePathCache *BKE_fcurve_pathcache_create(blender::Span<FCurve *> fcurves);
|
||||
void BKE_fcurve_pathcache_destroy(FCurvePathCache *fcache);
|
||||
FCurve *BKE_fcurve_pathcache_find(FCurvePathCache *fcache, const char rna_path[], int array_index);
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
using namespace blender;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Flip the Action (Armature/Pose Objects)
|
||||
*
|
||||
@@ -451,7 +453,8 @@ static void action_flip_pchan_rna_paths(bAction *act)
|
||||
|
||||
void BKE_action_flip_with_pose(bAction *act, Object *ob_arm)
|
||||
{
|
||||
FCurvePathCache *fcache = BKE_fcurve_pathcache_create(&act->curves);
|
||||
Vector<FCurve *> fcurves = animrig::legacy::fcurves_first_slot(act);
|
||||
FCurvePathCache *fcache = BKE_fcurve_pathcache_create(fcurves);
|
||||
int i;
|
||||
LISTBASE_FOREACH_INDEX (bPoseChannel *, pchan, &ob_arm->pose->chanbase, i) {
|
||||
action_flip_pchan(ob_arm, pchan, fcache);
|
||||
|
||||
@@ -63,14 +63,13 @@ static int fcurve_cmp_for_cache(const void *fcu_a_p, const void *fcu_b_p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
FCurvePathCache *BKE_fcurve_pathcache_create(ListBase *list)
|
||||
FCurvePathCache *BKE_fcurve_pathcache_create(blender::Span<FCurve *> fcurves)
|
||||
{
|
||||
const uint fcurve_array_len = BLI_listbase_count(list);
|
||||
const uint fcurve_array_len = fcurves.size();
|
||||
FCurve **fcurve_array = static_cast<FCurve **>(
|
||||
MEM_mallocN(sizeof(*fcurve_array) * fcurve_array_len, __func__));
|
||||
uint i;
|
||||
LISTBASE_FOREACH_INDEX (FCurve *, fcu, list, i) {
|
||||
fcurve_array[i] = fcu;
|
||||
for (const int i : fcurves.index_range()) {
|
||||
fcurve_array[i] = fcurves[i];
|
||||
}
|
||||
qsort(fcurve_array, fcurve_array_len, sizeof(FCurve *), fcurve_cmp_for_cache);
|
||||
|
||||
@@ -83,7 +82,7 @@ FCurvePathCache *BKE_fcurve_pathcache_create(ListBase *list)
|
||||
/* May over reserve, harmless. */
|
||||
GHash *span_from_rna_path = BLI_ghash_str_new_ex(__func__, fcurve_array_len);
|
||||
uint span_index = 0;
|
||||
i = 0;
|
||||
uint i = 0;
|
||||
while (i < fcurve_array_len) {
|
||||
uint i_end;
|
||||
for (i_end = i + 1; i_end < fcurve_array_len; i_end++) {
|
||||
|
||||
Reference in New Issue
Block a user