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) 2006 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_composite_util.h" 00034 00035 /* **************** SCALAR MATH ******************** */ 00036 static bNodeSocketTemplate cmp_node_math_in[]= { 00037 { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, 00038 { SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE}, 00039 { -1, 0, "" } 00040 }; 00041 00042 static bNodeSocketTemplate cmp_node_math_out[]= { 00043 { SOCK_FLOAT, 0, "Value"}, 00044 { -1, 0, "" } 00045 }; 00046 00047 static void do_math(bNode *node, float *out, float *in, float *in2) 00048 { 00049 switch(node->custom1) 00050 { 00051 case 0: /* Add */ 00052 out[0]= in[0] + in2[0]; 00053 break; 00054 case 1: /* Subtract */ 00055 out[0]= in[0] - in2[0]; 00056 break; 00057 case 2: /* Multiply */ 00058 out[0]= in[0] * in2[0]; 00059 break; 00060 case 3: /* Divide */ 00061 { 00062 if(in2[0]==0) /* We don't want to divide by zero. */ 00063 out[0]= 0.0; 00064 else 00065 out[0]= in[0] / in2[0]; 00066 } 00067 break; 00068 case 4: /* Sine */ 00069 out[0]= sin(in[0]); 00070 break; 00071 case 5: /* Cosine */ 00072 out[0]= cos(in[0]); 00073 break; 00074 case 6: /* Tangent */ 00075 out[0]= tan(in[0]); 00076 break; 00077 case 7: /* Arc-Sine */ 00078 { 00079 /* Can't do the impossible... */ 00080 if(in[0] <= 1 && in[0] >= -1 ) 00081 out[0]= asin(in[0]); 00082 else 00083 out[0]= 0.0; 00084 } 00085 break; 00086 case 8: /* Arc-Cosine */ 00087 { 00088 /* Can't do the impossible... */ 00089 if( in[0] <= 1 && in[0] >= -1 ) 00090 out[0]= acos(in[0]); 00091 else 00092 out[0]= 0.0; 00093 } 00094 break; 00095 case 9: /* Arc-Tangent */ 00096 out[0]= atan(in[0]); 00097 break; 00098 case 10: /* Power */ 00099 { 00100 /* Only raise negative numbers by full integers */ 00101 if( in[0] >= 0 ) { 00102 out[0]= pow(in[0], in2[0]); 00103 } else { 00104 float y_mod_1 = fmod(in2[0], 1); 00105 /* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */ 00106 if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) { 00107 out[0]= powf(in[0], floorf(in2[0] + 0.5f)); 00108 } else { 00109 out[0] = 0.0f; 00110 } 00111 } 00112 } 00113 break; 00114 case 11: /* Logarithm */ 00115 { 00116 /* Don't want any imaginary numbers... */ 00117 if( in[0] > 0 && in2[0] > 0 ) 00118 out[0]= log(in[0]) / log(in2[0]); 00119 else 00120 out[0]= 0.0; 00121 } 00122 break; 00123 case 12: /* Minimum */ 00124 { 00125 if( in[0] < in2[0] ) 00126 out[0]= in[0]; 00127 else 00128 out[0]= in2[0]; 00129 } 00130 break; 00131 case 13: /* Maximum */ 00132 { 00133 if( in[0] > in2[0] ) 00134 out[0]= in[0]; 00135 else 00136 out[0]= in2[0]; 00137 } 00138 break; 00139 case 14: /* Round */ 00140 { 00141 /* round by the second value */ 00142 if( in2[0] != 0.0f ) 00143 out[0]= floorf(in[0] / in2[0] + 0.5f) * in2[0]; 00144 else 00145 out[0]= floorf(in[0] + 0.5f); 00146 } 00147 break; 00148 case 15: /* Less Than */ 00149 { 00150 if( in[0] < in2[0] ) 00151 out[0]= 1.0f; 00152 else 00153 out[0]= 0.0f; 00154 } 00155 break; 00156 case 16: /* Greater Than */ 00157 { 00158 if( in[0] > in2[0] ) 00159 out[0]= 1.0f; 00160 else 00161 out[0]= 0.0f; 00162 } 00163 break; 00164 } 00165 } 00166 00167 static void node_composit_exec_math(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) 00168 { 00169 CompBuf *cbuf=in[0]->data; 00170 CompBuf *cbuf2=in[1]->data; 00171 CompBuf *stackbuf; 00172 00173 /* check for inputs and outputs for early out*/ 00174 if(out[0]->hasoutput==0) return; 00175 00176 /* no image-color operation */ 00177 if(in[0]->data==NULL && in[1]->data==NULL) { 00178 do_math(node, out[0]->vec, in[0]->vec, in[1]->vec); 00179 return; 00180 } 00181 00182 /*create output based on first input */ 00183 if(cbuf) { 00184 stackbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); 00185 } 00186 /* and if it doesn't exist use the second input since we 00187 know that one of them must exist at this point*/ 00188 else { 00189 stackbuf=alloc_compbuf(cbuf2->x, cbuf2->y, CB_VAL, 1); 00190 } 00191 00192 /* operate in case there's valid size */ 00193 composit2_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, in[1]->data, in[1]->vec, do_math, CB_VAL, CB_VAL); 00194 out[0]->data= stackbuf; 00195 } 00196 00197 void register_node_type_cmp_math(bNodeTreeType *ttype) 00198 { 00199 static bNodeType ntype; 00200 00201 node_type_base(ttype, &ntype, CMP_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); 00202 node_type_socket_templates(&ntype, cmp_node_math_in, cmp_node_math_out); 00203 node_type_size(&ntype, 120, 110, 160); 00204 node_type_label(&ntype, node_math_label); 00205 node_type_exec(&ntype, node_composit_exec_math); 00206 00207 nodeRegisterType(ttype, &ntype); 00208 }