Blender  V2.93
node_texture_math.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2005 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "NOD_texture.h"
25 #include "node_texture_util.h"
26 
27 /* **************** SCALAR MATH ******************** */
29  {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
30  {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
31  {SOCK_FLOAT, N_("Value"), 0.0f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
32  {-1, ""},
33 };
34 
36  {SOCK_FLOAT, N_("Value")},
37  {-1, ""},
38 };
39 
40 static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
41 {
42  float in0 = tex_input_value(in[0], p, thread);
43  float in1 = tex_input_value(in[1], p, thread);
44 
45  switch (node->custom1) {
46 
47  case NODE_MATH_ADD:
48  *out = in0 + in1;
49  break;
50  case NODE_MATH_SUBTRACT:
51  *out = in0 - in1;
52  break;
53  case NODE_MATH_MULTIPLY:
54  *out = in0 * in1;
55  break;
56  case NODE_MATH_DIVIDE: {
57  if (in1 == 0) {
58  /* We don't want to divide by zero. */
59  *out = 0.0;
60  }
61  else {
62  *out = in0 / in1;
63  }
64  break;
65  }
66  case NODE_MATH_SINE: {
67  *out = sinf(in0);
68  break;
69  }
70  case NODE_MATH_COSINE: {
71  *out = cosf(in0);
72  break;
73  }
74  case NODE_MATH_TANGENT: {
75  *out = tanf(in0);
76  break;
77  }
78  case NODE_MATH_SINH: {
79  *out = sinhf(in0);
80  break;
81  }
82  case NODE_MATH_COSH: {
83  *out = coshf(in0);
84  break;
85  }
86  case NODE_MATH_TANH: {
87  *out = tanhf(in0);
88  break;
89  }
90  case NODE_MATH_ARCSINE: {
91  /* Can't do the impossible... */
92  if (in0 <= 1 && in0 >= -1) {
93  *out = asinf(in0);
94  }
95  else {
96  *out = 0.0;
97  }
98  break;
99  }
100  case NODE_MATH_ARCCOSINE: {
101  /* Can't do the impossible... */
102  if (in0 <= 1 && in0 >= -1) {
103  *out = acosf(in0);
104  }
105  else {
106  *out = 0.0;
107  }
108  break;
109  }
110  case NODE_MATH_ARCTANGENT: {
111  *out = atan(in0);
112  break;
113  }
114  case NODE_MATH_POWER: {
115  /* Only raise negative numbers by full integers */
116  if (in0 >= 0) {
117  out[0] = pow(in0, in1);
118  }
119  else {
120  float y_mod_1 = fmod(in1, 1);
121  if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
122  *out = pow(in0, floor(in1 + 0.5f));
123  }
124  else {
125  *out = 0.0;
126  }
127  }
128  break;
129  }
130  case NODE_MATH_LOGARITHM: {
131  /* Don't want any imaginary numbers... */
132  if (in0 > 0 && in1 > 0) {
133  *out = log(in0) / log(in1);
134  }
135  else {
136  *out = 0.0;
137  }
138  break;
139  }
140  case NODE_MATH_MINIMUM: {
141  if (in0 < in1) {
142  *out = in0;
143  }
144  else {
145  *out = in1;
146  }
147  break;
148  }
149  case NODE_MATH_MAXIMUM: {
150  if (in0 > in1) {
151  *out = in0;
152  }
153  else {
154  *out = in1;
155  }
156  break;
157  }
158  case NODE_MATH_ROUND: {
159  *out = (in0 < 0) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f);
160  break;
161  }
162 
163  case NODE_MATH_LESS_THAN: {
164  if (in0 < in1) {
165  *out = 1.0f;
166  }
167  else {
168  *out = 0.0f;
169  }
170  break;
171  }
172 
173  case NODE_MATH_GREATER_THAN: {
174  if (in0 > in1) {
175  *out = 1.0f;
176  }
177  else {
178  *out = 0.0f;
179  }
180  break;
181  }
182 
183  case NODE_MATH_MODULO: {
184  if (in1 == 0.0f) {
185  *out = 0.0f;
186  }
187  else {
188  *out = fmod(in0, in1);
189  }
190  break;
191  }
192 
193  case NODE_MATH_ABSOLUTE: {
194  *out = fabsf(in0);
195  break;
196  }
197 
198  case NODE_MATH_RADIANS: {
199  *out = DEG2RADF(in0);
200  break;
201  }
202 
203  case NODE_MATH_DEGREES: {
204  *out = RAD2DEGF(in0);
205  break;
206  }
207 
208  case NODE_MATH_ARCTAN2: {
209  *out = atan2(in0, in1);
210  break;
211  }
212 
213  case NODE_MATH_SIGN: {
214  *out = compatible_signf(in0);
215  break;
216  }
217 
218  case NODE_MATH_EXPONENT: {
219  *out = expf(in0);
220  break;
221  }
222 
223  case NODE_MATH_FLOOR: {
224  *out = floorf(in0);
225  break;
226  }
227 
228  case NODE_MATH_CEIL: {
229  *out = ceilf(in0);
230  break;
231  }
232 
233  case NODE_MATH_FRACTION: {
234  *out = in0 - floorf(in0);
235  break;
236  }
237 
238  case NODE_MATH_SQRT: {
239  if (in0 > 0.0f) {
240  *out = sqrtf(in0);
241  }
242  else {
243  *out = 0.0f;
244  }
245  break;
246  }
247 
248  case NODE_MATH_INV_SQRT: {
249  if (in0 > 0.0f) {
250  *out = 1.0f / sqrtf(in0);
251  }
252  else {
253  *out = 0.0f;
254  }
255  break;
256  }
257 
258  case NODE_MATH_TRUNC: {
259  if (in0 > 0.0f) {
260  *out = floorf(in0);
261  }
262  else {
263  *out = ceilf(in0);
264  }
265  break;
266  }
267 
268  case NODE_MATH_SNAP: {
269  if (in1 == 0) {
270  *out = 0.0;
271  }
272  else {
273  *out = floorf(in0 / in1) * in1;
274  }
275  break;
276  }
277 
278  case NODE_MATH_WRAP: {
279  float in2 = tex_input_value(in[2], p, thread);
280  *out = wrapf(in0, in1, in2);
281  break;
282  }
283 
284  case NODE_MATH_PINGPONG: {
285  *out = pingpongf(in0, in1);
286  break;
287  }
288 
289  case NODE_MATH_COMPARE: {
290  float in2 = tex_input_value(in[2], p, thread);
291  *out = (fabsf(in0 - in1) <= MAX2(in2, 1e-5f)) ? 1.0f : 0.0f;
292  break;
293  }
294 
295  case NODE_MATH_MULTIPLY_ADD: {
296  float in2 = tex_input_value(in[2], p, thread);
297  *out = in0 * in1 + in2;
298  break;
299  }
300 
301  case NODE_MATH_SMOOTH_MIN: {
302  float in2 = tex_input_value(in[2], p, thread);
303  *out = smoothminf(in0, in1, in2);
304  break;
305  }
306 
307  case NODE_MATH_SMOOTH_MAX: {
308  float in2 = tex_input_value(in[2], p, thread);
309  *out = -smoothminf(-in0, -in1, in2);
310  break;
311  }
312 
313  default: {
314  BLI_assert(0);
315  break;
316  }
317  }
318 
319  if (node->custom2 & SHD_MATH_CLAMP) {
320  CLAMP(*out, 0.0f, 1.0f);
321  }
322 }
323 
324 static void exec(void *data,
325  int UNUSED(thread),
326  bNode *node,
327  bNodeExecData *execdata,
328  bNodeStack **in,
329  bNodeStack **out)
330 {
331  tex_output(node, execdata, in, out[0], &valuefn, data);
332 }
333 
335 {
336  static bNodeType ntype;
337 
341  node_type_storage(&ntype, "", NULL, NULL);
342  node_type_exec(&ntype, NULL, NULL, exec);
344 
345  nodeRegisterType(&ntype);
346 }
void node_type_socket_templates(struct bNodeType *ntype, struct bNodeSocketTemplate *inputs, struct bNodeSocketTemplate *outputs)
Definition: node.cc:4527
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4623
#define NODE_CLASS_CONVERTOR
Definition: BKE_node.h:341
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4599
#define TEX_NODE_MATH
Definition: BKE_node.h:1329
void node_type_exec(struct bNodeType *ntype, NodeInitExecFunction init_exec_fn, NodeFreeExecFunction free_exec_fn, NodeExecFunction exec_fn)
Definition: node.cc:4635
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1298
void node_type_label(struct bNodeType *ntype, void(*labelfunc)(struct bNodeTree *ntree, struct bNode *, char *label, int maxlen))
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define DEG2RADF(_deg)
#define RAD2DEGF(_rad)
#define UNUSED(x)
#define MAX2(a, b)
#define N_(msgid)
@ NODE_MATH_SINH
@ NODE_MATH_SMOOTH_MIN
@ NODE_MATH_TRUNC
@ NODE_MATH_COSH
@ NODE_MATH_SIGN
@ NODE_MATH_DEGREES
@ NODE_MATH_MODULO
@ NODE_MATH_ABSOLUTE
@ NODE_MATH_DIVIDE
@ NODE_MATH_SINE
@ NODE_MATH_ARCTAN2
@ NODE_MATH_ARCCOSINE
@ NODE_MATH_MULTIPLY_ADD
@ NODE_MATH_POWER
@ NODE_MATH_WRAP
@ NODE_MATH_ARCTANGENT
@ NODE_MATH_MINIMUM
@ NODE_MATH_SQRT
@ NODE_MATH_CEIL
@ NODE_MATH_TANH
@ NODE_MATH_GREATER_THAN
@ NODE_MATH_ADD
@ NODE_MATH_FRACTION
@ NODE_MATH_EXPONENT
@ NODE_MATH_LESS_THAN
@ NODE_MATH_ARCSINE
@ NODE_MATH_MAXIMUM
@ NODE_MATH_LOGARITHM
@ NODE_MATH_COMPARE
@ NODE_MATH_INV_SQRT
@ NODE_MATH_MULTIPLY
@ NODE_MATH_PINGPONG
@ NODE_MATH_ROUND
@ NODE_MATH_FLOOR
@ NODE_MATH_SUBTRACT
@ NODE_MATH_COSINE
@ NODE_MATH_SNAP
@ NODE_MATH_TANGENT
@ NODE_MATH_SMOOTH_MAX
@ NODE_MATH_RADIANS
#define SHD_MATH_CLAMP
@ SOCK_FLOAT
Group RGB to Bright Vector Camera CLAMP
@ PROP_NONE
Definition: RNA_types.h:113
OperationNode * node
#define sinf(x)
#define cosf(x)
#define expf(x)
#define tanf(x)
#define asinf(x)
#define ceilf(x)
#define floorf(x)
#define acosf(x)
#define tanhf(x)
#define sinhf(x)
#define coshf(x)
#define fabsf(x)
#define sqrtf(x)
MINLINE float smoothminf(float a, float b, float c)
MINLINE float pingpongf(float value, float scale)
MINLINE float compatible_signf(float f)
MINLINE float wrapf(float value, float max, float min)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
Definition: rall1d.h:359
INLINE Rall1d< T, V, S > log(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:303
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
Definition: rall1d.h:375
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
Definition: rall1d.h:429
void register_node_type_tex_math(void)
static bNodeSocketTemplate outputs[]
static bNodeSocketTemplate inputs[]
static void exec(void *data, int UNUSED(thread), bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass, short flag)
float tex_input_value(bNodeStack *in, TexParams *params, short thread)
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
void node_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
Definition: node_util.c:206
void node_math_update(bNodeTree *UNUSED(ntree), bNode *node)
Definition: node_util.c:100
Compact definition of a node socket.
Definition: BKE_node.h:95
Defines a node type.
Definition: BKE_node.h:221
ccl_device_inline float2 floor(const float2 &a)