diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index c3ca26efcb7..b4c9cf899f6 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -979,6 +979,9 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel): end = scene.frame_end layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False) + if strip.use_sequence: + layout.prop(strip, "correct_timing") + class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel): bl_label = "Mask" diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 500ece2a735..2e5d17fa707 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -42,6 +42,7 @@ #include "BLI_blenlib.h" #include "BLI_alloca.h" #include "BLI_dynstr.h" +#include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_string_utils.h" @@ -68,6 +69,7 @@ #include "BKE_material.h" #include "BKE_library.h" #include "BKE_report.h" +#include "BKE_scene.h" #include "BKE_texture.h" #include "RNA_access.h" @@ -2789,6 +2791,43 @@ void BKE_animsys_evaluate_animdata(Scene *scene, ID *id, AnimData *adt, float ct adt->recalc = 0; } +static void animate_subscenes(Main *main, Scene *scene, float ctime, LinkNode *unprocessed_scenes) +{ + if (scene->ed && scene->ed->seqbasep) { + Sequence *seq; + + seq = scene->ed->seqbasep->first; + while (seq != NULL) { + if (seq->scene != NULL && + ctime >= seq->start && ctime <= seq->start + seq->len) { + int offset = (seq->flag & SEQ_SCENE_CORRECT_TIMING) ? + seq->scene->r.sfra - seq->start : 0; + animate_subscenes(main, seq->scene, ctime + offset, unprocessed_scenes); + } + seq = seq->next; + } + } + + ID *id = (ID*)scene; + + AnimData *adt = BKE_animdata_from_id(id); + Scene *ntp = scene; + if (ntp->nodetree) { + AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); + BKE_animsys_evaluate_animdata(scene, (ID *)ntp->nodetree, adt2, ctime, ADT_RECALC_ANIM); + } + BKE_animsys_evaluate_animdata(scene, id, adt, ctime, ADT_RECALC_ANIM); + + /* Remove this scene from the list; we just set the pointer to NULL, the + * list will be automatically freed later. */ + for (LinkNode *scene_node = unprocessed_scenes; scene_node; scene_node = scene_node->next) { + if (scene_node->link == scene) { + scene_node->link = NULL; + break; + } + } +} + /* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only * * This will evaluate only the animation info available in the animation data-blocks @@ -2915,7 +2954,30 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime) EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM); /* scenes */ - EVAL_ANIM_NODETREE_IDS(main->scene.first, Scene, ADT_RECALC_ANIM); + /* In order to properly time the animations of scenes used in the VSE, we + * first process those -- with the proper ctime -- and then all the others. + * In order to keep track of which scenes we've already visited, we build a + * list of scenes. */ + LinkNode *unprocessed_scenes = NULL; + for (id = main->scene.first; id; id = id->next) { + if (ID_REAL_USERS(id) > 0) { + BLI_linklist_prepend_alloca(&unprocessed_scenes, id); + } + } + + animate_subscenes(main, scene, ctime, unprocessed_scenes); + + for (LinkNode *scene_node = unprocessed_scenes; scene_node; scene_node = scene_node->next) { + Scene *s = scene_node->link; + if (!s) continue; + id = (ID*)s; + AnimData *adt = BKE_animdata_from_id(id); + if (s->nodetree) { + AnimData *adt2 = BKE_animdata_from_id((ID *)s->nodetree); + BKE_animsys_evaluate_animdata(scene, (ID *)s->nodetree, adt2, ctime, ADT_RECALC_ANIM); + } + BKE_animsys_evaluate_animdata(scene, id, adt, ctime, ADT_RECALC_ANIM); + } } /* ***************************************** */ diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 386e66a63e0..754773ce854 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -314,6 +314,8 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); seq->len = sce_seq->r.efra - sce_seq->r.sfra + 1; strip->us = 1; + /* always use correct animation timings when creating a new strip (the option is only to preserve compatibility with old files) */ + seq->flag |= SEQ_SCENE_CORRECT_TIMING; BLI_strncpy(seq->name + 2, sce_seq->id.name + 2, sizeof(seq->name) - 2); BKE_sequence_base_unique_name_recursive(&ed->seqbase, seq); diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 6e2fd412445..5a2d96cfbc6 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -429,7 +429,7 @@ enum { SEQ_USE_CROP = (1 << 17), /* SEQ_USE_COLOR_BALANCE = (1 << 18), */ /* DEPRECATED */ /* SEQ_USE_PROXY_CUSTOM_DIR = (1 << 19), */ /* DEPRECATED */ - + SEQ_SCENE_CORRECT_TIMING = (1 << 20), /* SEQ_USE_PROXY_CUSTOM_FILE = (1 << 21), */ /* DEPRECATED */ SEQ_USE_EFFECT_DEFAULT_FADE = (1 << 22), SEQ_USE_LINEAR_MODIFIERS = (1 << 23), diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 5057d62774d..20c0440913b 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -756,6 +756,22 @@ static void rna_Sequence_sound_update(Main *bmain, Scene *scene, PointerRNA *ptr rna_Sequence_update(bmain, scene, ptr); } +static void rna_Sequence_update_correct_timing(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Scene *scene = (Scene *) ptr->id.data; + Editing *ed = BKE_sequencer_editing_get(scene, false); + + if (ed) { + Sequence *seq = (Sequence *) ptr->data; + + BKE_sequence_invalidate_cache(scene, seq); + + BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); + + do_sequence_frame_change_update(scene, seq); + } +} + static int seqproxy_seq_cmp_cb(Sequence *seq, void *arg_pt) { SequenceSearchData *data = arg_pt; @@ -1971,6 +1987,11 @@ static void rna_def_scene(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Use Sequence", "Use scenes sequence strips directly, instead of rendering"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); + prop = RNA_def_property(srna, "correct_timing", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SCENE_CORRECT_TIMING); + RNA_def_property_ui_text(prop, "Correct Timing", "Preserve relative timings of animations in subscene"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update_correct_timing"); + prop = RNA_def_property(srna, "use_grease_pencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_SCENE_NO_GPENCIL); RNA_def_property_ui_text(prop, "Use Grease Pencil", "Show Grease Pencil strokes in OpenGL previews");