Blender V4.3
node_texture_math.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "BLI_math_rotation.h"
10#include "node_texture_util.hh"
11#include "node_util.hh"
12
13/* **************** SCALAR MATH ******************** */
15 {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
16 {SOCK_FLOAT, N_("Value"), 0.5f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
17 {SOCK_FLOAT, N_("Value"), 0.0f, 0.5f, 0.5f, 1.0f, -100.0f, 100.0f, PROP_NONE},
18 {-1, ""},
19};
20
22 {SOCK_FLOAT, N_("Value")},
23 {-1, ""},
24};
25
26static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
27{
28 float in0 = tex_input_value(in[0], p, thread);
29 float in1 = tex_input_value(in[1], p, thread);
30
31 switch (node->custom1) {
32
33 case NODE_MATH_ADD:
34 *out = in0 + in1;
35 break;
37 *out = in0 - in1;
38 break;
40 *out = in0 * in1;
41 break;
42 case NODE_MATH_DIVIDE: {
43 if (in1 == 0) {
44 /* We don't want to divide by zero. */
45 *out = 0.0;
46 }
47 else {
48 *out = in0 / in1;
49 }
50 break;
51 }
52 case NODE_MATH_SINE: {
53 *out = sinf(in0);
54 break;
55 }
56 case NODE_MATH_COSINE: {
57 *out = cosf(in0);
58 break;
59 }
60 case NODE_MATH_TANGENT: {
61 *out = tanf(in0);
62 break;
63 }
64 case NODE_MATH_SINH: {
65 *out = sinhf(in0);
66 break;
67 }
68 case NODE_MATH_COSH: {
69 *out = coshf(in0);
70 break;
71 }
72 case NODE_MATH_TANH: {
73 *out = tanhf(in0);
74 break;
75 }
76 case NODE_MATH_ARCSINE: {
77 /* Can't do the impossible... */
78 if (in0 <= 1 && in0 >= -1) {
79 *out = asinf(in0);
80 }
81 else {
82 *out = 0.0;
83 }
84 break;
85 }
87 /* Can't do the impossible... */
88 if (in0 <= 1 && in0 >= -1) {
89 *out = acosf(in0);
90 }
91 else {
92 *out = 0.0;
93 }
94 break;
95 }
97 *out = atan(in0);
98 break;
99 }
100 case NODE_MATH_POWER: {
101 /* Only raise negative numbers by full integers */
102 if (in0 >= 0) {
103 out[0] = pow(in0, in1);
104 }
105 else {
106 float y_mod_1 = fmod(in1, 1);
107 if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
108 *out = pow(in0, floor(in1 + 0.5f));
109 }
110 else {
111 *out = 0.0;
112 }
113 }
114 break;
115 }
116 case NODE_MATH_LOGARITHM: {
117 /* Don't want any imaginary numbers... */
118 if (in0 > 0 && in1 > 0) {
119 *out = log(in0) / log(in1);
120 }
121 else {
122 *out = 0.0;
123 }
124 break;
125 }
126 case NODE_MATH_MINIMUM: {
127 if (in0 < in1) {
128 *out = in0;
129 }
130 else {
131 *out = in1;
132 }
133 break;
134 }
135 case NODE_MATH_MAXIMUM: {
136 if (in0 > in1) {
137 *out = in0;
138 }
139 else {
140 *out = in1;
141 }
142 break;
143 }
144 case NODE_MATH_ROUND: {
145 *out = (in0 < 0) ? int(in0 - 0.5f) : int(in0 + 0.5f);
146 break;
147 }
148
149 case NODE_MATH_LESS_THAN: {
150 if (in0 < in1) {
151 *out = 1.0f;
152 }
153 else {
154 *out = 0.0f;
155 }
156 break;
157 }
158
160 if (in0 > in1) {
161 *out = 1.0f;
162 }
163 else {
164 *out = 0.0f;
165 }
166 break;
167 }
168
169 case NODE_MATH_MODULO: {
170 if (in1 == 0.0f) {
171 *out = 0.0f;
172 }
173 else {
174 *out = fmod(in0, in1);
175 }
176 break;
177 }
178
180 if (in1 == 0.0f) {
181 *out = 0.0f;
182 }
183 else {
184 *out = in0 - floorf(in0 / in1) * in1;
185 }
186 break;
187 }
188
189 case NODE_MATH_ABSOLUTE: {
190 *out = fabsf(in0);
191 break;
192 }
193
194 case NODE_MATH_RADIANS: {
195 *out = DEG2RADF(in0);
196 break;
197 }
198
199 case NODE_MATH_DEGREES: {
200 *out = RAD2DEGF(in0);
201 break;
202 }
203
204 case NODE_MATH_ARCTAN2: {
205 *out = atan2(in0, in1);
206 break;
207 }
208
209 case NODE_MATH_SIGN: {
210 *out = compatible_signf(in0);
211 break;
212 }
213
214 case NODE_MATH_EXPONENT: {
215 *out = expf(in0);
216 break;
217 }
218
219 case NODE_MATH_FLOOR: {
220 *out = floorf(in0);
221 break;
222 }
223
224 case NODE_MATH_CEIL: {
225 *out = ceilf(in0);
226 break;
227 }
228
229 case NODE_MATH_FRACTION: {
230 *out = in0 - floorf(in0);
231 break;
232 }
233
234 case NODE_MATH_SQRT: {
235 if (in0 > 0.0f) {
236 *out = sqrtf(in0);
237 }
238 else {
239 *out = 0.0f;
240 }
241 break;
242 }
243
244 case NODE_MATH_INV_SQRT: {
245 if (in0 > 0.0f) {
246 *out = 1.0f / sqrtf(in0);
247 }
248 else {
249 *out = 0.0f;
250 }
251 break;
252 }
253
254 case NODE_MATH_TRUNC: {
255 if (in0 > 0.0f) {
256 *out = floorf(in0);
257 }
258 else {
259 *out = ceilf(in0);
260 }
261 break;
262 }
263
264 case NODE_MATH_SNAP: {
265 if (in1 == 0) {
266 *out = 0.0;
267 }
268 else {
269 *out = floorf(in0 / in1) * in1;
270 }
271 break;
272 }
273
274 case NODE_MATH_WRAP: {
275 float in2 = tex_input_value(in[2], p, thread);
276 *out = wrapf(in0, in1, in2);
277 break;
278 }
279
280 case NODE_MATH_PINGPONG: {
281 *out = pingpongf(in0, in1);
282 break;
283 }
284
285 case NODE_MATH_COMPARE: {
286 float in2 = tex_input_value(in[2], p, thread);
287 *out = (fabsf(in0 - in1) <= std::max(in2, 1e-5f)) ? 1.0f : 0.0f;
288 break;
289 }
290
292 float in2 = tex_input_value(in[2], p, thread);
293 *out = in0 * in1 + in2;
294 break;
295 }
296
298 float in2 = tex_input_value(in[2], p, thread);
299 *out = smoothminf(in0, in1, in2);
300 break;
301 }
302
304 float in2 = tex_input_value(in[2], p, thread);
305 *out = -smoothminf(-in0, -in1, in2);
306 break;
307 }
308
309 default: {
310 BLI_assert(0);
311 break;
312 }
313 }
314
315 if (node->custom2 & SHD_MATH_CLAMP) {
316 CLAMP(*out, 0.0f, 1.0f);
317 }
318}
319
320static void exec(void *data,
321 int /*thread*/,
322 bNode *node,
323 bNodeExecData *execdata,
324 bNodeStack **in,
325 bNodeStack **out)
326{
327 tex_output(node, execdata, in, out[0], &valuefn, static_cast<TexCallData *>(data));
328}
329
331{
332 static blender::bke::bNodeType ntype;
333
334 tex_node_type_base(&ntype, TEX_NODE_MATH, "Math", NODE_CLASS_CONVERTER);
335 blender::bke::node_type_socket_templates(&ntype, inputs, outputs);
337 ntype.exec_fn = exec;
339
341}
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:410
#define BLI_assert(a)
Definition BLI_assert.h:50
#define DEG2RADF(_deg)
#define RAD2DEGF(_rad)
#define CLAMP(a, b, c)
@ 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_FLOORED_MODULO
@ 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
@ SHD_MATH_CLAMP
@ SOCK_FLOAT
@ PROP_NONE
Definition RNA_types.hh:136
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
#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)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
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)
ccl_device_inline float2 fmod(const float2 a, const float b)
ccl_device_inline float2 floor(const float2 a)
ccl_device_inline float3 log(float3 v)
void node_type_socket_templates(bNodeType *ntype, bNodeSocketTemplate *inputs, bNodeSocketTemplate *outputs)
Definition node.cc:4570
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void exec(void *data, int, bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack **out)
void register_node_type_tex_math()
static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
void tex_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
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(const bNodeTree *, const bNode *node, char *label, int label_maxncpy)
Definition node_util.cc:203
void node_math_update(bNodeTree *ntree, bNode *node)
Definition node_util.cc:89
Compact definition of a node socket.
Definition BKE_node.hh:103
Defines a node type.
Definition BKE_node.hh:218
NodeExecFunction exec_fn
Definition BKE_node.hh:316
void(* labelfunc)(const bNodeTree *ntree, const bNode *node, char *label, int label_maxncpy)
Definition BKE_node.hh:249
void(* updatefunc)(bNodeTree *ntree, bNode *node)
Definition BKE_node.hh:257
#define N_(msgid)