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