in seqeffects.c I removed and extra ; and then did a lot of formatting
[blender.git] / release / plugins / sequence / scatter.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include "plugin.h"
34
35 /* ******************** GLOBAL VARIABLES ***************** */
36
37
38 char name[24]= "scatter";
39
40 /* structure for buttons, 
41  *  butcode      name           default  min  max  0
42  */
43
44 VarStruct varstr[]= {
45         LABEL,          "Input: 1 strip", 0.0, 0.0, 0.0, "", 
46         NUM|INT,        "seed: ",               1.0,    0.0, 10.0, "Offset in random table", 
47         NUMSLI|FLO,     "swing: ",              1.0,    0.0, 3.0, "The amplitude, width of the effect", 
48         TOG|INT,        "wrap",                 0.0,    0.0, 1.0, "Cyclic wrap around the left/right edges", 
49         NUM|INT,        "type: ",               1.0,    0.0, 1.0, "Type 1 is random for each frame", 
50 };
51
52 /* The cast struct is for input in the main doit function
53    Varstr and Cast must have the same variables in the same order */ 
54
55 typedef struct Cast {
56         int dummy;                      /* because of the 'label' button */
57         int seed;
58         float swing;
59         int wrap;
60         int type;
61 } Cast;
62
63 /* cfra: the current frame */
64
65 float cfra;
66
67 void plugin_seq_doit(Cast *, float, float, int, int, ImBuf *, ImBuf *, ImBuf *, ImBuf *);
68
69
70 /* ******************** Fixed functions ***************** */
71
72 int plugin_seq_getversion(void) 
73 {
74         return B_PLUGIN_VERSION;
75 }
76
77 void plugin_but_changed(int but) 
78 {
79 }
80
81 void plugin_init()
82 {
83 }
84
85 void plugin_getinfo(PluginInfo *info)
86 {
87         info->name= name;
88         info->nvars= sizeof(varstr)/sizeof(VarStruct);
89         info->cfra= &cfra;
90
91         info->varstr= varstr;
92
93         info->init= plugin_init;
94         info->seq_doit= (SeqDoit) plugin_seq_doit;
95         info->callback= plugin_but_changed;
96 }
97
98
99 /* ************************************************************
100         Scatter
101         
102         with usage of ImBuf rect operation.
103         
104    ************************************************************ */
105
106 static void ibufrectop(ImBuf *dbuf, ImBuf *sbuf,        
107                                 int destx, int desty, 
108                                 int srcx, int srcy, int width, int height,
109                                 void (*operation)(), 
110                                 int value)
111 {
112         uint *drect,*srect;
113
114         if (dbuf == 0) return;
115         if (operation == 0) return;
116
117         if (destx < 0){
118                 srcx -= destx ;
119                 width += destx ;
120                 destx = 0;
121         }
122         if (srcx < 0){
123                 destx -= srcx ;
124                 width += destx ;
125                 srcx = 0;
126         }
127         if (desty < 0){
128                 srcy -= desty ;
129                 height += desty ;
130                 desty = 0;
131         }
132         if (srcy < 0){
133                 desty -= srcy ;
134                 height += desty ;
135                 srcy = 0;
136         }
137
138         if (width > dbuf->x - destx) width = dbuf->x - destx;
139         if (height > dbuf->y - desty) height = dbuf->y - desty;
140         if (sbuf){
141                 if (width > sbuf->x - srcx) width = sbuf->x - srcx;
142                 if (height > sbuf->y - srcy) height = sbuf->y - srcy;
143         }
144
145         if (width <= 0) return;
146         if (height <= 0) return;
147
148         drect = dbuf->rect;
149         if (sbuf) srect = sbuf->rect;
150
151         drect += desty * dbuf->x;
152         drect += destx;
153         destx = dbuf->x;
154
155         if (sbuf) {
156                 srect += srcy * sbuf->x;
157                 srect += srcx;
158                 srcx = sbuf->x;
159         } else{
160                 srect = drect;
161                 srcx = destx;
162         }
163
164         for (;height > 0; height--){
165                 operation(drect, srect, width, value);
166                 drect += destx;
167                 srect += srcx;
168         }
169 }
170
171 static void rectcpy(uint *drect, uint *srect, int x) {
172         memcpy(drect,srect, x * sizeof(int));
173 }
174
175 static void rectfill(uint *drect, uint *srect, int x, int value)
176 {
177         for (;x > 0; x--) *drect++ = value;
178 }
179
180
181 void plugin_seq_doit(Cast *cast, float facf0, float facf1, int sx, int sy, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *out, ImBuf *use)
182 {
183         float f1, f2, t1, t2, t3;
184         int x, y, lr;
185         
186         /* fill imbuf 'out' with black */
187         ibufrectop(out, ibuf1,0,0,0,0,32767,32767,rectfill, 0);
188
189         switch (cast->type) {
190                 case 0:
191                         srand48(cast->seed);
192                         break;
193                 case 1:
194                         srand48(cast->seed + facf0 * 1000);
195                         break;
196         }
197
198         for (y = 0; y < sy; y++) {
199                 switch (cast->type) {
200                         case 0:
201                                 if ((y & 1) == 0) {
202                                         f1 = drand48() - 0.5;
203                                         f2 = drand48() - 0.5;
204                                         f1 = cast->swing * f1;
205                                         f2 = cast->swing * f2;
206                                         if (cast->wrap) f2 += 1.0;
207                                         lr = drand48()>0.5;
208                                         t1 = facf0;
209                                 } else t1 = facf1;
210                                 
211                                 t2 = 1.0 - t1;
212                                 t3 = 3.0 * (f1 * t1 * t1 * t2 + f2 * t1 * t2 * t2);
213                                 if (cast->wrap) t3 += t2 * t2 * t2;
214                                 x = sx * t3;
215                                 if (lr) x = -x;
216                                 break;
217                         case 1:
218                                 f1 = drand48() - 0.5;
219                                 f1 = f1 * cast->swing;
220                                 if ((y & 1) == 0) f1 *= facf0;
221                                 else f1 *= facf1;
222                                 x = f1 * sx;
223                                 break;
224                 }
225                 
226                 ibufrectop(out, ibuf1, 0, y, x, y, 32767, 1, rectcpy, 0);
227                 if (cast->wrap) {
228                         ibufrectop(out, ibuf1, 0, y, x + sx, y, 32767, 1, rectcpy, 0);
229                         ibufrectop(out, ibuf1, 0, y, x + sx + sx, y, 32767, 1, rectcpy, 0);
230                         ibufrectop(out, ibuf1, 0, y, x - sx, y, 32767, 1, rectcpy, 0);
231                         ibufrectop(out, ibuf1, 0, y, x - sx - sx, y, 32767, 1, rectcpy, 0);
232                 }
233         }
234 }
235