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