|
Blender
V2.59
|
00001 /* 00002 * $Id: SHD_util.c 38506 2011-07-19 08:31:53Z jbakker $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2005 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 */ 00029 00035 #include "SHD_util.h" 00036 00037 00038 00039 00040 00041 /* ****** */ 00042 00043 void nodestack_get_vec(float *in, short type_in, bNodeStack *ns) 00044 { 00045 float *from= ns->vec; 00046 00047 if(type_in==SOCK_VALUE) { 00048 if(ns->sockettype==SOCK_VALUE) 00049 *in= *from; 00050 else 00051 *in= 0.333333f*(from[0]+from[1]+from[2]); 00052 } 00053 else if(type_in==SOCK_VECTOR) { 00054 if(ns->sockettype==SOCK_VALUE) { 00055 in[0]= from[0]; 00056 in[1]= from[0]; 00057 in[2]= from[0]; 00058 } 00059 else { 00060 VECCOPY(in, from); 00061 } 00062 } 00063 else { /* type_in==SOCK_RGBA */ 00064 if(ns->sockettype==SOCK_RGBA) { 00065 QUATCOPY(in, from); 00066 } 00067 else if(ns->sockettype==SOCK_VALUE) { 00068 in[0]= from[0]; 00069 in[1]= from[0]; 00070 in[2]= from[0]; 00071 in[3]= 1.0f; 00072 } 00073 else { 00074 VECCOPY(in, from); 00075 in[3]= 1.0f; 00076 } 00077 } 00078 } 00079 00080 00081 /* ******************* execute and parse ************ */ 00082 00083 void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) 00084 { 00085 ShaderCallData scd; 00086 /* 00087 @note: preserve material from ShadeInput for material id, nodetree execs change it 00088 fix for bug "[#28012] Mat ID messy with shader nodes" 00089 */ 00090 Material *mat = shi->mat; 00091 /* convert caller data to struct */ 00092 scd.shi= shi; 00093 scd.shr= shr; 00094 00095 /* each material node has own local shaderesult, with optional copying */ 00096 memset(shr, 0, sizeof(ShadeResult)); 00097 00098 ntreeExecTree(ntree, &scd, shi->thread); /* threads */ 00099 // @note: set material back to preserved material 00100 shi->mat = mat; 00101 /* better not allow negative for now */ 00102 if(shr->combined[0]<0.0f) shr->combined[0]= 0.0f; 00103 if(shr->combined[1]<0.0f) shr->combined[1]= 0.0f; 00104 if(shr->combined[2]<0.0f) shr->combined[2]= 0.0f; 00105 00106 } 00107 00108 /* go over all used Geometry and Texture nodes, and return a texco flag */ 00109 /* no group inside needed, this function is called for groups too */ 00110 void ntreeShaderGetTexcoMode(bNodeTree *ntree, int r_mode, short *texco, int *mode) 00111 { 00112 bNode *node; 00113 bNodeSocket *sock; 00114 int a; 00115 00116 ntreeSocketUseFlags(ntree); 00117 00118 for(node= ntree->nodes.first; node; node= node->next) { 00119 if(node->type==SH_NODE_TEXTURE) { 00120 if((r_mode & R_OSA) && node->id) { 00121 Tex *tex= (Tex *)node->id; 00122 if ELEM3(tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) 00123 *texco |= TEXCO_OSA|NEED_UV; 00124 } 00125 /* usability exception... without input we still give the node orcos */ 00126 sock= node->inputs.first; 00127 if(sock==NULL || sock->link==NULL) 00128 *texco |= TEXCO_ORCO|NEED_UV; 00129 } 00130 else if(node->type==SH_NODE_GEOMETRY) { 00131 /* note; sockets always exist for the given type! */ 00132 for(a=0, sock= node->outputs.first; sock; sock= sock->next, a++) { 00133 if(sock->flag & SOCK_IN_USE) { 00134 switch(a) { 00135 case GEOM_OUT_GLOB: 00136 *texco |= TEXCO_GLOB|NEED_UV; break; 00137 case GEOM_OUT_VIEW: 00138 *texco |= TEXCO_VIEW|NEED_UV; break; 00139 case GEOM_OUT_ORCO: 00140 *texco |= TEXCO_ORCO|NEED_UV; break; 00141 case GEOM_OUT_UV: 00142 *texco |= TEXCO_UV|NEED_UV; break; 00143 case GEOM_OUT_NORMAL: 00144 *texco |= TEXCO_NORM|NEED_UV; break; 00145 case GEOM_OUT_VCOL: 00146 *texco |= NEED_UV; *mode |= MA_VERTEXCOL; break; 00147 } 00148 } 00149 } 00150 } 00151 } 00152 } 00153 00154 /* nodes that use ID data get synced with local data */ 00155 void nodeShaderSynchronizeID(bNode *node, int copyto) 00156 { 00157 if(node->id==NULL) return; 00158 00159 if(ELEM(node->type, SH_NODE_MATERIAL, SH_NODE_MATERIAL_EXT)) { 00160 bNodeSocket *sock; 00161 Material *ma= (Material *)node->id; 00162 int a; 00163 00164 /* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */ 00165 for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) { 00166 if(!(sock->flag & SOCK_HIDDEN)) { 00167 if(copyto) { 00168 switch(a) { 00169 case MAT_IN_COLOR: 00170 VECCOPY(&ma->r, sock->ns.vec); break; 00171 case MAT_IN_SPEC: 00172 VECCOPY(&ma->specr, sock->ns.vec); break; 00173 case MAT_IN_REFL: 00174 ma->ref= sock->ns.vec[0]; break; 00175 case MAT_IN_MIR: 00176 VECCOPY(&ma->mirr, sock->ns.vec); break; 00177 case MAT_IN_AMB: 00178 ma->amb= sock->ns.vec[0]; break; 00179 case MAT_IN_EMIT: 00180 ma->emit= sock->ns.vec[0]; break; 00181 case MAT_IN_SPECTRA: 00182 ma->spectra= sock->ns.vec[0]; break; 00183 case MAT_IN_RAY_MIRROR: 00184 ma->ray_mirror= sock->ns.vec[0]; break; 00185 case MAT_IN_ALPHA: 00186 ma->alpha= sock->ns.vec[0]; break; 00187 case MAT_IN_TRANSLUCENCY: 00188 ma->translucency= sock->ns.vec[0]; break; 00189 } 00190 } 00191 else { 00192 switch(a) { 00193 case MAT_IN_COLOR: 00194 VECCOPY(sock->ns.vec, &ma->r); break; 00195 case MAT_IN_SPEC: 00196 VECCOPY(sock->ns.vec, &ma->specr); break; 00197 case MAT_IN_REFL: 00198 sock->ns.vec[0]= ma->ref; break; 00199 case MAT_IN_MIR: 00200 VECCOPY(sock->ns.vec, &ma->mirr); break; 00201 case MAT_IN_AMB: 00202 sock->ns.vec[0]= ma->amb; break; 00203 case MAT_IN_EMIT: 00204 sock->ns.vec[0]= ma->emit; break; 00205 case MAT_IN_SPECTRA: 00206 sock->ns.vec[0]= ma->spectra; break; 00207 case MAT_IN_RAY_MIRROR: 00208 sock->ns.vec[0]= ma->ray_mirror; break; 00209 case MAT_IN_ALPHA: 00210 sock->ns.vec[0]= ma->alpha; break; 00211 case MAT_IN_TRANSLUCENCY: 00212 sock->ns.vec[0]= ma->translucency; break; 00213 } 00214 } 00215 } 00216 } 00217 } 00218 00219 }