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 #include "node_shader_util.h" 00034 00035 00036 /* **************** SCALAR MATH ******************** */ 00037 static bNodeSocketTemplate sh_node_math_in[]= { 00038 { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE}, 00039 { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE}, 00040 { -1, 0, "" } 00041 }; 00042 00043 static bNodeSocketTemplate sh_node_math_out[]= { 00044 { SOCK_FLOAT, 0, "Value"}, 00045 { -1, 0, "" } 00046 }; 00047 00048 static void node_shader_exec_math(void *UNUSED(data), bNode *node, bNodeStack **in, 00049 bNodeStack **out) 00050 { 00051 switch(node->custom1){ 00052 00053 case 0: /* Add */ 00054 out[0]->vec[0]= in[0]->vec[0] + in[1]->vec[0]; 00055 break; 00056 case 1: /* Subtract */ 00057 out[0]->vec[0]= in[0]->vec[0] - in[1]->vec[0]; 00058 break; 00059 case 2: /* Multiply */ 00060 out[0]->vec[0]= in[0]->vec[0] * in[1]->vec[0]; 00061 break; 00062 case 3: /* Divide */ 00063 { 00064 if(in[1]->vec[0]==0) /* We don't want to divide by zero. */ 00065 out[0]->vec[0]= 0.0; 00066 else 00067 out[0]->vec[0]= in[0]->vec[0] / in[1]->vec[0]; 00068 } 00069 break; 00070 case 4: /* Sine */ 00071 { 00072 if(in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ 00073 out[0]->vec[0]= sin(in[0]->vec[0]); 00074 else 00075 out[0]->vec[0]= sin(in[1]->vec[0]); 00076 } 00077 break; 00078 case 5: /* Cosine */ 00079 { 00080 if(in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ 00081 out[0]->vec[0]= cos(in[0]->vec[0]); 00082 else 00083 out[0]->vec[0]= cos(in[1]->vec[0]); 00084 } 00085 break; 00086 case 6: /* Tangent */ 00087 { 00088 if(in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ 00089 out[0]->vec[0]= tan(in[0]->vec[0]); 00090 else 00091 out[0]->vec[0]= tan(in[1]->vec[0]); 00092 } 00093 break; 00094 case 7: /* Arc-Sine */ 00095 { 00096 if(in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */ 00097 /* Can't do the impossible... */ 00098 if( in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1 ) 00099 out[0]->vec[0]= asin(in[0]->vec[0]); 00100 else 00101 out[0]->vec[0]= 0.0; 00102 } 00103 else { 00104 /* Can't do the impossible... */ 00105 if( in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1 ) 00106 out[0]->vec[0]= asin(in[1]->vec[0]); 00107 else 00108 out[0]->vec[0]= 0.0; 00109 } 00110 } 00111 break; 00112 case 8: /* Arc-Cosine */ 00113 { 00114 if(in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */ 00115 /* Can't do the impossible... */ 00116 if( in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1 ) 00117 out[0]->vec[0]= acos(in[0]->vec[0]); 00118 else 00119 out[0]->vec[0]= 0.0; 00120 } 00121 else { 00122 /* Can't do the impossible... */ 00123 if( in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1 ) 00124 out[0]->vec[0]= acos(in[1]->vec[0]); 00125 else 00126 out[0]->vec[0]= 0.0; 00127 } 00128 } 00129 break; 00130 case 9: /* Arc-Tangent */ 00131 { 00132 if(in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ 00133 out[0]->vec[0]= atan(in[0]->vec[0]); 00134 else 00135 out[0]->vec[0]= atan(in[1]->vec[0]); 00136 } 00137 break; 00138 case 10: /* Power */ 00139 { 00140 /* Don't want any imaginary numbers... */ 00141 if( in[0]->vec[0] >= 0 ) 00142 out[0]->vec[0]= pow(in[0]->vec[0], in[1]->vec[0]); 00143 else 00144 out[0]->vec[0]= 0.0; 00145 } 00146 break; 00147 case 11: /* Logarithm */ 00148 { 00149 /* Don't want any imaginary numbers... */ 00150 if( in[0]->vec[0] > 0 && in[1]->vec[0] > 0 ) 00151 out[0]->vec[0]= log(in[0]->vec[0]) / log(in[1]->vec[0]); 00152 else 00153 out[0]->vec[0]= 0.0; 00154 } 00155 break; 00156 case 12: /* Minimum */ 00157 { 00158 if( in[0]->vec[0] < in[1]->vec[0] ) 00159 out[0]->vec[0]= in[0]->vec[0]; 00160 else 00161 out[0]->vec[0]= in[1]->vec[0]; 00162 } 00163 break; 00164 case 13: /* Maximum */ 00165 { 00166 if( in[0]->vec[0] > in[1]->vec[0] ) 00167 out[0]->vec[0]= in[0]->vec[0]; 00168 else 00169 out[0]->vec[0]= in[1]->vec[0]; 00170 } 00171 break; 00172 case 14: /* Round */ 00173 { 00174 if(in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ 00175 out[0]->vec[0]= (in[0]->vec[0]<0)?(int)(in[0]->vec[0] - 0.5f):(int)(in[0]->vec[0] + 0.5f); 00176 else 00177 out[0]->vec[0]= (in[1]->vec[0]<0)?(int)(in[1]->vec[0] - 0.5f):(int)(in[1]->vec[0] + 0.5f); 00178 } 00179 break; 00180 case 15: /* Less Than */ 00181 { 00182 if( in[0]->vec[0] < in[1]->vec[0] ) 00183 out[0]->vec[0]= 1.0f; 00184 else 00185 out[0]->vec[0]= 0.0f; 00186 } 00187 break; 00188 case 16: /* Greater Than */ 00189 { 00190 if( in[0]->vec[0] > in[1]->vec[0] ) 00191 out[0]->vec[0]= 1.0f; 00192 else 00193 out[0]->vec[0]= 0.0f; 00194 } 00195 break; 00196 } 00197 } 00198 00199 static int gpu_shader_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) 00200 { 00201 static const char *names[] = {"math_add", "math_subtract", "math_multiply", 00202 "math_divide", "math_sine", "math_cosine", "math_tangent", "math_asin", 00203 "math_acos", "math_atan", "math_pow", "math_log", "math_min", "math_max", 00204 "math_round", "math_less_than", "math_greater_than"}; 00205 00206 switch (node->custom1) { 00207 case 0: 00208 case 1: 00209 case 2: 00210 case 3: 00211 case 10: 00212 case 11: 00213 case 12: 00214 case 13: 00215 case 15: 00216 case 16: 00217 GPU_stack_link(mat, names[node->custom1], NULL, out, 00218 GPU_socket(&in[0]), GPU_socket(&in[1])); 00219 break; 00220 case 4: 00221 case 5: 00222 case 6: 00223 case 7: 00224 case 8: 00225 case 9: 00226 case 14: 00227 if(in[0].hasinput || !in[1].hasinput) 00228 GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0])); 00229 else 00230 GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[1])); 00231 break; 00232 default: 00233 return 0; 00234 } 00235 00236 return 1; 00237 } 00238 00239 void register_node_type_sh_math(bNodeTreeType *ttype) 00240 { 00241 static bNodeType ntype; 00242 00243 node_type_base(ttype, &ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); 00244 node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); 00245 node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out); 00246 node_type_size(&ntype, 120, 110, 160); 00247 node_type_label(&ntype, node_math_label); 00248 node_type_storage(&ntype, "node_math", NULL, NULL); 00249 node_type_exec(&ntype, node_shader_exec_math); 00250 node_type_gpu(&ntype, gpu_shader_math); 00251 00252 nodeRegisterType(ttype, &ntype); 00253 }