Index: source/blender/src/drawnode.c =================================================================== --- source/blender/src/drawnode.c (revision 17197) +++ source/blender/src/drawnode.c (working copy) @@ -521,7 +521,7 @@ if(block) { uiBut *bt; - bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Power %x10|Logarithm %x11|Minimum %x12|Maximum %x13|Round %x14|Less Than %x15|Greater Than %x16", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); + bt=uiDefButS(block, MENU, B_NODE_EXEC, "Add %x0|Subtract %x1|Multiply %x2|Divide %x3|Sine %x4|Cosine %x5|Tangent %x6|Arcsine %x7|Arccosine %x8|Arctangent %x9|Sqrt %x10|Power %x11|Logarithm %x12|Minimum %x13|Maximum %x14|Round %x15|Less Than %x16|Greater Than %x17", butr->xmin, butr->ymin, butr->xmax-butr->xmin, 20, &node->custom1, 0, 0, 0, 0, ""); uiButSetFunc(bt, node_but_title_cb, node, bt); } return 20; Index: source/blender/nodes/intern/CMP_nodes/CMP_math.c =================================================================== --- source/blender/nodes/intern/CMP_nodes/CMP_math.c (revision 17197) +++ source/blender/nodes/intern/CMP_nodes/CMP_math.c (working copy) @@ -28,6 +28,7 @@ */ #include "../CMP_util.h" +#include /* **************** SCALAR MATH ******************** */ @@ -42,113 +43,119 @@ { -1, 0, "" } }; -static void do_math(bNode *node, float *out, float *in, float *in2) +static void do_math(bNode *node, float *out, float *in0, float *in1) { + float x = *in0; + float y = *in1; + float result = 0.0; + + /* functions as sinf(float) are C99 conform and should be well supported */ switch(node->custom1) { case 0: /* Add */ - out[0]= in[0] + in2[0]; + result = x+y; break; case 1: /* Subtract */ - out[0]= in[0] - in2[0]; + result = x-y; break; case 2: /* Multiply */ - out[0]= in[0] * in2[0]; + result = x*y; break; case 3: /* Divide */ { - if(in2[0]==0) /* We don't want to divide by zero. */ - out[0]= 0.0; + if (y==0) /* We don't want to divide by zero. */ + result = 0; else - out[0]= in[0] / in2[0]; - } - break; + result = x/y; + } break; case 4: /* Sine */ - out[0]= sin(in[0]); + result = sinf(x); break; case 5: /* Cosine */ - out[0]= cos(in[0]); + result = cosf(x); break; case 6: /* Tangent */ - out[0]= tan(in[0]); + result = tanf(x); break; case 7: /* Arc-Sine */ { /* Can't do the impossible... */ - if(in[0] <= 1 && in[0] >= -1 ) - out[0]= asin(in[0]); + if (x <= 1 && x >= -1 ) + result = asinf(x); else - out[0]= 0.0; - } - break; + result = 0; + } break; case 8: /* Arc-Cosine */ { /* Can't do the impossible... */ - if( in[0] <= 1 && in[0] >= -1 ) - out[0]= acos(in[0]); + if( x <= 1 && x >= -1 ) + result = acosf(x); else - out[0]= 0.0; - } - break; + result = 0; + } break; case 9: /* Arc-Tangent */ - out[0]= atan(in[0]); + result = atanf(x); break; - case 10: /* Power */ + case 10: /* SQRT, sqrt(x) */ { - /* Don't want any imaginary numbers... */ - if( in[0] >= 0 ) - out[0]= pow(in[0], in2[0]); + if( x > 0 ) + result = sqrtf(x); else - out[0]= 0.0; - } - break; - case 11: /* Logarithm */ + result = 0; + } break; + case 11: /* Power, x^y */ { + /* + FIXME button returns inaccurate float, even + if it is set to an integer, so we have to round here. + See Bug 17915. Should be replaced by + if ( x > 0 || y == (int)y ) once the GUI code is fixed. + */ /* Don't want any imaginary numbers... */ - if( in[0] > 0 && in2[0] > 0 ) - out[0]= log(in[0]) / log(in2[0]); + if ( x > 0 ) { + result = powf(x, y); + } else { + float y_mod_1 = fmod(y,1); + if ( y_mod_1 > 0.999 || y_mod_1 < 0.001 ) + result = powf(x, round(y)); + else + result = 0; + } + } break; + case 12: /* Logarithm, logy(x) */ + { + /* Don't want any imaginary numbers... */ + if( x > 0 && y > 0 ) + result = logf(x) / logf(y); else - out[0]= 0.0; - } - break; - case 12: /* Minimum */ + result = 0; + } break; + case 13: /* Minimum */ { - if( in[0] < in2[0] ) - out[0]= in[0]; + if( x < y) + result = x; else - out[0]= in2[0]; - } - break; - case 13: /* Maximum */ + result = y; + } break; + case 14: /* Maximum */ { - if( in[0] > in2[0] ) - out[0]= in[0]; + if( x > y ) + result = x; else - out[0]= in2[0]; - } + result = y; + } break; + case 15: /* Round, round(x)*/ + result = (int)(x + 0.5f); break; - case 14: /* Round */ - { - out[0]= (int)(in[0] + 0.5f); - } + case 16: /* Less Than, x < y */ + result = (x < y); break; - case 15: /* Less Than */ - { - if( in[0] < in2[0] ) - out[0]= 1.0f; - else - out[0]= 0.0f; - } + case 17: /* Greater Than */ + result = (x > y); break; - case 16: /* Greater Than */ - { - if( in[0] > in2[0] ) - out[0]= 1.0f; - else - out[0]= 0.0f; - } - break; } + + *out = result; } static void node_composit_exec_math(void *data, bNode *node, bNodeStack **in, bNodeStack **out) @@ -171,7 +178,7 @@ stackbuf=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); } /* and if it doesn't exist use the second input since we - know that one of them must exist at this point*/ + know that one of them must exist at this point */ else { stackbuf=alloc_compbuf(cbuf2->x, cbuf2->y, CB_VAL, 1); } @@ -198,5 +205,3 @@ /* id */ NULL }; - -