NLA SoC: Merge from 2.5
[blender.git] / source / blender / makesrna / intern / rna_nla.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
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.
10  *
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.
15  *
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.
19  *
20  * Contributor(s): Blender Foundation (2009), Joshua Leung
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include <stdlib.h>
26
27 #include "RNA_define.h"
28 #include "RNA_types.h"
29
30 #include "rna_internal.h"
31
32 #include "DNA_anim_types.h"
33 #include "DNA_action_types.h"
34 #include "DNA_scene_types.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #ifdef RNA_RUNTIME
39
40 #include <stdio.h>
41 #include <math.h>
42
43 static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value)
44 {
45         NlaStrip *data= (NlaStrip*)ptr->data;
46         
47         /* clamp value to lie within valid limits 
48          *      - cannot start past the end of the strip + some flexibility threshold
49          *      - cannot start before the previous strip (if present) ends 
50          *      - minimum frame is -MAXFRAME so that we don't get clipping on frame 0
51          */
52         if (data->prev) {
53                 CLAMP(value, data->prev->end, data->end-0.1f);
54         }
55         else {
56                 CLAMP(value, -MAXFRAME, data->end);
57         }
58         data->start= value;
59 }
60
61 static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value)
62 {
63         NlaStrip *data= (NlaStrip*)ptr->data;
64         float len, actlen;
65         
66         /* clamp value to lie within valid limits
67          *      - must not have zero or negative length strip, so cannot start before the first frame 
68          *        + some minimum-strip-length threshold
69          *      - cannot end later than the start of the next strip (if present)
70          */
71         if (data->next) {
72                 CLAMP(value, data->start+0.1f, data->next->start);
73         }
74         else {
75                 CLAMP(value, data->start+0.1f, MAXFRAME);
76         }
77         data->end= value;
78         
79         /* calculate the lengths the strip and its action (if applicable) */
80         len= data->end - data->start;
81         actlen= data->actend - data->actstart;
82         if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
83         
84         /* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */
85         data->scale= len / ((actlen) * data->repeat);
86 }
87
88 static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value)
89 {
90         NlaStrip *data= (NlaStrip*)ptr->data;
91         float actlen, mapping;
92         
93         /* set scale value */
94         CLAMP(value, 0.0001f, 1000.0f); /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */
95         data->scale= value;
96         
97         /* calculate existing factors */
98         actlen= data->actend - data->actstart;
99         if (IS_EQ(actlen, 0.0f)) actlen= 1.0f;
100         mapping= data->scale * data->repeat;
101         
102         /* adjust endpoint of strip in response to this */
103         if (IS_EQ(mapping, 0.0f) == 0)
104                 data->end = (actlen * mapping) + data->start; 
105         else
106                 printf("NlaStrip Set Scale Error (in RNA): Scale = %0.4f, Repeat = %0.4f \n", data->scale, data->repeat);
107 }
108
109 static void rna_NlaStrip_blend_in_set(PointerRNA *ptr, float value)
110 {
111         NlaStrip *data= (NlaStrip*)ptr->data;
112         float len;
113         
114         /* blend-in is limited to the length of the strip, and also cannot overlap with blendout */
115         len= (data->end - data->start) - data->blendout;
116         CLAMP(value, 0, len);
117         
118         data->blendin= value;
119 }
120
121 static void rna_NlaStrip_blend_out_set(PointerRNA *ptr, float value)
122 {
123         NlaStrip *data= (NlaStrip*)ptr->data;
124         float len;
125         
126         /* blend-out is limited to the length of the strip */
127         len= (data->end - data->start);
128         CLAMP(value, 0, len);
129         
130         /* it also cannot overlap with blendin */
131         if ((len - value) < data->blendin)
132                 value= len - data->blendin;
133         
134         data->blendout= value;
135 }
136
137 static void rna_NlaStrip_action_start_frame_set(PointerRNA *ptr, float value)
138 {
139         NlaStrip *data= (NlaStrip*)ptr->data;
140         CLAMP(value, -MAXFRAME, data->actend);
141         data->actstart= value;
142 }
143
144 static void rna_NlaStrip_action_end_frame_set(PointerRNA *ptr, float value)
145 {
146         NlaStrip *data= (NlaStrip*)ptr->data;
147         CLAMP(value, data->actstart, MAXFRAME);
148         data->actend= value;
149 }
150
151 #else
152
153 void rna_def_nlastrip(BlenderRNA *brna)
154 {
155         StructRNA *srna;
156         PropertyRNA *prop;
157         
158                 /* enum defs */
159         static EnumPropertyItem prop_type_items[] = {
160                 {NLASTRIP_TYPE_CLIP, "CLIP", 0, "Action Clip", "NLA Strip references some Action."},
161                 {NLASTRIP_TYPE_TRANSITION, "TRANSITION", 0, "Transition", "NLA Strip 'transitions' between adjacent strips."},
162                 {0, NULL, 0, NULL, NULL}};
163         static EnumPropertyItem prop_mode_blend_items[] = {
164                 {NLASTRIP_MODE_BLEND, "BLEND", 0, "Blend", "Results of strip and accumulated results are combined in ratio governed by influence."},
165                 {NLASTRIP_MODE_ADD, "ADD", 0, "Add", "Weighted result of strip is added to the accumlated results."},
166                 {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", 0, "Subtract", "Weighted result of strip is removed from the accumlated results."},
167                 {NLASTRIP_MODE_MULTIPLY, "MULITPLY", 0, "Multiply", "Weighted result of strip is multiplied with the accumlated results."},
168                 {0, NULL, 0, NULL, NULL}};
169         static EnumPropertyItem prop_mode_extend_items[] = {
170                 {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents."},
171                 {NLASTRIP_EXTEND_HOLD, "HOLD", 0, "Hold", "Hold the first frame if no previous strips in track, and always hold last frame."},
172                 {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame."},
173                 {0, NULL, 0, NULL, NULL}};
174         
175         /* struct definition */
176         srna= RNA_def_struct(brna, "NlaStrip", NULL);
177         RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action.");
178         RNA_def_struct_ui_icon(srna, ICON_NLA); // XXX
179         
180         /* Enums */
181         prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
182         RNA_def_property_enum_sdna(prop, NULL, "type");
183         RNA_def_property_enum_items(prop, prop_type_items);
184         RNA_def_property_ui_text(prop, "Type", "Type of NLA Strip.");
185         
186         prop= RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE);
187         RNA_def_property_enum_sdna(prop, NULL, "extendmode");
188         RNA_def_property_enum_items(prop, prop_mode_extend_items);
189         RNA_def_property_ui_text(prop, "Extrapolation", "Action to take for gaps past the strip extents.");
190         
191         prop= RNA_def_property(srna, "blending", PROP_ENUM, PROP_NONE);
192         RNA_def_property_enum_sdna(prop, NULL, "blendmode");
193         RNA_def_property_enum_items(prop, prop_mode_blend_items);
194         RNA_def_property_ui_text(prop, "Blending", "Method used for combining strip's result with accumulated result.");
195         
196         /* Strip extents */
197         prop= RNA_def_property(srna, "start_frame", PROP_FLOAT, PROP_NONE);
198         RNA_def_property_float_sdna(prop, NULL, "start");
199         RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_start_frame_set", NULL);
200         RNA_def_property_ui_text(prop, "Start Frame", "");
201         
202         prop= RNA_def_property(srna, "end_frame", PROP_FLOAT, PROP_NONE);
203         RNA_def_property_float_sdna(prop, NULL, "end");
204         RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_end_frame_set", NULL);
205         RNA_def_property_ui_text(prop, "End Frame", "");
206         
207         /* Blending */
208         prop= RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);
209         RNA_def_property_float_sdna(prop, NULL, "blendin");
210         RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_in_set", NULL);
211         RNA_def_property_ui_text(prop, "Blend In", "Number of frames at start of strip to fade in influence.");
212         
213         prop= RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE);
214         RNA_def_property_float_sdna(prop, NULL, "blendout");
215         RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_out_set", NULL);
216         RNA_def_property_ui_text(prop, "Blend Out", "");
217         
218         prop= RNA_def_property(srna, "auto_blending", PROP_BOOLEAN, PROP_NONE);
219         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_AUTO_BLENDS);
220         RNA_def_property_ui_text(prop, "Auto Blend In/Out", "Number of frames for Blending In/Out is automatically determined from overlapping strips.");
221         
222         /* Action */
223         prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
224         RNA_def_property_pointer_sdna(prop, NULL, "act");
225         RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip.");
226         
227         /* Action extents */
228         prop= RNA_def_property(srna, "action_start_frame", PROP_FLOAT, PROP_NONE);
229         RNA_def_property_float_sdna(prop, NULL, "actstart");
230         RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_start_frame_set", NULL);
231         RNA_def_property_ui_text(prop, "Action Start Frame", "");
232         
233         prop= RNA_def_property(srna, "action_end_frame", PROP_FLOAT, PROP_NONE);
234         RNA_def_property_float_sdna(prop, NULL, "actend");
235         RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_end_frame_set", NULL);
236         RNA_def_property_ui_text(prop, "Action End Frame", "");
237         
238         /* Action Reuse */
239         prop= RNA_def_property(srna, "repeat", PROP_FLOAT, PROP_NONE);
240         RNA_def_property_float_sdna(prop, NULL, "repeat"); 
241         RNA_def_property_range(prop, 1.0f, 1000.0f); /* these limits have currently be chosen arbitarily, but could be extended (minimum should still be > 0 though) if needed... */
242         RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the ");
243         
244         prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
245         RNA_def_property_float_sdna(prop, NULL, "scale"); 
246         RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_scale_set", NULL);
247         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 */
248         RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action.");
249         
250         // TODO: strip's F-Curves?
251         
252         /* Strip's F-Modifiers */
253         prop= RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
254         RNA_def_property_struct_type(prop, "FModifier");
255         RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting all the F-Curves in the referenced Action.");
256         
257         /* Settings - Values necessary for evaluation */
258         prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE);
259         RNA_def_property_range(prop, 0.0f, 1.0f);
260         RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result.");
261         
262         prop= RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_NONE);
263         RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate.");
264         
265         prop= RNA_def_property(srna, "animated_influence", PROP_BOOLEAN, PROP_NONE);
266         RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, not editable
267         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE);
268         RNA_def_property_ui_text(prop, "Animated Influence", "Influence setting is controlled by an F-Curve rather than automatically determined.");
269         
270         prop= RNA_def_property(srna, "animated_time", PROP_BOOLEAN, PROP_NONE);
271         RNA_def_property_clear_flag(prop, PROP_EDITABLE); // XXX for now, not editable
272         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE);
273         RNA_def_property_ui_text(prop, "Animated Strip Time", "Strip time is controlled by an F-Curve rather than automatically determined.");
274         
275         /* settings */
276         prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
277         RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
278         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_ACTIVE);
279         RNA_def_property_ui_text(prop, "Active", "NLA Strip is active.");
280         
281         prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
282         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SELECT);
283         RNA_def_property_ui_text(prop, "Selected", "NLA Strip is selected.");
284         
285         prop= RNA_def_property(srna, "muted", PROP_BOOLEAN, PROP_NONE);
286         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_MUTED);
287         RNA_def_property_ui_text(prop, "Muted", "NLA Strip is not evaluated.");
288         
289         prop= RNA_def_property(srna, "reversed", PROP_BOOLEAN, PROP_NONE);
290         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_REVERSE);
291         RNA_def_property_ui_text(prop, "Reversed", "NLA Strip is played back in reverse order (only when timing is automatically determined).");
292         
293         // TODO: 
294         // - sync length
295 }
296
297 void rna_def_nlatrack(BlenderRNA *brna)
298 {
299         StructRNA *srna;
300         PropertyRNA *prop;
301         
302         srna= RNA_def_struct(brna, "NlaTrack", NULL);
303         RNA_def_struct_ui_text(srna, "NLA Track", "A animation layer containing Actions referenced as NLA strips.");
304         RNA_def_struct_ui_icon(srna, ICON_NLA);
305         
306         /* strips collection */
307         prop= RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE);
308         RNA_def_property_struct_type(prop, "NlaStrip");
309         RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips on this NLA-track.");
310         
311         /* name property */
312         prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
313         RNA_def_property_ui_text(prop, "Name", "");
314         RNA_def_struct_name_property(srna, prop);
315         
316         /* settings */
317         prop= RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
318         RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
319         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_ACTIVE);
320         RNA_def_property_ui_text(prop, "Active", "NLA Track is active.");
321         
322         prop= RNA_def_property(srna, "solo", PROP_BOOLEAN, PROP_NONE);
323         RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can be made editable by hooking it up to the necessary NLA API methods */
324         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SOLO);
325         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).");
326         
327         prop= RNA_def_property(srna, "selected", PROP_BOOLEAN, PROP_NONE);
328         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SELECTED);
329         RNA_def_property_ui_text(prop, "Selected", "NLA Track is selected.");
330         
331         prop= RNA_def_property(srna, "muted", PROP_BOOLEAN, PROP_NONE);
332         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_MUTED);
333         RNA_def_property_ui_text(prop, "Muted", "NLA Track is not evaluated.");
334
335         prop= RNA_def_property(srna, "locked", PROP_BOOLEAN, PROP_NONE);
336         RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_PROTECTED);
337         RNA_def_property_ui_text(prop, "Locked", "NLA Track is locked.");
338 }
339
340 /* --------- */
341
342 void RNA_def_nla(BlenderRNA *brna)
343 {
344         rna_def_nlatrack(brna);
345         rna_def_nlastrip(brna);
346 }
347
348
349 #endif