4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * Contributor(s): Blender Foundation (2009), Joshua Leung
22 * ***** END GPL LICENSE BLOCK *****
27 #include "RNA_define.h"
28 #include "RNA_types.h"
30 #include "rna_internal.h"
32 #include "DNA_anim_types.h"
33 #include "DNA_action_types.h"
34 #include "DNA_scene_types.h"
36 #include "MEM_guardedalloc.h"
43 /* needed for some of the validation stuff... */
44 #include "BKE_animsys.h"
47 /* temp constant defined for these funcs only... */
48 #define NLASTRIP_MIN_LEN_THRESH 0.1f
50 void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value)
52 NlaStrip *data= (NlaStrip *)ptr->data;
54 /* copy the name first */
55 BLI_strncpy(data->name, value, sizeof(data->name));
57 /* validate if there's enough info to do so */
59 AnimData *adt= BKE_animdata_from_id(ptr->id.data);
60 BKE_nlastrip_validate_name(adt, data);
65 static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
67 NlaStrip *data= (NlaStrip*)ptr->data;
69 /* clamp value to lie within valid limits
70 * - cannot start past the end of the strip + some flexibility threshold
71 * - cannot start before the previous strip (if present) ends
72 * -> but if it was a transition, we could go up to the start of the strip + some flexibility threshold
73 * as long as we re-adjust the transition afterwards
74 * - minimum frame is -MAXFRAME so that we don't get clipping on frame 0
77 if (data->prev->type == NLASTRIP_TYPE_TRANSITION) {
78 CLAMP(value, data->prev->start+NLASTRIP_MIN_LEN_THRESH, data->end-NLASTRIP_MIN_LEN_THRESH);
80 /* readjust the transition to stick to the endpoints of the action-clips */
81 data->prev->end= value;
84 CLAMP(value, data->prev->end, data->end-NLASTRIP_MIN_LEN_THRESH);
88 CLAMP(value, MINAFRAME, data->end);
93 static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
95 NlaStrip *data= (NlaStrip*)ptr->data;
97 /* clamp value to lie within valid limits
98 * - must not have zero or negative length strip, so cannot start before the first frame
99 * + some minimum-strip-length threshold
100 * - cannot end later than the start of the next strip (if present)
101 * -> but if it was a transition, we could go up to the start of the end - some flexibility threshold
102 * as long as we re-adjust the transition afterwards
105 if (data->next->type == NLASTRIP_TYPE_TRANSITION) {
106 CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, data->next->end-NLASTRIP_MIN_LEN_THRESH);
108 /* readjust the transition to stick to the endpoints of the action-clips */
109 data->next->start= value;
112 CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, data->next->start);
116 CLAMP(value, data->start+NLASTRIP_MIN_LEN_THRESH, MAXFRAME);
121 /* calculate the lengths the strip and its action (if applicable) */
122 if (data->type == NLASTRIP_TYPE_CLIP) {
125 len= data->end - data->start;
126 actlen= data->actend - data->actstart;
127 if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
129 /* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */
130 data->scale= len / ((actlen) * data->repeat);
134 static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value)
136 NlaStrip *data= (NlaStrip*)ptr->data;
137 float actlen, mapping;
139 /* set scale value */
140 CLAMP(value, 0.0001f, 1000.0f); /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
143 /* calculate existing factors */
144 actlen= data->actend - data->actstart;
145 if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
146 mapping= data->scale * data->repeat;
148 /* adjust endpoint of strip in response to this */
149 if (IS_EQ(mapping, 0.0f) == 0)
150 data->end = (actlen * mapping) + data->start;
152 printf("NlaStrip Set Scale Error (in RNA): Scale = %0.4f, Repeat = %0.4f \n", data->scale, data->repeat);
155 static void rna_NlaStrip_repeat_set(PointerRNA *ptr, float value)
157 NlaStrip *data= (NlaStrip*)ptr->data;
158 float actlen, mapping;
160 /* set scale value */
161 CLAMP(value, 0.01f, 1000.0f); /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
164 /* calculate existing factors */
165 actlen= data->actend - data->actstart;
166 if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
167 mapping= data->scale * data->repeat;
169 /* adjust endpoint of strip in response to this */
170 if (IS_EQ(mapping, 0.0f) == 0)
171 data->end = (actlen * mapping) + data->start;
173 printf("NlaStrip Set Repeat Error (in RNA): Scale = %0.4f, Repeat = %0.4f \n", data->scale, data->repeat);
176 static void rna_NlaStrip_blend_in_set(PointerRNA *ptr, float value)
178 NlaStrip *data= (NlaStrip*)ptr->data;
181 /* blend-in is limited to the length of the strip, and also cannot overlap with blendout */
182 len= (data->end - data->start) - data->blendout;
183 CLAMP(value, 0, len);
185 data->blendin= value;
188 static void rna_NlaStrip_blend_out_set(PointerRNA *ptr, float value)
190 NlaStrip *data= (NlaStrip*)ptr->data;
193 /* blend-out is limited to the length of the strip */
194 len= (data->end - data->start);
195 CLAMP(value, 0, len);
197 /* it also cannot overlap with blendin */
198 if ((len - value) < data->blendin)
199 value= len - data->blendin;
201 data->blendout= value;
204 static void rna_NlaStrip_action_start_frame_set(PointerRNA *ptr, float value)
206 NlaStrip *data= (NlaStrip*)ptr->data;
207 CLAMP(value, MINAFRAME, data->actend);
208 data->actstart= value;
211 static void rna_NlaStrip_action_end_frame_set(PointerRNA *ptr, float value)
213 NlaStrip *data= (NlaStrip*)ptr->data;
214 CLAMP(value, data->actstart, MAXFRAME);
218 static void rna_NlaStrip_animated_influence_set(PointerRNA *ptr, int value)
220 NlaStrip *data= (NlaStrip*)ptr->data;
223 /* set the flag, then make sure a curve for this exists */
224 data->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
225 BKE_nlastrip_validate_fcurves(data);
228 data->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
231 static void rna_NlaStrip_animated_time_set(PointerRNA *ptr, int value)
233 NlaStrip *data= (NlaStrip*)ptr->data;
236 /* set the flag, then make sure a curve for this exists */
237 data->flag |= NLASTRIP_FLAG_USR_TIME;
238 BKE_nlastrip_validate_fcurves(data);
241 data->flag &= ~NLASTRIP_FLAG_USR_TIME;
246 void rna_def_nlastrip(BlenderRNA *brna)
252 static EnumPropertyItem prop_type_items[] = {
253 {NLASTRIP_TYPE_CLIP, "CLIP", 0, "Action Clip", "NLA Strip references some Action."},
254 {NLASTRIP_TYPE_TRANSITION, "TRANSITION", 0, "Transition", "NLA Strip 'transitions' between adjacent strips."},
255 {NLASTRIP_TYPE_META, "META", 0, "Meta", "NLA Strip acts as a container for adjacent strips."},
256 {0, NULL, 0, NULL, NULL}};
257 static EnumPropertyItem prop_mode_blend_items[] = {
258 {NLASTRIP_MODE_REPLACE, "REPLACE", 0, "Replace", "Result strip replaces the accumulated results by amount specified by influence."},
259 {NLASTRIP_MODE_ADD, "ADD", 0, "Add", "Weighted result of strip is added to the accumlated results."},
260 {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", 0, "Subtract", "Weighted result of strip is removed from the accumlated results."},
261 {NLASTRIP_MODE_MULTIPLY, "MULITPLY", 0, "Multiply", "Weighted result of strip is multiplied with the accumlated results."},
262 {0, NULL, 0, NULL, NULL}};
263 static EnumPropertyItem prop_mode_extend_items[] = {
264 {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents."},
265 {NLASTRIP_EXTEND_HOLD, "HOLD", 0, "Hold", "Hold the first frame if no previous strips in track, and always hold last frame."},
266 {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame."},
267 {0, NULL, 0, NULL, NULL}};
269 /* struct definition */
270 srna= RNA_def_struct(brna, "NlaStrip", NULL);
271 RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action.");
272 RNA_def_struct_ui_icon(srna, ICON_NLA); // XXX
275 prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
276 RNA_def_property_ui_text(prop, "Name", "");
277 RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NlaStrip_name_set");
278 RNA_def_struct_name_property(srna, prop);
281 prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
282 RNA_def_property_enum_sdna(prop, NULL, "type");
283 RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, not editable, since this is dangerous
284 RNA_def_property_enum_items(prop, prop_type_items);
285 RNA_def_property_ui_text(prop, "Type", "Type of NLA Strip.");
287 prop= RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE);
288 RNA_def_property_enum_sdna(prop, NULL, "extendmode");
289 RNA_def_property_enum_items(prop, prop_mode_extend_items);
290 RNA_def_property_ui_text(prop, "Extrapolation", "Action to take for gaps past the strip extents.");
292 prop= RNA_def_property(srna, "blending", PROP_ENUM, PROP_NONE);
293 RNA_def_property_enum_sdna(prop, NULL, "blendmode");
294 RNA_def_property_enum_items(prop, prop_mode_blend_items);
295 RNA_def_property_ui_text(prop, "Blending", "Method used for combining strip's result with accumulated result.");
298 prop= RNA_def_property(srna, "start_frame", PROP_FLOAT, PROP_NONE);
299 RNA_def_property_float_sdna(prop, NULL, "start");
300 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_start_frame_set", NULL);
301 RNA_def_property_ui_text(prop, "Start Frame", "");
303 prop= RNA_def_property(srna, "end_frame", PROP_FLOAT, PROP_NONE);
304 RNA_def_property_float_sdna(prop, NULL, "end");
305 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_end_frame_set", NULL);
306 RNA_def_property_ui_text(prop, "End Frame", "");
309 prop= RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);
310 RNA_def_property_float_sdna(prop, NULL, "blendin");
311 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_in_set", NULL);
312 RNA_def_property_ui_text(prop, "Blend In", "Number of frames at start of strip to fade in influence.");
314 prop= RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE);
315 RNA_def_property_float_sdna(prop, NULL, "blendout");
316 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_out_set", NULL);
317 RNA_def_property_ui_text(prop, "Blend Out", "");
319 prop= RNA_def_property(srna, "auto_blending", PROP_BOOLEAN, PROP_NONE);
320 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_AUTO_BLENDS);
321 RNA_def_property_ui_text(prop, "Auto Blend In/Out", "Number of frames for Blending In/Out is automatically determined from overlapping strips.");
324 prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
325 RNA_def_property_pointer_sdna(prop, NULL, "act");
326 RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip.");
329 prop= RNA_def_property(srna, "action_start_frame", PROP_FLOAT, PROP_NONE);
330 RNA_def_property_float_sdna(prop, NULL, "actstart");
331 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_start_frame_set", NULL);
332 RNA_def_property_ui_text(prop, "Action Start Frame", "");
334 prop= RNA_def_property(srna, "action_end_frame", PROP_FLOAT, PROP_NONE);
335 RNA_def_property_float_sdna(prop, NULL, "actend");
336 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_end_frame_set", NULL);
337 RNA_def_property_ui_text(prop, "Action End Frame", "");
340 prop= RNA_def_property(srna, "repeat", PROP_FLOAT, PROP_NONE);
341 RNA_def_property_float_sdna(prop, NULL, "repeat");
342 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_repeat_set", NULL);
343 RNA_def_property_range(prop, 0.1f, 1000.0f); /* these limits have currently be chosen arbitarily, but could be extended (minimum should still be > 0 though) if needed... */
344 RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range.");
346 prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
347 RNA_def_property_float_sdna(prop, NULL, "scale");
348 RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_scale_set", NULL);
349 RNA_def_property_range(prop, 0.0001f, 1000.0f); /* these limits can be extended, but beyond this, we can get some crazy+annoying bugs due to numeric errors */
350 RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action.");
352 /* Strip's F-Curves */
353 prop= RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE);
354 RNA_def_property_struct_type(prop, "FCurve");
355 RNA_def_property_ui_text(prop, "F-Curves", "F-Curves for controlling the strip's influence and timing.");
357 /* Strip's F-Modifiers */
358 prop= RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
359 RNA_def_property_struct_type(prop, "FModifier");
360 RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting all the F-Curves in the referenced Action.");
362 /* Strip's Sub-Strips (for Meta-Strips) */
363 prop= RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
364 RNA_def_property_struct_type(prop, "NlaStrip");
365 RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips that this strip acts as a container for (if it is of type Meta).");
367 /* Settings - Values necessary for evaluation */
368 prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE);
369 RNA_def_property_range(prop, 0.0f, 1.0f);
370 RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result.");
372 prop= RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_NONE);
373 RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate.");
375 // TODO: should the animated_influence/time settings be animatable themselves?
376 prop= RNA_def_property(srna, "animated_influence", PROP_BOOLEAN, PROP_NONE);
377 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE);
378 RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_influence_set");
379 RNA_def_property_ui_text(prop, "Animated Influence", "Influence setting is controlled by an F-Curve rather than automatically determined.");
381 prop= RNA_def_property(srna, "animated_time", PROP_BOOLEAN, PROP_NONE);
382 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME);
383 RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_time_set");
384 RNA_def_property_ui_text(prop, "Animated Strip Time", "Strip time is controlled by an F-Curve rather than automatically determined.");
387 prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
388 RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
389 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_ACTIVE);
390 RNA_def_property_ui_text(prop, "Active", "NLA Strip is active.");
392 prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
393 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SELECT);
394 RNA_def_property_ui_text(prop, "Selected", "NLA Strip is selected.");
396 prop= RNA_def_property(srna, "muted", PROP_BOOLEAN, PROP_NONE);
397 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_MUTED);
398 RNA_def_property_ui_text(prop, "Muted", "NLA Strip is not evaluated.");
400 prop= RNA_def_property(srna, "reversed", PROP_BOOLEAN, PROP_NONE);
401 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_REVERSE);
402 RNA_def_property_ui_text(prop, "Reversed", "NLA Strip is played back in reverse order (only when timing is automatically determined).");
408 void rna_def_nlatrack(BlenderRNA *brna)
413 srna= RNA_def_struct(brna, "NlaTrack", NULL);
414 RNA_def_struct_ui_text(srna, "NLA Track", "A animation layer containing Actions referenced as NLA strips.");
415 RNA_def_struct_ui_icon(srna, ICON_NLA);
417 /* strips collection */
418 prop= RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
419 RNA_def_property_struct_type(prop, "NlaStrip");
420 RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips on this NLA-track.");
423 prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
424 RNA_def_property_ui_text(prop, "Name", "");
425 RNA_def_struct_name_property(srna, prop);
428 prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
429 RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
430 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_ACTIVE);
431 RNA_def_property_ui_text(prop, "Active", "NLA Track is active.");
433 prop= RNA_def_property(srna, "solo", PROP_BOOLEAN, PROP_NONE);
434 RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
435 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SOLO);
436 RNA_def_property_ui_text(prop, "Solo", "NLA Track is evaluated itself (i.e. active Action and all other NLA Tracks in the same AnimData block are disabled).");
438 prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
439 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SELECTED);
440 RNA_def_property_ui_text(prop, "Selected", "NLA Track is selected.");
442 prop= RNA_def_property(srna, "muted", PROP_BOOLEAN, PROP_NONE);
443 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_MUTED);
444 RNA_def_property_ui_text(prop, "Muted", "NLA Track is not evaluated.");
446 prop= RNA_def_property(srna, "locked", PROP_BOOLEAN, PROP_NONE);
447 RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_PROTECTED);
448 RNA_def_property_ui_text(prop, "Locked", "NLA Track is locked.");
453 void RNA_def_nla(BlenderRNA *brna)
455 rna_def_nlatrack(brna);
456 rna_def_nlastrip(brna);