Blender V2.61 - r43446

node_shader_vectMath.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 
00034 #include "node_shader_util.h"
00035 
00036 
00037 /* **************** VECTOR MATH ******************** */ 
00038 static bNodeSocketTemplate sh_node_vect_math_in[]= { 
00039     { SOCK_VECTOR, 1, "Vector", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, PROP_NONE}, 
00040     { SOCK_VECTOR, 1, "Vector", 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 1.0f, PROP_NONE}, 
00041     { -1, 0, "" } 
00042 };
00043 
00044 static bNodeSocketTemplate sh_node_vect_math_out[]= {
00045     { SOCK_VECTOR, 0, "Vector"}, 
00046     { SOCK_FLOAT, 0, "Value"},
00047     { -1, 0, "" } 
00048 };
00049 
00050 static void node_shader_exec_vect_math(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 
00051 { 
00052     float vec1[3], vec2[3];
00053     
00054     nodestack_get_vec(vec1, SOCK_VECTOR, in[0]);
00055     nodestack_get_vec(vec2, SOCK_VECTOR, in[1]);
00056     
00057     if(node->custom1 == 0) {    /* Add */
00058         out[0]->vec[0]= vec1[0] + vec2[0];
00059         out[0]->vec[1]= vec1[1] + vec2[1];
00060         out[0]->vec[2]= vec1[2] + vec2[2];
00061         
00062         out[1]->vec[0]= (fabs(out[0]->vec[0]) + fabs(out[0]->vec[0]) + fabs(out[0]->vec[0])) / 3;
00063     }
00064     else if(node->custom1 == 1) {   /* Subtract */
00065         out[0]->vec[0]= vec1[0] - vec2[0];
00066         out[0]->vec[1]= vec1[1] - vec2[1];
00067         out[0]->vec[2]= vec1[2] - vec2[2];
00068         
00069         out[1]->vec[0]= (fabs(out[0]->vec[0]) + fabs(out[0]->vec[0]) + fabs(out[0]->vec[0])) / 3;
00070     }
00071     else if(node->custom1 == 2) {   /* Average */
00072         out[0]->vec[0]= vec1[0] + vec2[0];
00073         out[0]->vec[1]= vec1[1] + vec2[1];
00074         out[0]->vec[2]= vec1[2] + vec2[2];
00075         
00076         out[1]->vec[0] = normalize_v3( out[0]->vec );
00077     }
00078     else if(node->custom1 == 3) {   /* Dot product */
00079         out[1]->vec[0]= (vec1[0] * vec2[0]) + (vec1[1] * vec2[1]) + (vec1[2] * vec2[2]);
00080     }
00081     else if(node->custom1 == 4) {   /* Cross product */
00082         out[0]->vec[0]= (vec1[1] * vec2[2]) - (vec1[2] * vec2[1]);
00083         out[0]->vec[1]= (vec1[2] * vec2[0]) - (vec1[0] * vec2[2]);
00084         out[0]->vec[2]= (vec1[0] * vec2[1]) - (vec1[1] * vec2[0]);
00085         
00086         out[1]->vec[0] = normalize_v3( out[0]->vec );
00087     }
00088     else if(node->custom1 == 5) {   /* Normalize */
00089         if(in[0]->hasinput || !in[1]->hasinput) {   /* This one only takes one input, so we've got to choose. */
00090             out[0]->vec[0]= vec1[0];
00091             out[0]->vec[1]= vec1[1];
00092             out[0]->vec[2]= vec1[2];
00093         }
00094         else {
00095             out[0]->vec[0]= vec2[0];
00096             out[0]->vec[1]= vec2[1];
00097             out[0]->vec[2]= vec2[2];
00098         }
00099         
00100         out[1]->vec[0] = normalize_v3( out[0]->vec );
00101     }
00102     
00103 }
00104 
00105 static int gpu_shader_vect_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out)
00106 {
00107     static const char *names[] = {"vec_math_add", "vec_math_sub",
00108         "vec_math_average", "vec_math_dot", "vec_math_cross",
00109         "vec_math_normalize"};
00110 
00111     switch (node->custom1) {
00112         case 0:
00113         case 1:
00114         case 2:
00115         case 3:
00116         case 4:
00117             GPU_stack_link(mat, names[node->custom1], NULL, out,
00118                 GPU_socket(&in[0]), GPU_socket(&in[1]));
00119             break;
00120         case 5:
00121             if(in[0].hasinput || !in[1].hasinput)
00122                 GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0]));
00123             else
00124                 GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[1]));
00125             break;
00126         default:
00127             return 0;
00128     }
00129     
00130     return 1;
00131 }
00132 
00133 void register_node_type_sh_vect_math(bNodeTreeType *ttype)
00134 {
00135     static bNodeType ntype;
00136 
00137     node_type_base(ttype, &ntype, SH_NODE_VECT_MATH, "Vector Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS);
00138     node_type_compatibility(&ntype, NODE_OLD_SHADING|NODE_NEW_SHADING);
00139     node_type_socket_templates(&ntype, sh_node_vect_math_in, sh_node_vect_math_out);
00140     node_type_size(&ntype, 80, 75, 140);
00141     node_type_label(&ntype, node_vect_math_label);
00142     node_type_storage(&ntype, "node_vect_math", NULL, NULL);
00143     node_type_exec(&ntype, node_shader_exec_vect_math);
00144     node_type_gpu(&ntype, gpu_shader_vect_math);
00145 
00146     nodeRegisterType(ttype, &ntype);
00147 }