Blender V2.61 - r43446

node_shader_math.c

Go to the documentation of this file.
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 }