Refactor: Move Pose code out of the kernel
Move the functions * `BKE_pose_apply_action_selected_bones` * `BKE_pose_apply_action_all_bones` * and `BKE_pose_apply_action_blend` out of the blender kernel and into animrig. This will allow solving #126969 without having to include animrig code in the blender kernel. Pull Request: https://projects.blender.org/blender/blender/pulls/126978
This commit is contained in:
committed by
Christoph Lendenfeld
parent
938e50a3ed
commit
a661a7bf89
37
source/blender/animrig/ANIM_pose.hh
Normal file
37
source/blender/animrig/ANIM_pose.hh
Normal file
@@ -0,0 +1,37 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup animrig
|
||||
*
|
||||
* \brief Functions to work with animation poses.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct AnimationEvalContext;
|
||||
struct Object;
|
||||
struct bAction;
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
/**
|
||||
* Evaluate the action and apply it to the pose. If any pose bones are selected, only FCurves that
|
||||
* relate to those bones are evaluated.
|
||||
*/
|
||||
void pose_apply_action_selected_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context);
|
||||
/**
|
||||
* Evaluate the action and apply it to the pose. Ignore selection state of the bones.
|
||||
*/
|
||||
void pose_apply_action_all_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context);
|
||||
|
||||
void pose_apply_action_blend(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context,
|
||||
float blend_factor);
|
||||
} // namespace blender::animrig
|
||||
@@ -34,6 +34,7 @@ set(SRC
|
||||
intern/fcurve.cc
|
||||
intern/keyframing.cc
|
||||
intern/keyframing_auto.cc
|
||||
intern/pose.cc
|
||||
intern/visualkey.cc
|
||||
|
||||
ANIM_action.hh
|
||||
@@ -48,6 +49,7 @@ set(SRC
|
||||
ANIM_fcurve.hh
|
||||
ANIM_keyframing.hh
|
||||
ANIM_keyingsets.hh
|
||||
ANIM_pose.hh
|
||||
ANIM_rna.hh
|
||||
ANIM_visualkey.hh
|
||||
intern/action_runtime.hh
|
||||
|
||||
@@ -1,79 +1,45 @@
|
||||
/* SPDX-FileCopyrightText: 2015 Blender Authors
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
* \ingroup animrig
|
||||
*/
|
||||
|
||||
#include "ANIM_pose.hh"
|
||||
#include "BKE_action.hh"
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.hh"
|
||||
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
|
||||
using namespace blender::bke;
|
||||
|
||||
namespace {
|
||||
|
||||
using ActionApplier =
|
||||
blender::FunctionRef<void(PointerRNA *, bAction *, const AnimationEvalContext *)>;
|
||||
|
||||
/* Forward declarations. */
|
||||
void pose_apply_disable_fcurves_for_unselected_bones(bAction *action,
|
||||
const BoneNameSet &selected_bone_names);
|
||||
void pose_apply_restore_fcurves(bAction *action);
|
||||
|
||||
void pose_apply(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context,
|
||||
ActionApplier applier);
|
||||
|
||||
} // namespace
|
||||
|
||||
void BKE_pose_apply_action_selected_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context)
|
||||
void pose_apply_restore_fcurves(bAction *action)
|
||||
{
|
||||
auto evaluate_and_apply =
|
||||
[](PointerRNA *ptr, bAction *act, const AnimationEvalContext *anim_eval_context) {
|
||||
animsys_evaluate_action(ptr, act, anim_eval_context, false);
|
||||
};
|
||||
|
||||
pose_apply(ob, action, anim_eval_context, evaluate_and_apply);
|
||||
/* TODO(Sybren): Restore the FCurve flags, instead of just erasing the 'disabled' flag. */
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &action->curves) {
|
||||
fcu->flag &= ~FCURVE_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_pose_apply_action_all_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context)
|
||||
void pose_apply_disable_fcurves_for_unselected_bones(
|
||||
bAction *action, const blender::bke::BoneNameSet &selected_bone_names)
|
||||
{
|
||||
PointerRNA pose_owner_ptr = RNA_id_pointer_create(&ob->id);
|
||||
animsys_evaluate_action(&pose_owner_ptr, action, anim_eval_context, false);
|
||||
}
|
||||
|
||||
void BKE_pose_apply_action_blend(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context,
|
||||
const float blend_factor)
|
||||
{
|
||||
auto evaluate_and_blend = [blend_factor](PointerRNA *ptr,
|
||||
bAction *act,
|
||||
const AnimationEvalContext *anim_eval_context) {
|
||||
animsys_blend_in_action(ptr, act, anim_eval_context, blend_factor);
|
||||
auto disable_unselected_fcurve = [&](FCurve *fcu, const char *bone_name) {
|
||||
const bool is_bone_selected = selected_bone_names.contains(bone_name);
|
||||
if (!is_bone_selected) {
|
||||
fcu->flag |= FCURVE_DISABLED;
|
||||
}
|
||||
};
|
||||
|
||||
pose_apply(ob, action, anim_eval_context, evaluate_and_blend);
|
||||
blender::bke::BKE_action_find_fcurves_with_bones(action, disable_unselected_fcurve);
|
||||
}
|
||||
|
||||
namespace {
|
||||
void pose_apply(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context,
|
||||
@@ -85,7 +51,8 @@ void pose_apply(Object *ob,
|
||||
}
|
||||
|
||||
const bArmature *armature = (bArmature *)ob->data;
|
||||
const BoneNameSet selected_bone_names = BKE_armature_find_selected_bone_names(armature);
|
||||
const blender::bke::BoneNameSet selected_bone_names =
|
||||
blender::bke::BKE_armature_find_selected_bone_names(armature);
|
||||
const bool limit_to_selected_bones = !selected_bone_names.is_empty();
|
||||
|
||||
if (limit_to_selected_bones) {
|
||||
@@ -104,24 +71,42 @@ void pose_apply(Object *ob,
|
||||
}
|
||||
}
|
||||
|
||||
void pose_apply_restore_fcurves(bAction *action)
|
||||
{
|
||||
/* TODO(Sybren): Restore the FCurve flags, instead of just erasing the 'disabled' flag. */
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &action->curves) {
|
||||
fcu->flag &= ~FCURVE_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
void pose_apply_disable_fcurves_for_unselected_bones(bAction *action,
|
||||
const BoneNameSet &selected_bone_names)
|
||||
{
|
||||
auto disable_unselected_fcurve = [&](FCurve *fcu, const char *bone_name) {
|
||||
const bool is_bone_selected = selected_bone_names.contains(bone_name);
|
||||
if (!is_bone_selected) {
|
||||
fcu->flag |= FCURVE_DISABLED;
|
||||
}
|
||||
};
|
||||
BKE_action_find_fcurves_with_bones(action, disable_unselected_fcurve);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace blender::animrig {
|
||||
|
||||
void pose_apply_action_selected_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context)
|
||||
{
|
||||
auto evaluate_and_apply =
|
||||
[](PointerRNA *ptr, bAction *act, const AnimationEvalContext *anim_eval_context) {
|
||||
animsys_evaluate_action(ptr, act, anim_eval_context, false);
|
||||
};
|
||||
|
||||
pose_apply(ob, action, anim_eval_context, evaluate_and_apply);
|
||||
}
|
||||
|
||||
void pose_apply_action_all_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context)
|
||||
{
|
||||
PointerRNA pose_owner_ptr = RNA_id_pointer_create(&ob->id);
|
||||
animsys_evaluate_action(&pose_owner_ptr, action, anim_eval_context, false);
|
||||
}
|
||||
|
||||
void pose_apply_action_blend(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context,
|
||||
const float blend_factor)
|
||||
{
|
||||
auto evaluate_and_blend = [blend_factor](PointerRNA *ptr,
|
||||
bAction *act,
|
||||
const AnimationEvalContext *anim_eval_context) {
|
||||
animsys_blend_in_action(ptr, act, anim_eval_context, blend_factor);
|
||||
};
|
||||
|
||||
pose_apply(ob, action, anim_eval_context, evaluate_and_blend);
|
||||
}
|
||||
|
||||
} // namespace blender::animrig
|
||||
@@ -281,25 +281,6 @@ void BKE_pose_where_is_bone(Depsgraph *depsgraph,
|
||||
*/
|
||||
void BKE_pose_where_is_bone_tail(bPoseChannel *pchan);
|
||||
|
||||
/**
|
||||
* Evaluate the action and apply it to the pose. If any pose bones are selected, only FCurves that
|
||||
* relate to those bones are evaluated.
|
||||
*/
|
||||
void BKE_pose_apply_action_selected_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context);
|
||||
/**
|
||||
* Evaluate the action and apply it to the pose. Ignore selection state of the bones.
|
||||
*/
|
||||
void BKE_pose_apply_action_all_bones(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context);
|
||||
|
||||
void BKE_pose_apply_action_blend(Object *ob,
|
||||
bAction *action,
|
||||
const AnimationEvalContext *anim_eval_context,
|
||||
float blend_factor);
|
||||
|
||||
void vec_roll_to_mat3(const float vec[3], float roll, float r_mat[3][3]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,7 +58,6 @@ set(SRC
|
||||
intern/appdir.cc
|
||||
intern/armature.cc
|
||||
intern/armature_deform.cc
|
||||
intern/armature_pose.cc
|
||||
intern/armature_selection.cc
|
||||
intern/armature_update.cc
|
||||
intern/asset.cc
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "ANIM_bone_collections.hh"
|
||||
#include "ANIM_keyframing.hh"
|
||||
#include "ANIM_keyingsets.hh"
|
||||
#include "ANIM_pose.hh"
|
||||
|
||||
#include "armature_intern.hh"
|
||||
|
||||
@@ -193,7 +194,8 @@ static void poselib_blend_apply(bContext *C, wmOperator *op)
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, 0.0f);
|
||||
bAction *to_blend = poselib_action_to_blend(pbd);
|
||||
BKE_pose_apply_action_blend(pbd->ob, to_blend, &anim_eval_context, pbd->blend_factor);
|
||||
blender::animrig::pose_apply_action_blend(
|
||||
pbd->ob, to_blend, &anim_eval_context, pbd->blend_factor);
|
||||
}
|
||||
|
||||
/* ---------------------------- */
|
||||
|
||||
@@ -41,6 +41,7 @@ set(LIB
|
||||
PRIVATE bf::dna
|
||||
bf_draw
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::animrig
|
||||
)
|
||||
|
||||
if(WITH_HEADLESS)
|
||||
|
||||
@@ -97,6 +97,8 @@
|
||||
|
||||
#include "UI_interface_icons.hh"
|
||||
|
||||
#include "ANIM_pose.hh"
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Used for database init assert(). */
|
||||
# include "BLI_threads.h"
|
||||
@@ -963,7 +965,7 @@ static PoseBackup *action_preview_render_prepare(IconPreview *preview)
|
||||
/* Apply the Action as pose, so that it can be rendered. This assumes the Action represents a
|
||||
* single pose, and that thus the evaluation time doesn't matter. */
|
||||
AnimationEvalContext anim_eval_context = {preview->depsgraph, 0.0f};
|
||||
BKE_pose_apply_action_all_bones(object, action, &anim_eval_context);
|
||||
blender::animrig::pose_apply_action_all_bones(object, action, &anim_eval_context);
|
||||
|
||||
/* Force evaluation of the new pose, before the preview is rendered. */
|
||||
DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY);
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
|
||||
# include "BLI_ghash.h"
|
||||
|
||||
# include "ANIM_pose.hh"
|
||||
|
||||
static float rna_PoseBone_do_envelope(bPoseChannel *chan, const float vec[3])
|
||||
{
|
||||
Bone *bone = chan->bone;
|
||||
@@ -125,7 +127,7 @@ static void rna_Pose_apply_pose_from_action(ID *pose_owner,
|
||||
Object *pose_owner_ob = (Object *)pose_owner;
|
||||
|
||||
AnimationEvalContext anim_eval_context = {CTX_data_depsgraph_pointer(C), evaluation_time};
|
||||
BKE_pose_apply_action_selected_bones(pose_owner_ob, action, &anim_eval_context);
|
||||
blender::animrig::pose_apply_action_selected_bones(pose_owner_ob, action, &anim_eval_context);
|
||||
|
||||
/* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */
|
||||
DEG_id_tag_update(pose_owner, ID_RECALC_GEOMETRY);
|
||||
@@ -142,7 +144,8 @@ static void rna_Pose_blend_pose_from_action(ID *pose_owner,
|
||||
Object *pose_owner_ob = (Object *)pose_owner;
|
||||
|
||||
AnimationEvalContext anim_eval_context = {CTX_data_depsgraph_pointer(C), evaluation_time};
|
||||
BKE_pose_apply_action_blend(pose_owner_ob, action, &anim_eval_context, blend_factor);
|
||||
blender::animrig::pose_apply_action_blend(
|
||||
pose_owner_ob, action, &anim_eval_context, blend_factor);
|
||||
|
||||
/* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */
|
||||
DEG_id_tag_update(pose_owner, ID_RECALC_GEOMETRY);
|
||||
|
||||
Reference in New Issue
Block a user