Merged the particles-2010 branch with node improvements into trunk.
[blender.git] / source / blender / nodes / texture / nodes / node_texture_proc.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) 2005 Blender Foundation.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): Robin Allen
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/nodes/texture/nodes/node_texture_proc.c
30  *  \ingroup texnodes
31  */
32
33
34 #include "node_texture_util.h"
35 #include "NOD_texture.h"
36
37 #include "RE_shader_ext.h"
38
39 /* 
40         In this file: wrappers to use procedural textures as nodes
41 */
42
43
44 static bNodeSocketTemplate outputs_both[]= {
45         { SOCK_RGBA, 0, "Color",  1.0f, 0.0f, 0.0f, 1.0f },
46         { SOCK_VECTOR, 0, "Normal", 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, PROP_DIRECTION },
47         { -1, 0, "" }
48 };
49 static bNodeSocketTemplate outputs_color_only[]= {
50         { SOCK_RGBA, 0, "Color" },
51         { -1, 0, "" }
52 };
53
54 /* Inputs common to all, #defined because nodes will need their own inputs too */
55 #define I 2 /* count */
56 #define COMMON_INPUTS \
57         { SOCK_RGBA, 1, "Color 1", 0.0f, 0.0f, 0.0f, 1.0f }, \
58         { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f }
59
60 /* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */
61 static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread)
62 {
63         TexResult texres;
64         int textype;
65         
66         if(is_normal) {
67                 texres.nor = result;
68         }
69         else
70                 texres.nor = NULL;
71         
72         textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex,
73                 &texres, thread, 0, p->shi, p->mtex);
74         
75         if(is_normal)
76                 return;
77         
78         if(textype & TEX_RGB) {
79                 QUATCOPY(result, &texres.tr);
80         }
81         else {
82                 QUATCOPY(result, col1);
83                 ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2);
84         }
85 }
86
87 typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, short thread);
88
89 static void texfn(
90         float *result, 
91         TexParams *p,
92         bNode *node, 
93         bNodeStack **in,
94         char is_normal, 
95         MapFn map_inputs,
96         short thread)
97 {
98         Tex tex = *((Tex*)(node->storage));
99         float col1[4], col2[4];
100         tex_input_rgba(col1, in[0], p, thread);
101         tex_input_rgba(col2, in[1], p, thread);
102         
103         map_inputs(&tex, in, p, thread);
104         
105         do_proc(result, p, col1, col2, is_normal, &tex, thread);
106 }
107
108 static int count_outputs(bNode *node)
109 {
110         bNodeSocket *sock;
111         int num = 0;
112         for(sock= node->outputs.first; sock; sock= sock->next) {
113                 num++;
114         }
115         return num;
116 }
117
118 /* Boilerplate generators */
119
120 #define ProcNoInputs(name) \
121                 static void name##_map_inputs(Tex *UNUSED(tex), bNodeStack **UNUSED(in), TexParams *UNUSED(p), short UNUSED(thread)) \
122                 {}
123
124 #define ProcDef(name) \
125                 static void name##_colorfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread)  \
126                 {                                                                                                    \
127                                 texfn(result, p, node, in, 0, &name##_map_inputs, thread);                               \
128                 }                                                                                                    \
129                 static void name##_normalfn(float *result, TexParams *p, bNode *node, bNodeStack **in, short thread) \
130                 {                                                                                                    \
131                                 texfn(result, p, node, in, 1, &name##_map_inputs, thread);                               \
132                 }                                                                                                    \
133                 static void name##_exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)                  \
134                 {                                                                                                    \
135                                 int outs = count_outputs(node);                                                              \
136                                 if(outs >= 1) tex_output(node, in, out[0], &name##_colorfn, data);                                 \
137                                 if(outs >= 2) tex_output(node, in, out[1], &name##_normalfn, data);                                \
138                 }
139
140
141 /* --- VORONOI -- */
142 static bNodeSocketTemplate voronoi_inputs[]= {
143         COMMON_INPUTS,
144         { SOCK_FLOAT, 1, "W1", 1.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f, PROP_NONE },
145         { SOCK_FLOAT, 1, "W2", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f, PROP_NONE },
146         { SOCK_FLOAT, 1, "W3", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f, PROP_NONE },
147         { SOCK_FLOAT, 1, "W4", 0.0f, 0.0f, 0.0f, 0.0f,   -2.0f, 2.0f, PROP_NONE },
148         
149         { SOCK_FLOAT, 1, "iScale", 1.0f, 0.0f, 0.0f, 0.0f,    0.01f,  10.0f, PROP_UNSIGNED },
150         { SOCK_FLOAT, 1, "Size",   0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 4.0f, PROP_UNSIGNED },
151         
152         { -1, 0, "" }
153 };
154 static void voronoi_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
155 {
156         tex->vn_w1 = tex_input_value(in[I+0], p, thread);
157         tex->vn_w2 = tex_input_value(in[I+1], p, thread);
158         tex->vn_w3 = tex_input_value(in[I+2], p, thread);
159         tex->vn_w4 = tex_input_value(in[I+3], p, thread);
160         
161         tex->ns_outscale = tex_input_value(in[I+4], p, thread);
162         tex->noisesize   = tex_input_value(in[I+5], p, thread);
163 }
164 ProcDef(voronoi)
165
166 /* --- BLEND -- */
167 static bNodeSocketTemplate blend_inputs[]= {
168         COMMON_INPUTS,
169         { -1, 0, "" }
170 };
171 ProcNoInputs(blend)
172 ProcDef(blend)
173
174 /* -- MAGIC -- */
175 static bNodeSocketTemplate magic_inputs[]= {
176         COMMON_INPUTS,
177         { SOCK_FLOAT, 1, "Turbulence", 5.0f, 0.0f, 0.0f, 0.0f,   0.0f, 200.0f, PROP_UNSIGNED },
178         { -1, 0, "" }
179 };
180 static void magic_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
181 {
182         tex->turbul = tex_input_value(in[I+0], p, thread);
183 }
184 ProcDef(magic)
185
186 /* --- MARBLE --- */
187 static bNodeSocketTemplate marble_inputs[]= {
188         COMMON_INPUTS,
189         { SOCK_FLOAT, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f, PROP_UNSIGNED },
190         { SOCK_FLOAT, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f, PROP_UNSIGNED },
191         { -1, 0, "" }
192 };
193 static void marble_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
194 {
195         tex->noisesize = tex_input_value(in[I+0], p, thread);
196         tex->turbul    = tex_input_value(in[I+1], p, thread);
197 }
198 ProcDef(marble)
199
200 /* --- CLOUDS --- */
201 static bNodeSocketTemplate clouds_inputs[]= {
202         COMMON_INPUTS,
203         { SOCK_FLOAT, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f, PROP_UNSIGNED },
204         { -1, 0, "" }
205 };
206 static void clouds_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
207 {
208         tex->noisesize = tex_input_value(in[I+0], p, thread);
209 }
210 ProcDef(clouds)
211
212 /* --- DISTORTED NOISE --- */
213 static bNodeSocketTemplate distnoise_inputs[]= {
214         COMMON_INPUTS,
215         { SOCK_FLOAT, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f,  2.0f, PROP_UNSIGNED },
216         { SOCK_FLOAT, 1, "Distortion", 1.00f, 0.0f, 0.0f, 0.0f,   0.0000f, 10.0f, PROP_UNSIGNED },
217         { -1, 0, "" }
218 };
219 static void distnoise_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
220 {
221         tex->noisesize   = tex_input_value(in[I+0], p, thread);
222         tex->dist_amount = tex_input_value(in[I+1], p, thread);
223 }
224 ProcDef(distnoise)
225
226 /* --- WOOD --- */
227 static bNodeSocketTemplate wood_inputs[]= {
228         COMMON_INPUTS,
229         { SOCK_FLOAT, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f, PROP_UNSIGNED },
230         { SOCK_FLOAT, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f, PROP_UNSIGNED },
231         { -1, 0, "" }
232 };
233 static void wood_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
234 {
235         tex->noisesize = tex_input_value(in[I+0], p, thread);
236         tex->turbul    = tex_input_value(in[I+1], p, thread);
237 }
238 ProcDef(wood)
239
240 /* --- MUSGRAVE --- */
241 static bNodeSocketTemplate musgrave_inputs[]= {
242         COMMON_INPUTS,
243         { SOCK_FLOAT, 1, "H",          1.0f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f, PROP_UNSIGNED },
244         { SOCK_FLOAT, 1, "Lacunarity", 2.0f, 0.0f, 0.0f, 0.0f,   0.0f,    6.0f, PROP_UNSIGNED },
245         { SOCK_FLOAT, 1, "Octaves",    2.0f, 0.0f, 0.0f, 0.0f,   0.0f,    8.0f, PROP_UNSIGNED },
246         
247         { SOCK_FLOAT, 1, "iScale",     1.0f,  0.0f, 0.0f, 0.0f,  0.0f,   10.0f, PROP_UNSIGNED },
248         { SOCK_FLOAT, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,  0.0001f, 2.0f, PROP_UNSIGNED },
249         { -1, 0, "" }
250 };
251 static void musgrave_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
252 {
253         tex->mg_H          = tex_input_value(in[I+0], p, thread);
254         tex->mg_lacunarity = tex_input_value(in[I+1], p, thread);
255         tex->mg_octaves    = tex_input_value(in[I+2], p, thread);
256         tex->ns_outscale   = tex_input_value(in[I+3], p, thread);
257         tex->noisesize     = tex_input_value(in[I+4], p, thread);
258 }
259 ProcDef(musgrave)
260
261 /* --- NOISE --- */
262 static bNodeSocketTemplate noise_inputs[]= {
263         COMMON_INPUTS,
264         { -1, 0, "" }
265 };
266 ProcNoInputs(noise)
267 ProcDef(noise)
268
269 /* --- STUCCI --- */
270 static bNodeSocketTemplate stucci_inputs[]= {
271         COMMON_INPUTS,
272         { SOCK_FLOAT, 1, "Size",       0.25f, 0.0f, 0.0f, 0.0f,   0.0001f, 2.0f, PROP_UNSIGNED },
273         { SOCK_FLOAT, 1, "Turbulence", 5.0f,  0.0f, 0.0f, 0.0f,   0.0f, 200.0f, PROP_UNSIGNED },
274         { -1, 0, "" }
275 };
276 static void stucci_map_inputs(Tex *tex, bNodeStack **in, TexParams *p, short thread)
277 {
278         tex->noisesize = tex_input_value(in[I+0], p, thread);
279         tex->turbul    = tex_input_value(in[I+1], p, thread);
280 }
281 ProcDef(stucci)
282
283 /* --- */
284
285 static void init(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp))
286 {
287         Tex *tex = MEM_callocN(sizeof(Tex), "Tex");
288         node->storage= tex;
289         
290         default_tex(tex);
291         tex->type = node->type - TEX_NODE_PROC;
292         
293         if(tex->type == TEX_WOOD)
294                 tex->stype = TEX_BANDNOISE;
295         
296 }
297
298 /* Node type definitions */
299 #define TexDef(TEXTYPE, outputs, name, Name) \
300 void register_node_type_tex_proc_##name(ListBase *lb) \
301 { \
302         static bNodeType ntype; \
303         \
304         node_type_base(&ntype, TEX_NODE_PROC+TEXTYPE, Name, NODE_CLASS_TEXTURE, NODE_PREVIEW|NODE_OPTIONS); \
305         node_type_socket_templates(&ntype, name##_inputs, outputs); \
306         node_type_size(&ntype, 140, 80, 140); \
307         node_type_init(&ntype, init); \
308         node_type_storage(&ntype, "Tex", node_free_standard_storage, node_copy_standard_storage); \
309         node_type_exec(&ntype, name##_exec); \
310         \
311         nodeRegisterType(lb, &ntype); \
312 }
313         
314 #define C outputs_color_only
315 #define CV outputs_both
316         
317 TexDef(TEX_VORONOI,   CV, voronoi,   "Voronoi"  )
318 TexDef(TEX_BLEND,     C,  blend,     "Blend"    )
319 TexDef(TEX_MAGIC,     C,  magic,     "Magic"    )
320 TexDef(TEX_MARBLE,    CV, marble,    "Marble"   )
321 TexDef(TEX_CLOUDS,    CV, clouds,    "Clouds"   )
322 TexDef(TEX_WOOD,      CV, wood,      "Wood"     )
323 TexDef(TEX_MUSGRAVE,  CV, musgrave,  "Musgrave" )
324 TexDef(TEX_NOISE,     C,  noise,     "Noise"    )
325 TexDef(TEX_STUCCI,    CV, stucci,    "Stucci"   )
326 TexDef(TEX_DISTNOISE, CV, distnoise, "Distorted Noise" )