Add Chromium-only Blender WebEngine parity work
This commit is contained in:
203
blender-5.2.0/source/blender/sequencer/intern/animation.cc
Normal file
203
blender-5.2.0/source/blender/sequencer/intern/animation.cc
Normal file
@@ -0,0 +1,203 @@
|
||||
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup sequencer
|
||||
*/
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
|
||||
#include "BKE_fcurve.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
#include "SEQ_animation.hh"
|
||||
|
||||
namespace blender::seq {
|
||||
|
||||
bool animation_keyframes_exist(const Scene *scene)
|
||||
{
|
||||
return scene->adt != nullptr && scene->adt->action != nullptr &&
|
||||
scene->adt->action->wrap().has_keyframes(scene->adt->slot_handle);
|
||||
}
|
||||
|
||||
bool animation_drivers_exist(Scene *scene)
|
||||
{
|
||||
return scene->adt != nullptr && !scene->adt->drivers.is_empty();
|
||||
}
|
||||
|
||||
bool fcurve_matches(const Strip &strip, const FCurve &fcurve)
|
||||
{
|
||||
return animrig::fcurve_matches_collection_path(
|
||||
fcurve, "sequence_editor.strips_all[", strip.name + 2);
|
||||
}
|
||||
|
||||
void offset_animdata(const Scene *scene, Strip *strip, float ofs)
|
||||
{
|
||||
if (!animation_keyframes_exist(scene) || ofs == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<FCurve *> fcurves = animrig::fcurves_in_action_slot_filtered(
|
||||
scene->adt->action, scene->adt->slot_handle, [&](const FCurve &fcurve) {
|
||||
return fcurve_matches(*strip, fcurve);
|
||||
});
|
||||
|
||||
for (FCurve *fcu : fcurves) {
|
||||
uint i;
|
||||
if (fcu->bezt) {
|
||||
for (i = 0; i < fcu->totvert; i++) {
|
||||
BezTriple *bezt = &fcu->bezt[i];
|
||||
bezt->vec[0][0] += ofs;
|
||||
bezt->vec[1][0] += ofs;
|
||||
bezt->vec[2][0] += ofs;
|
||||
}
|
||||
}
|
||||
if (fcu->fpt) {
|
||||
for (i = 0; i < fcu->totvert; i++) {
|
||||
FPoint *fpt = &fcu->fpt[i];
|
||||
fpt->vec[0] += ofs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&scene->adt->action->id, ID_RECALC_ANIMATION);
|
||||
}
|
||||
|
||||
void free_animdata(Scene *scene, Strip *strip)
|
||||
{
|
||||
if (!animation_keyframes_exist(scene)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<FCurve *> fcurves = animrig::fcurves_in_action_slot_filtered(
|
||||
scene->adt->action, scene->adt->slot_handle, [&](const FCurve &fcurve) {
|
||||
return fcurve_matches(*strip, fcurve);
|
||||
});
|
||||
|
||||
animrig::Action &action = scene->adt->action->wrap();
|
||||
for (FCurve *fcu : fcurves) {
|
||||
action_fcurve_remove(action, *fcu);
|
||||
}
|
||||
}
|
||||
|
||||
void animation_backup_original(Scene *scene, AnimationBackup *backup)
|
||||
{
|
||||
if (animation_keyframes_exist(scene)) {
|
||||
animrig::Action &action = scene->adt->action->wrap();
|
||||
|
||||
assert_baklava_phase_1_invariants(action);
|
||||
|
||||
if (animrig::Channelbag *channelbag = animrig::channelbag_for_action_slot(
|
||||
action, scene->adt->slot_handle))
|
||||
{
|
||||
animrig::channelbag_fcurves_move(backup->channelbag, *channelbag);
|
||||
}
|
||||
}
|
||||
|
||||
if (animation_drivers_exist(scene)) {
|
||||
BLI_movelisttolist(&backup->drivers, &scene->adt->drivers);
|
||||
}
|
||||
}
|
||||
|
||||
void animation_restore_original(Scene *scene, AnimationBackup *backup)
|
||||
{
|
||||
if (!backup->channelbag.fcurves().is_empty()) {
|
||||
BLI_assert(scene->adt != nullptr && scene->adt->action != nullptr);
|
||||
|
||||
animrig::Action &action = scene->adt->action->wrap();
|
||||
|
||||
assert_baklava_phase_1_invariants(action);
|
||||
|
||||
animrig::Channelbag *channelbag = animrig::channelbag_for_action_slot(action,
|
||||
scene->adt->slot_handle);
|
||||
/* The channel bag should exist if we got here, because otherwise the
|
||||
* backup channel bag would have been empty. */
|
||||
BLI_assert(channelbag != nullptr);
|
||||
|
||||
animrig::channelbag_fcurves_move(*channelbag, backup->channelbag);
|
||||
}
|
||||
|
||||
if (!backup->drivers.is_empty()) {
|
||||
BLI_assert(scene->adt != nullptr);
|
||||
BLI_movelisttolist(&scene->adt->drivers, &backup->drivers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the animation in `src` that matches items in `strip` into `dst`.
|
||||
*/
|
||||
static void strip_animation_duplicate(Strip *strip,
|
||||
animrig::Action &dst,
|
||||
const animrig::slot_handle_t dst_slot_handle,
|
||||
AnimationBackup *src)
|
||||
{
|
||||
if (strip->type == STRIP_TYPE_META) {
|
||||
for (Strip &meta_child : strip->seqbase) {
|
||||
strip_animation_duplicate(&meta_child, dst, dst_slot_handle, src);
|
||||
}
|
||||
}
|
||||
|
||||
Vector<FCurve *> fcurves = animrig::fcurves_in_span_filtered(
|
||||
src->channelbag.fcurves(),
|
||||
[&](const FCurve &fcurve) { return fcurve_matches(*strip, fcurve); });
|
||||
|
||||
for (const FCurve *fcu : fcurves) {
|
||||
FCurve *fcu_copy = BKE_fcurve_copy(fcu);
|
||||
|
||||
/* Handling groups properly requires more work, so we ignore them for now.
|
||||
*
|
||||
* Note that when legacy actions are deprecated, then we can handle channel
|
||||
* groups way more easily because we know they're stored in the
|
||||
* already-duplicated channelbag in `src`, and we therefore don't have to
|
||||
* worry that they might have already been freed. */
|
||||
fcu_copy->grp = nullptr;
|
||||
|
||||
animrig::action_fcurve_attach(dst, dst_slot_handle, *fcu_copy, std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the drivers in `src` that matches items in `strip` into `dst`.
|
||||
*/
|
||||
static void strip_drivers_duplicate(Strip *strip, AnimData *dst, AnimationBackup *src)
|
||||
{
|
||||
if (strip->type == STRIP_TYPE_META) {
|
||||
for (Strip &meta_child : strip->seqbase) {
|
||||
strip_drivers_duplicate(&meta_child, dst, src);
|
||||
}
|
||||
}
|
||||
|
||||
Vector<FCurve *> fcurves = animrig::fcurves_in_listbase_filtered(
|
||||
src->drivers, [&](const FCurve &fcurve) { return fcurve_matches(*strip, fcurve); });
|
||||
|
||||
for (const FCurve *fcu : fcurves) {
|
||||
FCurve *fcu_cpy = BKE_fcurve_copy(fcu);
|
||||
BLI_addtail(&dst->drivers, fcu_cpy);
|
||||
}
|
||||
}
|
||||
|
||||
void animation_duplicate_backup_to_scene(Scene *scene, Strip *strip, AnimationBackup *backup)
|
||||
{
|
||||
BLI_assert(scene != nullptr);
|
||||
|
||||
if (!backup->channelbag.fcurves().is_empty()) {
|
||||
BLI_assert(scene->adt != nullptr);
|
||||
BLI_assert(scene->adt->action != nullptr);
|
||||
strip_animation_duplicate(strip, scene->adt->action->wrap(), scene->adt->slot_handle, backup);
|
||||
}
|
||||
|
||||
if (!backup->drivers.is_empty()) {
|
||||
BLI_assert(scene->adt != nullptr);
|
||||
strip_drivers_duplicate(strip, scene->adt, backup);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::seq
|
||||
Reference in New Issue
Block a user