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