/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung * All rights reserved. */ /** \file * \ingroup bke */ #pragma once #include "BLI_bitmap.h" #include "BLI_ghash.h" #include "RNA_types.h" #ifdef __cplusplus extern "C" { #endif struct AnimationEvalContext; /* --------------- NLA Evaluation DataTypes ----------------------- */ /* used for list of strips to accumulate at current time */ typedef struct NlaEvalStrip { struct NlaEvalStrip *next, *prev; NlaTrack *track; /* Track that this strip belongs to. */ NlaStrip *strip; /* Strip that's being used. */ short track_index; /* The index of the track within the list. */ short strip_mode; /* Which end of the strip are we looking at. */ float strip_time; /* Time at which this strip is being evaluated. */ } NlaEvalStrip; /* NlaEvalStrip->strip_mode */ enum eNlaEvalStrip_StripMode { /* standard evaluation */ NES_TIME_BEFORE = -1, NES_TIME_WITHIN, NES_TIME_AFTER, /* transition-strip evaluations */ NES_TIME_TRANSITION_START, NES_TIME_TRANSITION_END, }; struct NlaEvalChannel; struct NlaEvalData; /* Unique channel key for GHash. */ typedef struct NlaEvalChannelKey { struct PointerRNA ptr; struct PropertyRNA *prop; } NlaEvalChannelKey; /* Bitmask of array indices touched by actions. */ typedef struct NlaValidMask { BLI_bitmap *ptr; BLI_bitmap buffer[sizeof(uint64_t) / sizeof(BLI_bitmap)]; } NlaValidMask; /* Set of property values for blending. */ typedef struct NlaEvalChannelSnapshot { struct NlaEvalChannel *channel; /** For an upper snapshot channel, marks values that should be blended. */ NlaValidMask blend_domain; /** Only used for keyframe remapping. Any values not in the \a remap_domain will not be used * for keyframe remapping. */ NlaValidMask remap_domain; int length; /* Number of values in the property. */ bool is_base; /* Base snapshot of the channel. */ float values[]; /* Item values. */ /* Memory over-allocated to provide space for values. */ } NlaEvalChannelSnapshot; /* NlaEvalChannel->mix_mode */ enum eNlaEvalChannel_MixMode { NEC_MIX_ADD, NEC_MIX_MULTIPLY, NEC_MIX_QUATERNION, NEC_MIX_AXIS_ANGLE, }; /* Temp channel for accumulating data from NLA for a single property. * Handles array properties as a unit to allow intelligent blending. */ typedef struct NlaEvalChannel { struct NlaEvalChannel *next, *prev; struct NlaEvalData *owner; /* Original RNA path string and property key. */ const char *rna_path; NlaEvalChannelKey key; int index; bool is_array; char mix_mode; /* Associated with the RNA property's value(s), marks which elements are affected by NLA. */ NlaValidMask domain; /* Base set of values. */ NlaEvalChannelSnapshot base_snapshot; /* Memory over-allocated to provide space for base_snapshot.values. */ } NlaEvalChannel; /* Set of values for all channels. */ typedef struct NlaEvalSnapshot { /* Snapshot this one defaults to. */ struct NlaEvalSnapshot *base; int size; NlaEvalChannelSnapshot **channels; } NlaEvalSnapshot; /* Set of all channels covered by NLA. */ typedef struct NlaEvalData { ListBase channels; /* Mapping of paths and NlaEvalChannelKeys to channels. */ GHash *path_hash; GHash *key_hash; /* Base snapshot. */ int num_channels; NlaEvalSnapshot base_snapshot; /* Evaluation result shapshot. */ NlaEvalSnapshot eval_snapshot; } NlaEvalData; /* Information about the currently edited strip and ones below it for keyframing. */ typedef struct NlaKeyframingContext { struct NlaKeyframingContext *next, *prev; /* AnimData for which this context was built. */ struct AnimData *adt; /* Data of the currently edited strip (copy, or fake strip for the main action). */ NlaStrip strip; NlaEvalStrip *eval_strip; /* Evaluated NLA stack below the tweak strip. */ NlaEvalData lower_eval_data; } NlaKeyframingContext; /* --------------- NLA Functions (not to be used as a proper API) ----------------------- */ /** * Convert non clipped mapping for strip-time <-> global time: * `mode = eNlaTime_ConvertModes[] -> NLATIME_CONVERT_*` * * Only secure for 'internal' (i.e. within AnimSys evaluation) operations, * but should not be directly relied on for stuff which interacts with editors. */ float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode); /* --------------- NLA Evaluation (very-private stuff) ----------------------- */ /* these functions are only defined here to avoid problems with the order * in which they get defined. */ /** * Gets the strip active at the current time for a list of strips for evaluation purposes. */ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, ListBase *strips, short index, const struct AnimationEvalContext *anim_eval_context, bool flush_to_original); /** * Evaluates the given evaluation strip. */ void nlastrip_evaluate(PointerRNA *ptr, NlaEvalData *channels, ListBase *modifiers, NlaEvalStrip *nes, NlaEvalSnapshot *snapshot, const struct AnimationEvalContext *anim_eval_context, bool flush_to_original); /** * write the accumulated settings to. */ void nladata_flush_channels(PointerRNA *ptr, NlaEvalData *channels, NlaEvalSnapshot *snapshot, bool flush_to_original); void nlasnapshot_enable_all_blend_domain(NlaEvalSnapshot *snapshot); void nlasnapshot_ensure_channels(NlaEvalData *eval_data, NlaEvalSnapshot *snapshot); /** * Blends the \a lower_snapshot with the \a upper_snapshot into \a r_blended_snapshot according * to the given \a upper_blendmode and \a upper_influence. * * For \a upper_snapshot, blending limited to values in the \a blend_domain. * For Replace blend-mode, this allows the upper snapshot to have a location XYZ channel * where only a subset of values are blended. */ void nlasnapshot_blend(NlaEvalData *eval_data, NlaEvalSnapshot *lower_snapshot, NlaEvalSnapshot *upper_snapshot, short upper_blendmode, float upper_influence, NlaEvalSnapshot *r_blended_snapshot); /** * Using \a blended_snapshot and \a lower_snapshot, we can solve for the \a r_upper_snapshot. * * Only channels that exist within \a blended_snapshot are inverted. * * For \a r_upper_snapshot, disables \a NlaEvalChannelSnapshot->remap_domain for failed inversions. * Only values within the \a remap_domain are processed. */ void nlasnapshot_blend_get_inverted_upper_snapshot(NlaEvalData *eval_data, NlaEvalSnapshot *lower_snapshot, NlaEvalSnapshot *blended_snapshot, short upper_blendmode, float upper_influence, NlaEvalSnapshot *r_upper_snapshot); #ifdef __cplusplus } #endif