Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2005 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 /* 00034 HOW TEXTURE NODES WORK 00035 00036 In contrast to Shader nodes, which place a color into the output 00037 stack when executed, Texture nodes place a TexDelegate* there. To 00038 obtain a color value from this, a node further up the chain reads 00039 the TexDelegate* from its input stack, and uses tex_call_delegate to 00040 retrieve the color from the delegate. 00041 00042 comments: (ton) 00043 00044 This system needs recode, a node system should rely on the stack, and 00045 callbacks for nodes only should evaluate own node, not recursively go 00046 over other previous ones. 00047 */ 00048 00049 #include <assert.h> 00050 #include "node_texture_util.h" 00051 00052 #define PREV_RES 128 /* default preview resolution */ 00053 00054 static void tex_call_delegate(TexDelegate *dg, float *out, TexParams *params, short thread) 00055 { 00056 if(dg->node->need_exec) { 00057 dg->fn(out, params, dg->node, dg->in, thread); 00058 00059 if(dg->cdata->do_preview) 00060 tex_do_preview(dg->node, params->previewco, out); 00061 } 00062 } 00063 00064 static void tex_input(float *out, int sz, bNodeStack *in, TexParams *params, short thread) 00065 { 00066 TexDelegate *dg = in->data; 00067 if(dg) { 00068 tex_call_delegate(dg, in->vec, params, thread); 00069 00070 if(in->hasoutput && in->sockettype == SOCK_FLOAT) 00071 in->vec[1] = in->vec[2] = in->vec[0]; 00072 } 00073 memcpy(out, in->vec, sz * sizeof(float)); 00074 } 00075 00076 void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread) 00077 { 00078 tex_input(out, 3, in, params, thread); 00079 } 00080 00081 void tex_input_rgba(float *out, bNodeStack *in, TexParams *params, short thread) 00082 { 00083 tex_input(out, 4, in, params, thread); 00084 00085 if(in->hasoutput && in->sockettype == SOCK_FLOAT) 00086 { 00087 out[1] = out[2] = out[0]; 00088 out[3] = 1; 00089 } 00090 00091 if(in->hasoutput && in->sockettype == SOCK_VECTOR) { 00092 out[0] = out[0] * .5f + .5f; 00093 out[1] = out[1] * .5f + .5f; 00094 out[2] = out[2] * .5f + .5f; 00095 out[3] = 1; 00096 } 00097 } 00098 00099 float tex_input_value(bNodeStack *in, TexParams *params, short thread) 00100 { 00101 float out[4]; 00102 tex_input_vec(out, in, params, thread); 00103 return out[0]; 00104 } 00105 00106 void params_from_cdata(TexParams *out, TexCallData *in) 00107 { 00108 out->co = in->co; 00109 out->dxt = in->dxt; 00110 out->dyt = in->dyt; 00111 out->previewco = in->co; 00112 out->osatex = in->osatex; 00113 out->cfra = in->cfra; 00114 out->shi = in->shi; 00115 out->mtex = in->mtex; 00116 } 00117 00118 void tex_do_preview(bNode *node, float *co, float *col) 00119 { 00120 bNodePreview *preview= node->preview; 00121 00122 if(preview) { 00123 int xs= ((co[0] + 1.0f)*0.5f)*preview->xsize; 00124 int ys= ((co[1] + 1.0f)*0.5f)*preview->ysize; 00125 00126 nodeAddToPreview(node, col, xs, ys, 0); /* 0 = no color management */ 00127 } 00128 } 00129 00130 void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata) 00131 { 00132 TexDelegate *dg; 00133 if(!out->data) 00134 /* Freed in tex_end_exec (node.c) */ 00135 dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate"); 00136 else 00137 dg = out->data; 00138 00139 dg->cdata= cdata; 00140 dg->fn = texfn; 00141 dg->node = node; 00142 memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*)); 00143 dg->type = out->sockettype; 00144 } 00145 00146 /* Used for muted nodes, just pass the TexDelegate data from input to output… 00147 * XXX That *%!?¿§ callback TextureDelegate system is a nightmare here! 00148 * So I have to use an ugly hack (checking inputs twice!)… Yuk! 00149 * I’d be very happy if someone can imagine a better solution 00150 * (without changing the whole stuff). 00151 * WARNING: These are only suitable for default muting behavior. If you want a custom 00152 * one for your texnode, you must not use them! 00153 */ 00154 static void passonvalfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread) 00155 { 00156 bNodeSocket *sock; 00157 int i; 00158 00159 /* test the inputs */ 00160 for(i=0, sock = node->inputs.first; sock; sock = sock->next, i++) { 00161 if(sock->link && sock->type==SOCK_FLOAT && in) { 00162 out[0] = tex_input_value(in[i], p, thread); 00163 break; 00164 } 00165 } 00166 } 00167 00168 static void passonvecfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread) 00169 { 00170 bNodeSocket *sock; 00171 int i; 00172 00173 /* test the inputs */ 00174 for(i=0, sock = node->inputs.first; sock; sock = sock->next, i++) { 00175 if(sock->link && sock->type==SOCK_VECTOR && in) { 00176 tex_input_vec(out, in[i], p, thread); 00177 break; 00178 } 00179 } 00180 } 00181 00182 static void passoncolfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread) 00183 { 00184 bNodeSocket *sock; 00185 int i; 00186 00187 /* test the inputs */ 00188 for(i=0, sock = node->inputs.first; sock; sock = sock->next, i++) { 00189 if(sock->link && sock->type==SOCK_RGBA && in) { 00190 tex_input_rgba(out, in[i], p, thread); 00191 break; 00192 } 00193 } 00194 } 00195 00196 void node_tex_pass_on(void *data, int UNUSED(thread), struct bNode *node, void *UNUSED(nodedata), 00197 struct bNodeStack **in, struct bNodeStack **out) 00198 { 00199 ListBase links; 00200 LinkInOutsMuteNode *lnk; 00201 int i; 00202 00203 if(node->typeinfo->mutelinksfunc == NULL) 00204 return; 00205 00206 /* Get default muting links (as bNodeStack pointers). */ 00207 links = node->typeinfo->mutelinksfunc(NULL, node, in, out, NULL, NULL); 00208 00209 for(lnk = links.first; lnk; lnk = lnk->next) { 00210 /* XXX This breaks the generality of the system. 00211 * Again, unfortunately, I see no other way to do due to tex nodes behavior... 00212 */ 00213 void (*passonfn)(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread); 00214 switch(((bNodeStack*)(lnk->in))->sockettype) { 00215 case SOCK_FLOAT: 00216 passonfn = passonvalfn; 00217 break; 00218 case SOCK_VECTOR: 00219 passonfn = passonvecfn; 00220 break; 00221 case SOCK_RGBA: 00222 passonfn = passoncolfn; 00223 break; 00224 default: 00225 passonfn = NULL; 00226 } 00227 for(i = 0; i < lnk->num_outs; i++) { 00228 if(((bNodeStack*)(lnk->in))->data && passonfn) 00229 tex_output(node, in, ((bNodeStack*)(lnk->outs))+i, passonfn, data); 00230 } 00231 /* If num_outs > 1, lnk->outs was an allocated table of pointers... */ 00232 if(i > 1) 00233 MEM_freeN(lnk->outs); 00234 } 00235 BLI_freelistN(&links); 00236 } 00237 00238 void ntreeTexCheckCyclics(struct bNodeTree *ntree) 00239 { 00240 bNode *node; 00241 for(node= ntree->nodes.first; node; node= node->next) { 00242 00243 if(node->type == TEX_NODE_TEXTURE && node->id) 00244 { 00245 /* custom2 stops the node from rendering */ 00246 if(node->custom1) { 00247 node->custom2 = 1; 00248 node->custom1 = 0; 00249 } else { 00250 Tex *tex = (Tex *)node->id; 00251 00252 node->custom2 = 0; 00253 00254 node->custom1 = 1; 00255 if(tex->use_nodes && tex->nodetree) { 00256 ntreeTexCheckCyclics(tex->nodetree); 00257 } 00258 node->custom1 = 0; 00259 } 00260 } 00261 00262 } 00263 }