tornavis/source/blender/blenkernel/BKE_nla.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

532 lines
18 KiB
C
Raw Normal View History

/* SPDX-FileCopyrightText: 2009 Blender Authors, Joshua Leung. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0-or-later */
2002-10-12 13:37:38 +02:00
#pragma once
2002-10-12 13:37:38 +02:00
/** \file
* \ingroup bke
*/
2022-09-19 06:47:27 +02:00
/** Temp constant defined for these functions only. */
#define NLASTRIP_MIN_LEN_THRESH 0.1f
#include "DNA_listBase.h"
#ifdef __cplusplus
extern "C" {
#endif
struct AnimData;
struct ID;
struct LibraryForeachIDData;
struct Main;
struct NlaStrip;
struct NlaTrack;
struct Scene;
struct Speaker;
struct bAction;
struct BlendDataReader;
2020-09-30 03:51:13 +02:00
struct BlendLibReader;
struct BlendWriter;
struct PointerRNA;
struct PropertyRNA;
/* ----------------------------- */
/* Data Management */
/**
* Create new NLA Track.
* The returned pointer is owned by the caller.
*/
struct NlaTrack *BKE_nlatrack_new(void);
/**
* Frees the given NLA strip, and calls #BKE_nlastrip_remove_and_free to
* remove and free all children strips.
*/
void BKE_nlastrip_free(struct NlaStrip *strip, bool do_id_user);
/**
* Remove & Frees all NLA strips from the given NLA track,
* then frees (doesn't remove) the track itself.
*/
void BKE_nlatrack_free(struct NlaTrack *nlt, bool do_id_user);
/**
* Free the elements of type NLA Tracks provided in the given list, but do not free
* the list itself since that is not free-standing
*/
void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user);
/**
* Copy NLA strip
*
* \param use_same_action: When true, the existing action is used (instead of being duplicated)
* \param flag: Control ID pointers management, see LIB_ID_CREATE_.../LIB_ID_COPY_...
* flags in BKE_lib_id.h
*/
struct NlaStrip *BKE_nlastrip_copy(struct Main *bmain,
struct NlaStrip *strip,
bool use_same_action,
int flag);
/**
* Copy a single NLA Track.
* \param flag: Control ID pointers management, see LIB_ID_CREATE_.../LIB_ID_COPY_...
* flags in BKE_lib_id.h
*/
struct NlaTrack *BKE_nlatrack_copy(struct Main *bmain,
struct NlaTrack *nlt,
bool use_same_actions,
int flag);
/**
* Copy all NLA data.
* \param flag: Control ID pointers management, see LIB_ID_CREATE_.../LIB_ID_COPY_...
* flags in BKE_lib_id.h
*/
void BKE_nla_tracks_copy(struct Main *bmain, ListBase *dst, const ListBase *src, int flag);
/**
* Copy NLA tracks from #adt_source to #adt_dest, and update the active track/strip pointers to
* point at those copies.
*/
void BKE_nla_tracks_copy_from_adt(struct Main *bmain,
struct AnimData *adt_dest,
const struct AnimData *adt_source,
int flag);
/**
* Inserts a given NLA track before a specified NLA track within the
* passed NLA track list.
*/
void BKE_nlatrack_insert_before(ListBase *nla_tracks,
struct NlaTrack *next,
struct NlaTrack *new_track,
bool is_liboverride);
/**
* Inserts a given NLA track after a specified NLA track within the
* passed NLA track list.
*/
void BKE_nlatrack_insert_after(ListBase *nla_tracks,
struct NlaTrack *prev,
struct NlaTrack *new_track,
bool is_liboverride);
/**
* Calls #BKE_nlatrack_new to create a new NLA track, inserts it before the
* given NLA track with #BKE_nlatrack_insert_before.
*/
struct NlaTrack *BKE_nlatrack_new_before(ListBase *nla_tracks,
struct NlaTrack *next,
bool is_liboverride);
/**
* Calls #BKE_nlatrack_new to create a new NLA track, inserts it after the
* given NLA track with #BKE_nlatrack_insert_after.
*/
struct NlaTrack *BKE_nlatrack_new_after(ListBase *nla_tracks,
struct NlaTrack *prev,
bool is_liboverride);
/**
* Calls #BKE_nlatrack_new to create a new NLA track, inserts it as the head of the
* NLA track list with #BKE_nlatrack_new_before.
*/
struct NlaTrack *BKE_nlatrack_new_head(ListBase *nla_tracks, bool is_liboverride);
/**
* Calls #BKE_nlatrack_new to create a new NLA track, inserts it as the tail of the
* NLA track list with #BKE_nlatrack_new_after.
*/
struct NlaTrack *BKE_nlatrack_new_tail(ListBase *nla_tracks, const bool is_liboverride);
/**
* Removes the given NLA track from the list of tracks provided.
*/
void BKE_nlatrack_remove(ListBase *tracks, struct NlaTrack *nlt);
/**
* Remove the given NLA track from the list of NLA tracks, free the track's data,
* and the track itself.
*/
void BKE_nlatrack_remove_and_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user);
/**
* Compute the length of the passed strip's clip, unless the clip length
* is zero in which case a non-zero value is returned.
*
* WARNING: this function is *very narrow* and special-cased in its
* application. It was introduced as part of the fix for issue #107030,
2023-09-27 05:02:37 +02:00
* as a way to collect a bunch of whack-a-mole inline applications of this
* logic in one place. The logic itself isn't principled in any way,
* and should almost certainly not be used anywhere that it isn't already,
2023-09-27 05:02:37 +02:00
* short of one of those whack-a-mole inline places being overlooked.
*
* The underlying purpose of this function is to ensure that the computed
* clip length for an NLA strip is (in certain places) never zero, in order to
* avoid the strip's scale having to be infinity. In other words, it's a
* hack. But at least now it's a hack collected in one place.
*
*/
float BKE_nla_clip_length_get_nonzero(const NlaStrip *strip);
/**
* Ensure the passed range has non-zero length, using the same logic as
* `BKE_nla_clip_length_get_nonzero` to determine the new non-zero length.
*
* See the documentation for `BKE_nla_clip_length_get_nonzero` for the
* reason this function exists and the issues around its use.
*
* Usage: both `actstart` and `r_actend` should already be set to the
* start/end values of a strip's clip. `r_actend` will be modified
* if necessary to ensure the range is non-zero in length.
*/
void BKE_nla_clip_length_ensure_nonzero(const float *actstart, float *r_actend);
/**
* Create a NLA Strip referencing the given Action.
*/
struct NlaStrip *BKE_nlastrip_new(struct bAction *act);
/*
* Removes the given NLA strip from the list of strips provided.
*/
void BKE_nlastrip_remove(ListBase *strips, struct NlaStrip *strip);
/*
* Removes the given NLA strip from the list of strips provided, and frees it's memory.
*/
void BKE_nlastrip_remove_and_free(ListBase *strips, struct NlaStrip *strip, const bool do_id_user);
/**
* Add new NLA-strip to the top of the NLA stack - i.e.
* into the last track if space, or a new one otherwise.
*/
struct NlaStrip *BKE_nlastack_add_strip(struct AnimData *adt,
struct bAction *act,
bool is_liboverride);
/**
* Add a NLA Strip referencing the given speaker's sound.
*/
struct NlaStrip *BKE_nla_add_soundstrip(struct Main *bmain,
struct Scene *scene,
struct Speaker *speaker);
/**
* Callback used by lib_query to walk over all ID usages
* (mimics `foreach_id` callback of #IDTypeInfo structure).
*/
void BKE_nla_strip_foreach_id(struct NlaStrip *strip, struct LibraryForeachIDData *data);
/* ----------------------------- */
/* API */
/**
* Check if there is any space in the given list to add the given strip.
*/
2014-02-03 08:55:59 +01:00
bool BKE_nlastrips_has_space(ListBase *strips, float start, float end);
/**
* Rearrange the strips in the track so that they are always in order
* (usually only needed after a strip has been moved)
*/
void BKE_nlastrips_sort_strips(ListBase *strips);
/**
* Add the given NLA-Strip to the given list of strips, assuming that it
* isn't currently a member of another list, NULL, or conflicting with existing
* strips position.
*/
void BKE_nlastrips_add_strip_unsafe(ListBase *strips, struct NlaStrip *strip);
/**
2023-02-27 11:44:59 +01:00
* NULL checks incoming strip and verifies no overlap / invalid
* configuration against other strips in NLA Track before calling
* #BKE_nlastrips_add_strip_unsafe.
*/
2014-04-11 03:25:41 +02:00
bool BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
/**
* Convert 'islands' (i.e. continuous string of) selected strips to be
* contained within 'Meta-Strips' which act as strips which contain strips.
*
* \param is_temp: are the meta-strips to be created 'temporary' ones used for transforms?
*/
2014-04-11 03:25:41 +02:00
void BKE_nlastrips_make_metas(ListBase *strips, bool is_temp);
/**
* Remove meta-strips (i.e. flatten the list of strips) from the top-level of the list of strips.
*
* \param only_sel: only consider selected meta-strips, otherwise all meta-strips are removed
* \param only_temp: only remove the 'temporary' meta-strips used for transforms
*/
2014-04-11 03:25:41 +02:00
void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp);
/**
* Split a meta-strip into a set of normal strips.
*/
void BKE_nlastrips_clear_metastrip(ListBase *strips, struct NlaStrip *strip);
/**
* Add the given NLA-Strip to the given Meta-Strip, assuming that the
* strip isn't attached to any list of strips
*/
2014-04-11 03:25:41 +02:00
bool BKE_nlameta_add_strip(struct NlaStrip *mstrip, struct NlaStrip *strip);
/**
* Adjust the settings of NLA-Strips contained within a Meta-Strip (recursively),
* until the Meta-Strips children all fit within the Meta-Strip's new dimensions
*/
void BKE_nlameta_flush_transforms(struct NlaStrip *mstrip);
/* ............ */
/**
* Find the active NLA-track for the given stack.
*/
struct NlaTrack *BKE_nlatrack_find_active(ListBase *tracks);
/**
* Make the given NLA-track the active one for the given stack. If no track is provided,
* this function can be used to simply deactivate all the NLA tracks in the given stack too.
*/
void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt);
/**
* Get the NLA Track that the active action/action strip comes from,
* since this info is not stored in AnimData. It also isn't as simple
* as just using the active track, since multiple tracks may have been
* entered at the same time.
*/
struct NlaTrack *BKE_nlatrack_find_tweaked(struct AnimData *adt);
/**
* Toggle the 'solo' setting for the given NLA-track, making sure that it is the only one
* that has this status in its AnimData block.
*/
void BKE_nlatrack_solo_toggle(struct AnimData *adt, struct NlaTrack *nlt);
/**
* Check if there is any space in the given track to add a strip of the given length.
*/
2014-02-03 08:55:59 +01:00
bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
/**
* Check to see if there are any NLA strips in the NLA tracks.
*/
bool BKE_nlatrack_has_strips(ListBase *tracks);
/**
* Rearrange the strips in the track so that they are always in order
* (usually only needed after a strip has been moved).
*/
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
/**
* Add the given NLA-Strip to the given NLA-Track.
* Calls #BKE_nlastrips_add_strip to check if strip can be added.
*/
bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip, bool is_liboverride);
NLA SoC: Transition Strips + Strip Adding Operators + Bugfixes == Transitions == Transition strips are now able to be created + evaluated. Transitions allow for interpolation between the endpoints of two adjacent strips in the same track (i.e. two strips which occur in the same track one after the other, but with a gap between them). - The current behaviour when only one endpoint affects some setting is non-optimal, since it appears somewhat inconsistently extend/replace values... - Transform code needs a few fixes still to deal with these == Strip Adding Operators == * New strips referencing Actions can be added using the Shift-A hotkey while in the strips-area. You must have a track selected first though. The new strip will get added, starting from the current frame, in the selected track(s) only if there is enough space to do so. Otherwise, the new strip gets added at the top of the stack in a new track. * New transition strips can be added with the Shift-T hotkey while in the strips area. You must have two adjacent strips selected for this to work. == New Backend Methods == * Recoded the strip/track adding API to be more flexible * Added a new method for testing whether F-Curve has any modifiers of with certain attributes. Will be used in a later bugfix... == Bugfixes == - Fixed bug with strip-blending which caused the blending modes to be useless. - NLA buttons now use proper poll callbacks instead of defining checks - Commented out missing operator in menus, silencing warnings in console - Removed obsolete/incorrect comments
2009-06-19 06:45:56 +02:00
/**
* Remove the NLA-Strip from the given NLA-Track.
*/
void BKE_nlatrack_remove_strip(struct NlaTrack *track, struct NlaStrip *strip);
/**
* Get the extents of the given NLA-Track including gaps between strips,
* returning whether this succeeded or not
*/
2014-04-11 03:25:41 +02:00
bool BKE_nlatrack_get_bounds(struct NlaTrack *nlt, float bounds[2]);
/**
* Check whether given NLA track is not local (i.e. from linked data) when the object is a library
* override.
*
* \param nlt: May be NULL, in which case we consider it as a non-local track case.
*/
bool BKE_nlatrack_is_nonlocal_in_liboverride(const struct ID *id, const struct NlaTrack *nlt);
/* ............ */
/**
* Compute the left-hand-side 'frame limit' of that strip, in its NLA track.
*
* \details This is either :
* - the end frame of the previous strip, if the strip's track contains another strip on it left
* - the macro MINFRAMEF, if no strips are to the left of this strip in its track
*
2022-07-06 06:24:37 +02:00
* \param strip: The strip to compute the left-hand-side 'frame limit' of.
* \return The beginning frame of the previous strip, or MINFRAMEF if no strips are next in that
* track.
*/
float BKE_nlastrip_compute_frame_from_previous_strip(struct NlaStrip *strip);
/**
* Compute the right-hand-side 'frame limit' of that strip, in its NLA track.
*
* \details This is either :
*
* - the begin frame of the next strip, if the strip's track contains another strip on it right
* - the macro MAXFRAMEF, if no strips are to the right of this strip in its track
*
2022-07-06 06:24:37 +02:00
* \param strip: The strip to compute the right-hand-side 'frame limit' of.
* \return The beginning frame of the next strip, or MAXFRAMEF if no strips are next in that track.
*/
float BKE_nlastrip_compute_frame_to_next_strip(struct NlaStrip *strip);
/**
* Returns the next strip in this strip's NLA track, or a null pointer.
*
2022-11-01 02:24:04 +01:00
* \param strip: The strip to find the next trip from.
* \param check_transitions: Whether or not to skip transitions.
* \return The next strip in the track, or NULL if none are present.
*/
struct NlaStrip *BKE_nlastrip_next_in_track(struct NlaStrip *strip, bool skip_transitions);
/**
* Returns the previous strip in this strip's NLA track, or a null pointer.
*
2022-11-01 02:24:04 +01:00
* \param strip: The strip to find the previous trip from.
* \param check_transitions: Whether or not to skip transitions.
* \return The previous strip in the track, or NULL if none are present.
*/
struct NlaStrip *BKE_nlastrip_prev_in_track(struct NlaStrip *strip, bool skip_transitions);
/* ............ */
/**
* Find the active NLA-strip within the given track.
*/
NLA SoC: Operators for 'tweaking' strip actions (TAB-Key for both) In this commit, I've introduced the mechanism by which actions already referenced by strips used in the NLA can be edited (or 'tweaked'). To use, simply select a strip you wish to edit, and hit that TAB key to start tweaking that strip's action, and hit TAB again once you're done. What happens when you enter 'tweak mode': 1) The action of the active strip temporarily becomes the 'active action' of the AnimData block. You are now able to edit this in one of the Animation Editors (DopeSheet/Action, Graph Editors) as per normal (i.e. sliding keyframes around, inserting keyframes, etc.). The 'action-line' will therefore get drawn immediately above the active track containing the active strip, so that it's clear that that's what we're editing. 2) All the NLA-tracks (and all the strips within them) that occur after the track that the active strip lived in get disabled while you're in tweakmode. This is equivalent to travelling back to an earlier state in a construction history stack. 3) The active NLA track also gets disabled while in tweakmode, since it would otherwise interfere with the correct functioning of the tweaking for the action of interest. 4) The 'real' active action (i.e. the one displaced by the active strip's action) gets put into temp storage, and will be restored after you exit tweakmode. 5) Any strips which also reference the action being tweaked will get highlighted in red shading to indicate that you may be making some changes to the action which you don't really want to make for the other users too. Please note though, that this is only a rough prototype of this functionality, with some niceties still to come. i.e.: * NLA-tracks after the active track should still get drawn above the 'tweaking action line', but perhaps with different appearance? * Various tools will still need awareness of this to prevent corrupting operations from taking place. How to proceed is still undecided... * When exiting tweak-mode, the strip the action came from still needs some form of syncing with the modified action... there are a few tricky issues here that will need to be solved * Evaluation code doesn't totally take this into account yet... --- Also, fixed a number of bugs with various code (notably selection, and also a few drawing bugs)
2009-06-05 07:18:07 +02:00
struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
/**
* Make the given NLA-Strip the active one within the given block.
*/
void BKE_nlastrip_set_active(struct AnimData *adt, struct NlaStrip *strip);
/**
* Does the given NLA-strip fall within the given bounds (times)?.
*/
2014-04-11 03:25:41 +02:00
bool BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);
/**
* Return the distance from the given frame to the NLA strip, measured in frames.
* If the given frame intersects the NLA strip, the distance is zero.
*/
float BKE_nlastrip_distance_to_frame(const struct NlaStrip *strip, float timeline_frame);
/**
* Recalculate the start and end frames for the current strip, after changing
* the extents of the action or the mapping (repeats or scale factor) info.
*/
void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip);
/**
* Recalculate the start and end frames for the strip to match the bounds of its action such that
* the overall NLA animation result is unchanged.
*/
void BKE_nlastrip_recalculate_bounds_sync_action(struct NlaStrip *strip);
/**
2023-01-20 05:19:32 +01:00
* Recalculate the blend-in and blend-out values after a strip transform update.
*/
void BKE_nlastrip_recalculate_blend(struct NlaStrip *strip);
/**
* Find (and set) a unique name for a strip from the whole AnimData block
* Uses a similar method to the BLI method, but is implemented differently
* as we need to ensure that the name is unique over several lists of tracks,
* not just a single track.
*/
void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip);
/* ............ */
/**
* Check if the given NLA-Track has any strips with own F-Curves.
*/
2014-04-11 03:25:41 +02:00
bool BKE_nlatrack_has_animated_strips(struct NlaTrack *nlt);
/**
* Check if given NLA-Tracks have any strips with own F-Curves.
*/
2014-04-11 03:25:41 +02:00
bool BKE_nlatracks_have_animated_strips(ListBase *tracks);
/**
* Validate the NLA-Strips 'control' F-Curves based on the flags set.
*/
void BKE_nlastrip_validate_fcurves(struct NlaStrip *strip);
/**
* Check if the given RNA pointer + property combo should be handled by
* NLA strip curves or not.
*/
bool BKE_nlastrip_has_curves_for_property(const struct PointerRNA *ptr,
const struct PropertyRNA *prop);
/**
* Ensure that auto-blending and other settings are set correctly.
*/
void BKE_nla_validate_state(struct AnimData *adt);
/* ............ */
/**
* Check if an action is "stashed" in the NLA already
*
* The criteria for this are:
* 1) The action in question lives in a "stash" track.
* 2) We only check first-level strips. That is, we will not check inside meta strips.
*/
bool BKE_nla_action_is_stashed(struct AnimData *adt, struct bAction *act);
/**
* "Stash" an action (i.e. store it as a track/layer in the NLA, but non-contributing)
* to retain it in the file for future uses.
*/
bool BKE_nla_action_stash(struct AnimData *adt, bool is_liboverride);
2002-10-12 13:37:38 +02:00
/* ............ */
/**
* For the given AnimData block, add the active action to the NLA
* stack (i.e. 'push-down' action). The UI should only allow this
* for normal editing only (i.e. not in edit-mode for some strip's action),
* so no checks for this are performed.
*
* TODO: maybe we should have checks for this too.
*/
void BKE_nla_action_pushdown(struct AnimData *adt, bool is_liboverride);
/**
* Find the active strip + track combination, and set them up as the tweaking track,
* and return if successful or not.
*/
2014-04-11 03:25:41 +02:00
bool BKE_nla_tweakmode_enter(struct AnimData *adt);
/**
* Exit tweak-mode for this AnimData block.
*/
NLA SoC: Operators for 'tweaking' strip actions (TAB-Key for both) In this commit, I've introduced the mechanism by which actions already referenced by strips used in the NLA can be edited (or 'tweaked'). To use, simply select a strip you wish to edit, and hit that TAB key to start tweaking that strip's action, and hit TAB again once you're done. What happens when you enter 'tweak mode': 1) The action of the active strip temporarily becomes the 'active action' of the AnimData block. You are now able to edit this in one of the Animation Editors (DopeSheet/Action, Graph Editors) as per normal (i.e. sliding keyframes around, inserting keyframes, etc.). The 'action-line' will therefore get drawn immediately above the active track containing the active strip, so that it's clear that that's what we're editing. 2) All the NLA-tracks (and all the strips within them) that occur after the track that the active strip lived in get disabled while you're in tweakmode. This is equivalent to travelling back to an earlier state in a construction history stack. 3) The active NLA track also gets disabled while in tweakmode, since it would otherwise interfere with the correct functioning of the tweaking for the action of interest. 4) The 'real' active action (i.e. the one displaced by the active strip's action) gets put into temp storage, and will be restored after you exit tweakmode. 5) Any strips which also reference the action being tweaked will get highlighted in red shading to indicate that you may be making some changes to the action which you don't really want to make for the other users too. Please note though, that this is only a rough prototype of this functionality, with some niceties still to come. i.e.: * NLA-tracks after the active track should still get drawn above the 'tweaking action line', but perhaps with different appearance? * Various tools will still need awareness of this to prevent corrupting operations from taking place. How to proceed is still undecided... * When exiting tweak-mode, the strip the action came from still needs some form of syncing with the modified action... there are a few tricky issues here that will need to be solved * Evaluation code doesn't totally take this into account yet... --- Also, fixed a number of bugs with various code (notably selection, and also a few drawing bugs)
2009-06-05 07:18:07 +02:00
void BKE_nla_tweakmode_exit(struct AnimData *adt);
/* ----------------------------- */
/* Time Mapping */
/* time mapping conversion modes */
enum eNlaTime_ConvertModes {
/* convert from global time to strip time - for evaluation */
NLATIME_CONVERT_EVAL = 0,
/* convert from global time to strip time - for editing corrections */
/* XXX: old 0 invert. */
NLATIME_CONVERT_UNMAP,
/* convert from strip time to global time */
/* XXX: old 1 invert. */
NLATIME_CONVERT_MAP,
};
/**
* Non clipped mapping for strip-time <-> global time:
* `mode = eNlaTime_ConvertModes -> NLATIME_CONVERT_*`
*
* Public API method - perform this mapping using the given AnimData block
* and perform any necessary sanity checks on the value
*/
float BKE_nla_tweakedit_remap(struct AnimData *adt, float cframe, short mode);
/* ----------------------------- */
/* .blend file API */
void BKE_nla_blend_write(struct BlendWriter *writer, struct ListBase *tracks);
void BKE_nla_blend_read_data(struct BlendDataReader *reader,
struct ID *id_owner,
struct ListBase *tracks);
#ifdef __cplusplus
}
#endif