36
36
/* **************** SCALAR MATH ******************** */
37
static bNodeSocketTemplate sh_node_math_in[]= {
38
{ SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
39
{ SOCK_FLOAT, 1, "Value", 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
37
static bNodeSocketTemplate sh_node_math_in[] = {
38
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
39
{ SOCK_FLOAT, 1, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
43
static bNodeSocketTemplate sh_node_math_out[]= {
44
{ SOCK_FLOAT, 0, "Value"},
43
static bNodeSocketTemplate sh_node_math_out[] = {
44
{ SOCK_FLOAT, 0, N_("Value")},
48
48
static void node_shader_exec_math(void *UNUSED(data), bNode *node, bNodeStack **in,
51
switch(node->custom1) {
51
switch (node->custom1) {
54
out[0]->vec[0]= in[0]->vec[0] + in[1]->vec[0];
54
out[0]->vec[0] = in[0]->vec[0] + in[1]->vec[0];
56
56
case 1: /* Subtract */
57
out[0]->vec[0]= in[0]->vec[0] - in[1]->vec[0];
57
out[0]->vec[0] = in[0]->vec[0] - in[1]->vec[0];
59
59
case 2: /* Multiply */
60
out[0]->vec[0]= in[0]->vec[0] * in[1]->vec[0];
60
out[0]->vec[0] = in[0]->vec[0] * in[1]->vec[0];
62
62
case 3: /* Divide */
64
64
if (in[1]->vec[0]==0) /* We don't want to divide by zero. */
67
out[0]->vec[0]= in[0]->vec[0] / in[1]->vec[0];
67
out[0]->vec[0] = in[0]->vec[0] / in[1]->vec[0];
72
72
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
73
out[0]->vec[0]= sin(in[0]->vec[0]);
73
out[0]->vec[0] = sin(in[0]->vec[0]);
75
out[0]->vec[0]= sin(in[1]->vec[0]);
75
out[0]->vec[0] = sin(in[1]->vec[0]);
78
78
case 5: /* Cosine */
80
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
81
out[0]->vec[0]= cos(in[0]->vec[0]);
80
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
81
out[0]->vec[0] = cos(in[0]->vec[0]);
83
out[0]->vec[0]= cos(in[1]->vec[0]);
83
out[0]->vec[0] = cos(in[1]->vec[0]);
86
86
case 6: /* Tangent */
88
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
89
out[0]->vec[0]= tan(in[0]->vec[0]);
88
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
89
out[0]->vec[0] = tan(in[0]->vec[0]);
91
out[0]->vec[0]= tan(in[1]->vec[0]);
91
out[0]->vec[0] = tan(in[1]->vec[0]);
94
94
case 7: /* Arc-Sine */
96
96
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
97
97
/* Can't do the impossible... */
98
98
if ( in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1 )
99
out[0]->vec[0]= asin(in[0]->vec[0]);
99
out[0]->vec[0] = asin(in[0]->vec[0]);
101
out[0]->vec[0] = 0.0;
104
104
/* Can't do the impossible... */
105
105
if ( in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1 )
106
out[0]->vec[0]= asin(in[1]->vec[0]);
106
out[0]->vec[0] = asin(in[1]->vec[0]);
108
out[0]->vec[0] = 0.0;
114
114
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
115
115
/* Can't do the impossible... */
116
116
if ( in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1 )
117
out[0]->vec[0]= acos(in[0]->vec[0]);
117
out[0]->vec[0] = acos(in[0]->vec[0]);
119
out[0]->vec[0] = 0.0;
122
122
/* Can't do the impossible... */
123
123
if ( in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1 )
124
out[0]->vec[0]= acos(in[1]->vec[0]);
124
out[0]->vec[0] = acos(in[1]->vec[0]);
126
out[0]->vec[0] = 0.0;
130
130
case 9: /* Arc-Tangent */
132
132
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
133
out[0]->vec[0]= atan(in[0]->vec[0]);
133
out[0]->vec[0] = atan(in[0]->vec[0]);
135
out[0]->vec[0]= atan(in[1]->vec[0]);
135
out[0]->vec[0] = atan(in[1]->vec[0]);
138
138
case 10: /* Power */
140
/* Don't want any imaginary numbers... */
141
if ( in[0]->vec[0] >= 0 )
142
out[0]->vec[0]= pow(in[0]->vec[0], in[1]->vec[0]);
140
/* Only raise negative numbers by full integers */
141
if ( in[0]->vec[0] >= 0 ) {
142
out[0]->vec[0] = pow(in[0]->vec[0], in[1]->vec[0]);
145
float y_mod_1 = fabsf(fmodf(in[1]->vec[0], 1.0f));
147
/* if input value is not nearly an integer, fall back to zero, nicer than straight rounding */
148
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
149
out[0]->vec[0] = powf(in[0]->vec[0], floorf(in[1]->vec[0] + 0.5f));
152
out[0]->vec[0] = 0.0f;
147
158
case 11: /* Logarithm */
149
160
/* Don't want any imaginary numbers... */
150
161
if ( in[0]->vec[0] > 0 && in[1]->vec[0] > 0 )
151
out[0]->vec[0]= log(in[0]->vec[0]) / log(in[1]->vec[0]);
162
out[0]->vec[0] = log(in[0]->vec[0]) / log(in[1]->vec[0]);
164
out[0]->vec[0] = 0.0;
156
167
case 12: /* Minimum */
158
169
if ( in[0]->vec[0] < in[1]->vec[0] )
159
out[0]->vec[0]= in[0]->vec[0];
170
out[0]->vec[0] = in[0]->vec[0];
161
out[0]->vec[0]= in[1]->vec[0];
172
out[0]->vec[0] = in[1]->vec[0];
164
175
case 13: /* Maximum */
166
177
if ( in[0]->vec[0] > in[1]->vec[0] )
167
out[0]->vec[0]= in[0]->vec[0];
178
out[0]->vec[0] = in[0]->vec[0];
169
out[0]->vec[0]= in[1]->vec[0];
180
out[0]->vec[0] = in[1]->vec[0];
172
183
case 14: /* Round */
174
185
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
175
out[0]->vec[0]= (in[0]->vec[0]<0)?(int)(in[0]->vec[0] - 0.5f):(int)(in[0]->vec[0] + 0.5f);
186
out[0]->vec[0] = (in[0]->vec[0]<0)?(int)(in[0]->vec[0] - 0.5f):(int)(in[0]->vec[0] + 0.5f);
177
out[0]->vec[0]= (in[1]->vec[0]<0)?(int)(in[1]->vec[0] - 0.5f):(int)(in[1]->vec[0] + 0.5f);
188
out[0]->vec[0] = (in[1]->vec[0]<0)?(int)(in[1]->vec[0] - 0.5f):(int)(in[1]->vec[0] + 0.5f);
180
191
case 15: /* Less Than */
182
193
if ( in[0]->vec[0] < in[1]->vec[0] )
183
out[0]->vec[0]= 1.0f;
194
out[0]->vec[0] = 1.0f;
185
out[0]->vec[0]= 0.0f;
196
out[0]->vec[0] = 0.0f;
188
199
case 16: /* Greater Than */
190
201
if ( in[0]->vec[0] > in[1]->vec[0] )
191
out[0]->vec[0]= 1.0f;
202
out[0]->vec[0] = 1.0f;
193
out[0]->vec[0]= 0.0f;
204
out[0]->vec[0] = 0.0f;
199
210
static int gpu_shader_math(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out)
227
if (in[0].hasinput || !in[1].hasinput)
228
GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[0]));
230
GPU_stack_link(mat, names[node->custom1], NULL, out, GPU_socket(&in[1]));
237
if (in[0].hasinput || !in[1].hasinput) {
238
/* use only first item and terminator */
239
GPUNodeStack tmp_in[2];
240
memcpy(&tmp_in[0], &in[0], sizeof(GPUNodeStack));
241
memcpy(&tmp_in[1], &in[2], sizeof(GPUNodeStack));
242
GPU_stack_link(mat, names[node->custom1], tmp_in, out);
245
/* use only second item and terminator */
246
GPUNodeStack tmp_in[2];
247
memcpy(&tmp_in[0], &in[1], sizeof(GPUNodeStack));
248
memcpy(&tmp_in[1], &in[2], sizeof(GPUNodeStack));
249
GPU_stack_link(mat, names[node->custom1], tmp_in, out);