Shading: Extend Vector Math Node with Sin, Cos, Tan and Wrap functions
authorCharlie Jolly <charlie>
Fri, 14 Feb 2020 21:46:10 +0000 (21:46 +0000)
committerCharlie Jolly <mistajolly@gmail.com>
Fri, 14 Feb 2020 22:14:05 +0000 (22:14 +0000)
This adds some extra functions recently added to the float Maths Node.
Not all functions have been ported over in this patch.

Also:
+ Tidy up menu
+ Change node color to match other vector nodes, this helps distinguish vector and float nodes in the tree
+ Move shared OSL functions to new header node_math.h

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D6713

16 files changed:
intern/cycles/kernel/shaders/CMakeLists.txt
intern/cycles/kernel/shaders/node_math.h [new file with mode: 0644]
intern/cycles/kernel/shaders/node_math.osl
intern/cycles/kernel/shaders/node_vector_math.osl
intern/cycles/kernel/svm/svm_math.h
intern/cycles/kernel/svm/svm_math_util.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/nodes.cpp
intern/cycles/render/nodes.h
release/scripts/addons
source/blender/gpu/shaders/material/gpu_shader_material_math.glsl
source/blender/gpu/shaders/material/gpu_shader_material_math_util.glsl
source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/intern/rna_nodetree.c
source/blender/nodes/shader/nodes/node_shader_vector_math.c

index 8605f23b8fa0baebf1e911b2f1416a02bf07356c..1c9445107ade09afe36f5c0546ecf844198023a0 100644 (file)
@@ -112,6 +112,7 @@ set(SRC_OSL_HEADERS
   node_color.h
   node_fresnel.h
   node_hash.h
+  node_math.h
   node_noise.h
   node_ramp_util.h
   stdcycles.h
diff --git a/intern/cycles/kernel/shaders/node_math.h b/intern/cycles/kernel/shaders/node_math.h
new file mode 100644 (file)
index 0000000..9baf101
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011-2020 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+float safe_divide(float a, float b)
+{
+  return (b != 0.0) ? a / b : 0.0;
+}
+
+vector safe_divide(vector a, vector b)
+{
+  return vector((b[0] != 0.0) ? a[0] / b[0] : 0.0,
+                (b[1] != 0.0) ? a[1] / b[1] : 0.0,
+                (b[2] != 0.0) ? a[2] / b[2] : 0.0);
+}
+
+float safe_modulo(float a, float b)
+{
+  return (b != 0.0) ? fmod(a, b) : 0.0;
+}
+
+float fract(float a)
+{
+  return a - floor(a);
+}
+
+/* See: https://www.iquilezles.org/www/articles/smin/smin.htm. */
+float smoothmin(float a, float b, float c)
+{
+  if (c != 0.0) {
+    float h = max(c - abs(a - b), 0.0) / c;
+    return min(a, b) - h * h * h * c * (1.0 / 6.0);
+  }
+  else {
+    return min(a, b);
+  }
+}
+
+float pingpong(float a, float b)
+{
+  return (b != 0.0) ? abs(fract((a - b) / (b * 2.0)) * b * 2.0 - b) : 0.0;
+}
+
+float safe_sqrt(float a)
+{
+  return (a > 0.0) ? sqrt(a) : 0.0;
+}
+
+float safe_log(float a, float b)
+{
+  return (a > 0.0 && b > 0.0) ? log(a) / log(b) : 0.0;
+}
+
+float safe_divide(float a, float b)
+{
+  return (b != 0.0) ? a / b : 0.0;
+}
+
+vector project(vector v, vector v_proj)
+{
+  float lenSquared = dot(v_proj, v_proj);
+  return (lenSquared != 0.0) ? (dot(v, v_proj) / lenSquared) * v_proj : vector(0.0);
+}
+
+vector snap(vector a, vector b)
+{
+  return floor(safe_divide(a, b)) * b;
+}
+
+/* Adapted from godotengine math_funcs.h. */
+float wrap(float value, float max, float min)
+{
+  float range = max - min;
+  return (range != 0.0) ? value - (range * floor((value - min) / range)) : min;
+}
+
+point wrap(point value, point max, point min)
+{
+  return point(wrap(value[0], max[0], min[0]),
+               wrap(value[1], max[1], min[1]),
+               wrap(value[2], max[2], min[2]));
+}
index 54a2e38dcd61341d8662ccef6e6a735a77b0c8c8..6c3dd1547a61d8dfc939af123eb75c8a952e7eb2 100644 (file)
  */
 
 #include "stdcycles.h"
-
-float safe_divide(float a, float b)
-{
-  return (b != 0.0) ? a / b : 0.0;
-}
-
-float safe_modulo(float a, float b)
-{
-  return (b != 0.0) ? fmod(a, b) : 0.0;
-}
-
-float fract(float a)
-{
-  return a - floor(a);
-}
-
-/* Adapted from godotengine math_funcs.h. */
-float wrap(float value, float max, float min)
-{
-  float range = max - min;
-  return (range != 0.0) ? value - (range * floor((value - min) / range)) : min;
-}
-
-/* See: https://www.iquilezles.org/www/articles/smin/smin.htm. */
-float smoothmin(float a, float b, float c)
-{
-  if (c != 0.0) {
-    float h = max(c - abs(a - b), 0.0) / c;
-    return min(a, b) - h * h * h * c * (1.0 / 6.0);
-  }
-  else {
-    return min(a, b);
-  }
-}
-
-float pingpong(float a, float b)
-{
-  return (b != 0.0) ? abs(fract((a - b) / (b * 2.0)) * b * 2.0 - b) : 0.0;
-}
-
-float safe_sqrt(float a)
-{
-  return (a > 0.0) ? sqrt(a) : 0.0;
-}
-
-float safe_log(float a, float b)
-{
-  return (a > 0.0 && b > 0.0) ? log(a) / log(b) : 0.0;
-}
+#include "node_math.h"
 
 /* OSL asin, acos, and pow functions are safe by default. */
 shader node_math(string type = "add",
index 87bfb663d2c1daea5f2959168c20411967c00c27..7f3ea781f385b09bd29c7b018dc45312b0517806 100644 (file)
  */
 
 #include "stdcycles.h"
-
-float safe_divide(float a, float b)
-{
-  return (b != 0.0) ? a / b : 0.0;
-}
-
-vector safe_divide(vector a, vector b)
-{
-  return vector((b[0] != 0.0) ? a[0] / b[0] : 0.0,
-                (b[1] != 0.0) ? a[1] / b[1] : 0.0,
-                (b[2] != 0.0) ? a[2] / b[2] : 0.0);
-}
-
-vector project(vector v, vector v_proj)
-{
-  float lenSquared = dot(v_proj, v_proj);
-  return (lenSquared != 0.0) ? (dot(v, v_proj) / lenSquared) * v_proj : vector(0.0);
-}
-
-vector snap(vector a, vector b)
-{
-  return floor(safe_divide(a, b)) * b;
-}
+#include "node_math.h"
 
 shader node_vector_math(string type = "add",
                         vector Vector1 = vector(0.0, 0.0, 0.0),
                         vector Vector2 = vector(0.0, 0.0, 0.0),
+                        vector Vector3 = vector(0.0, 0.0, 0.0),
                         float Scale = 1.0,
                         output float Value = 0.0,
                         output vector Vector = vector(0.0, 0.0, 0.0))
@@ -94,6 +73,9 @@ shader node_vector_math(string type = "add",
   else if (type == "modulo") {
     Vector = fmod(Vector1, Vector2);
   }
+  else if (type == "wrap") {
+    Vector = wrap(Vector1, Vector2, Vector3);
+  }
   else if (type == "fraction") {
     Vector = Vector1 - floor(Vector1);
   }
@@ -106,6 +88,15 @@ shader node_vector_math(string type = "add",
   else if (type == "maximum") {
     Vector = max(Vector1, Vector2);
   }
+  else if (type == "sine") {
+    Vector = sin(Vector1);
+  }
+  else if (type == "cosine") {
+    Vector = cos(Vector1);
+  }
+  else if (type == "tangent") {
+    Vector = tan(Vector1);
+  }
   else {
     warning("%s", "Unknown vector math operator!");
   }
index 82cae7bbacf810f5065d631832d97da2b1ee731a..01e01c399eae8473f5fda457f430f07eca7ef6da 100644 (file)
@@ -51,11 +51,19 @@ ccl_device void svm_node_vector_math(KernelGlobals *kg,
 
   float3 a = stack_load_float3(stack, a_stack_offset);
   float3 b = stack_load_float3(stack, b_stack_offset);
+  float3 c;
   float scale = stack_load_float(stack, scale_stack_offset);
 
   float value;
   float3 vector;
-  svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, scale);
+
+  /* 3 Vector Operators */
+  if (type == NODE_VECTOR_MATH_WRAP) {
+    uint4 extra_node = read_node(kg, offset);
+    c = stack_load_float3(stack, extra_node.x);
+  }
+
+  svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, c, scale);
 
   if (stack_valid(value_stack_offset))
     stack_store_float(stack, value_stack_offset, value);
index 7b9eaaeb710e683fce9e0465795d27881bb2d878..8b431b54eea1857f9432f5a2e67bd88d95693daa 100644 (file)
@@ -17,7 +17,7 @@
 CCL_NAMESPACE_BEGIN
 
 ccl_device void svm_vector_math(
-    float *value, float3 *vector, NodeVectorMathType type, float3 a, float3 b, float scale)
+    float *value, float3 *vector, NodeVectorMathType type, float3 a, float3 b, float3 c, float scale)
 {
   switch (type) {
     case NODE_VECTOR_MATH_ADD:
@@ -68,6 +68,10 @@ ccl_device void svm_vector_math(
     case NODE_VECTOR_MATH_MODULO:
       *vector = make_float3(safe_modulo(a.x, b.x), safe_modulo(a.y, b.y), safe_modulo(a.z, b.z));
       break;
+    case NODE_VECTOR_MATH_WRAP:
+      *vector = make_float3(
+          wrapf(a.x, b.x, c.x), wrapf(a.y, b.y, c.y), wrapf(a.z, b.z, c.z));
+      break;
     case NODE_VECTOR_MATH_FRACTION:
       *vector = a - floor(a);
       break;
@@ -80,6 +84,15 @@ ccl_device void svm_vector_math(
     case NODE_VECTOR_MATH_MAXIMUM:
       *vector = max(a, b);
       break;
+    case NODE_VECTOR_MATH_SINE:
+      *vector = make_float3(sinf(a.x), sinf(a.y), sinf(a.z));
+      break;
+    case NODE_VECTOR_MATH_COSINE:
+      *vector = make_float3(cosf(a.x), cosf(a.y), cosf(a.z));
+      break;
+    case NODE_VECTOR_MATH_TANGENT:
+      *vector = make_float3(tanf(a.x), tanf(a.y), tanf(a.z));
+      break;
     default:
       *vector = make_float3(0.0f, 0.0f, 0.0f);
       *value = 0.0f;
index 8dbb147e76a5648ebdadbeffa1afc9183efa16ee..828b43eb8e4dce8ed9be2424143e6065b0506d27 100644 (file)
@@ -326,6 +326,10 @@ typedef enum NodeVectorMathType {
   NODE_VECTOR_MATH_ABSOLUTE,
   NODE_VECTOR_MATH_MINIMUM,
   NODE_VECTOR_MATH_MAXIMUM,
+  NODE_VECTOR_MATH_WRAP,
+  NODE_VECTOR_MATH_SINE,
+  NODE_VECTOR_MATH_COSINE,
+  NODE_VECTOR_MATH_TANGENT,
 } NodeVectorMathType;
 
 typedef enum NodeClampType {
index 75e21e00dcf544c3b4749e96843b1f7720716e56..3f5c2aacc98b6a7184e3a15be83ed2d12a37d3cd 100644 (file)
@@ -6022,14 +6022,20 @@ NODE_DEFINE(VectorMathNode)
   type_enum.insert("floor", NODE_VECTOR_MATH_FLOOR);
   type_enum.insert("ceil", NODE_VECTOR_MATH_CEIL);
   type_enum.insert("modulo", NODE_VECTOR_MATH_MODULO);
+  type_enum.insert("wrap", NODE_VECTOR_MATH_WRAP);
   type_enum.insert("fraction", NODE_VECTOR_MATH_FRACTION);
   type_enum.insert("absolute", NODE_VECTOR_MATH_ABSOLUTE);
   type_enum.insert("minimum", NODE_VECTOR_MATH_MINIMUM);
   type_enum.insert("maximum", NODE_VECTOR_MATH_MAXIMUM);
+
+  type_enum.insert("sine", NODE_VECTOR_MATH_SINE);
+  type_enum.insert("cosine", NODE_VECTOR_MATH_COSINE);
+  type_enum.insert("tangent", NODE_VECTOR_MATH_TANGENT);
   SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_MATH_ADD);
 
   SOCKET_IN_VECTOR(vector1, "Vector1", make_float3(0.0f, 0.0f, 0.0f));
   SOCKET_IN_VECTOR(vector2, "Vector2", make_float3(0.0f, 0.0f, 0.0f));
+  SOCKET_IN_VECTOR(vector3, "Vector3", make_float3(0.0f, 0.0f, 0.0f));
   SOCKET_IN_FLOAT(scale, "Scale", 1.0f);
 
   SOCKET_OUT_FLOAT(value, "Value");
@@ -6048,7 +6054,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder)
   float3 vector = make_float3(0.0f, 0.0f, 0.0f);
 
   if (folder.all_inputs_constant()) {
-    svm_vector_math(&value, &vector, type, vector1, vector2, scale);
+    svm_vector_math(&value, &vector, type, vector1, vector2, vector3, scale);
     if (folder.output == output("Value")) {
       folder.make_constant(value);
     }
@@ -6075,11 +6081,24 @@ void VectorMathNode::compile(SVMCompiler &compiler)
   int value_stack_offset = compiler.stack_assign_if_linked(value_out);
   int vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
 
-  compiler.add_node(
-      NODE_VECTOR_MATH,
-      type,
-      compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset),
-      compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
+  /* 3 Vector Operators */
+  if (type == NODE_VECTOR_MATH_WRAP) {
+    ShaderInput *vector3_in = input("Vector3");
+    int vector3_stack_offset = compiler.stack_assign(vector3_in);
+    compiler.add_node(
+        NODE_VECTOR_MATH,
+        type,
+        compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset),
+        compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
+    compiler.add_node(vector3_stack_offset);
+  }
+  else {
+    compiler.add_node(
+        NODE_VECTOR_MATH,
+        type,
+        compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset),
+        compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
+  }
 }
 
 void VectorMathNode::compile(OSLCompiler &compiler)
index a8fe764495765b5d107dab53ce90c07761c28c51..56f709c8a79facbfb10973cc1434ad2ead8b3543 100644 (file)
@@ -1377,6 +1377,7 @@ class VectorMathNode : public ShaderNode {
 
   float3 vector1;
   float3 vector2;
+  float3 vector3;
   float scale;
   NodeVectorMathType type;
 };
index cbcf507f3045e867c4b2d8e0976b76e1753dc49b..47a32a5370d36942674621e5a03e57e8dd4986d8 160000 (submodule)
@@ -1 +1 @@
-Subproject commit cbcf507f3045e867c4b2d8e0976b76e1753dc49b
+Subproject commit 47a32a5370d36942674621e5a03e57e8dd4986d8
index 94f69d35b7eb46fb9e1d4dc1270d64fe70b8c11d..f200d666e28d065ef1dd20761410110da8681189 100644 (file)
@@ -127,8 +127,7 @@ void math_pingpong(float a, float b, float c, out float result)
 /* Adapted from godotengine math_funcs.h. */
 void math_wrap(float a, float b, float c, out float result)
 {
-  float range = b - c;
-  result = (range != 0.0) ? a - (range * floor((a - c) / range)) : c;
+  result = wrap(a, b, c);
 }
 
 void math_sine(float a, float b, float c, out float result)
index 37da918acd6b8a94c42b37dfaa2fe090a320cbad..c6203bc36ab9497323b46694429bfcb4101528d9 100644 (file)
@@ -34,6 +34,17 @@ float compatible_pow(float x, float y)
   return pow(x, y);
 }
 
+float wrap(float a, float b, float c)
+{
+  float range = b - c;
+  return (range != 0.0) ? a - (range * floor((a - c) / range)) : c;
+}
+
+vec3 wrap(vec3 a, vec3 b, vec3 c)
+{
+  return vec3(wrap(a.x, b.x, c.x), wrap(a.y, b.y, c.y), wrap(a.z, b.z, c.z));
+}
+
 float hypot(float x, float y)
 {
   return sqrt(x * x + y * y);
index 420f177e1464f40c5804d07bafea51469b9b2676..256fdcafe3ce36622badd8e5ce0801e3bd9fcb92 100644 (file)
-void vector_math_add(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_add(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = a + b;
 }
 
-void vector_math_subtract(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_subtract(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = a - b;
 }
 
-void vector_math_multiply(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_multiply(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = a * b;
 }
 
-void vector_math_divide(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_divide(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = safe_divide(a, b);
 }
 
-void vector_math_cross(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_cross(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = cross(a, b);
 }
 
-void vector_math_project(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_project(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   float lenSquared = dot(b, b);
   outVector = (lenSquared != 0.0) ? (dot(a, b) / lenSquared) * b : vec3(0.0);
 }
 
-void vector_math_reflect(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_reflect(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = reflect(a, normalize(b));
 }
 
-void vector_math_dot(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_dot(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outValue = dot(a, b);
 }
 
-void vector_math_distance(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_distance(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outValue = distance(a, b);
 }
 
-void vector_math_length(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_length(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outValue = length(a);
 }
 
-void vector_math_scale(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_scale(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = a * scale;
 }
 
-void vector_math_normalize(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_normalize(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = normalize(a);
 }
 
-void vector_math_snap(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_snap(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = floor(safe_divide(a, b)) * b;
 }
 
-void vector_math_floor(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_floor(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = floor(a);
 }
 
-void vector_math_ceil(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_ceil(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = ceil(a);
 }
 
-void vector_math_modulo(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_modulo(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = compatible_fmod(a, b);
 }
 
-void vector_math_fraction(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_wrap(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
+{
+  outVector = wrap(a, b, c);
+}
+
+void vector_math_fraction(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = fract(a);
 }
 
-void vector_math_absolute(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_absolute(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = abs(a);
 }
 
-void vector_math_minimum(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_minimum(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = min(a, b);
 }
 
-void vector_math_maximum(vec3 a, vec3 b, float scale, out vec3 outVector, out float outValue)
+void vector_math_maximum(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
 {
   outVector = max(a, b);
 }
+
+void vector_math_sine(vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
+{
+  outVector = sin(a);
+}
+
+void vector_math_cosine(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
+{
+  outVector = cos(a);
+}
+
+void vector_math_tangent(
+    vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
+{
+  outVector = tan(a);
+}
index 559048ab8cf044ff7ebeb8e1e5699ada41e59843..b7bb267db113d7a8159d2476559232c04a0602e4 100644 (file)
@@ -1265,6 +1265,10 @@ enum {
   NODE_VECTOR_MATH_ABSOLUTE = 17,
   NODE_VECTOR_MATH_MINIMUM = 18,
   NODE_VECTOR_MATH_MAXIMUM = 19,
+  NODE_VECTOR_MATH_WRAP = 20,
+  NODE_VECTOR_MATH_SINE = 21,
+  NODE_VECTOR_MATH_COSINE = 22,
+  NODE_VECTOR_MATH_TANGENT = 23,
 };
 
 /* Clamp node types. */
index 7efd01bbef942aa3a63c9533ba91156209fb61ae..bed00b588e80093fa738e0867a6d8a72b7a187a2 100644 (file)
@@ -164,9 +164,9 @@ const EnumPropertyItem rna_enum_node_math_items[] = {
     {NODE_MATH_TRUNC, "TRUNC", 0, "Truncate", "trunc(A)"},
     {0, "", ICON_NONE, NULL, NULL},
     {NODE_MATH_FRACTION, "FRACT", 0, "Fraction", "The fraction part of A"},
-    {NODE_MATH_MODULO, "MODULO", 0, "Modulo", "A mod B"},
-    {NODE_MATH_SNAP, "SNAP", 0, "Snap", "Snap to increment, snap(A,B)"},
+    {NODE_MATH_MODULO, "MODULO", 0, "Modulo", "Modulo using fmod(A,B)"},
     {NODE_MATH_WRAP, "WRAP", 0, "Wrap", "Wrap value to range, wrap(A,B)"},
+    {NODE_MATH_SNAP, "SNAP", 0, "Snap", "Snap to increment, snap(A,B)"},
     {NODE_MATH_PINGPONG,
      "PINGPONG",
      0,
@@ -211,18 +211,23 @@ const EnumPropertyItem rna_enum_node_vec_math_items[] = {
     {NODE_VECTOR_MATH_SCALE, "SCALE", 0, "Scale", "A multiplied by Scale"},
     {NODE_VECTOR_MATH_NORMALIZE, "NORMALIZE", 0, "Normalize", "Normalize A"},
     {0, "", ICON_NONE, NULL, NULL},
+    {NODE_VECTOR_MATH_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Entrywise absolute"},
+    {NODE_VECTOR_MATH_MINIMUM, "MINIMUM", 0, "Minimum", "Entrywise minimum"},
+    {NODE_VECTOR_MATH_MAXIMUM, "MAXIMUM", 0, "Maximum", "Entrywise maximum"},
+    {NODE_VECTOR_MATH_FLOOR, "FLOOR", 0, "Floor", "Entrywise floor"},
+    {NODE_VECTOR_MATH_CEIL, "CEIL", 0, "Ceil", "Entrywise ceil"},
+    {NODE_VECTOR_MATH_FRACTION, "FRACTION", 0, "Fraction", "The fraction part of A entrywise"},
+    {NODE_VECTOR_MATH_MODULO, "MODULO", 0, "Modulo", "Entrywise modulo using fmod(A,B)"},
+    {NODE_VECTOR_MATH_WRAP, "WRAP", 0, "Wrap", "Entrywise wrap(A,B)"},
     {NODE_VECTOR_MATH_SNAP,
      "SNAP",
      0,
      "Snap",
      "Round A to the largest integer multiple of B less than or equal A"},
-    {NODE_VECTOR_MATH_FLOOR, "FLOOR", 0, "Floor", "Entrywise floor"},
-    {NODE_VECTOR_MATH_CEIL, "CEIL", 0, "Ceil", "Entrywise ceil"},
-    {NODE_VECTOR_MATH_MODULO, "MODULO", 0, "Modulo", "Entrywise modulo"},
-    {NODE_VECTOR_MATH_FRACTION, "FRACTION", 0, "Fraction", "The fraction part of A entrywise"},
-    {NODE_VECTOR_MATH_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Entrywise absolute"},
-    {NODE_VECTOR_MATH_MINIMUM, "MINIMUM", 0, "Minimum", "Entrywise minimum"},
-    {NODE_VECTOR_MATH_MAXIMUM, "MAXIMUM", 0, "Maximum", "Entrywise maximum"},
+    {0, "", ICON_NONE, NULL, NULL},
+    {NODE_VECTOR_MATH_SINE, "SINE", 0, "Sine", "Entrywise sin(A)"},
+    {NODE_VECTOR_MATH_COSINE, "COSINE", 0, "Cosine", "Entrywise cos(A)"},
+    {NODE_VECTOR_MATH_TANGENT, "TANGENT", 0, "Tangent", "Entrywise tan(A)"},
     {0, NULL, 0, NULL, NULL},
 };
 
index ba53cfd17997d5741e5742bbbfb1d115084cf78c..46a1779de0836b2889388ed9a3cf26a9a13072f1 100644 (file)
@@ -25,6 +25,7 @@
 
 /* **************** VECTOR MATH ******************** */
 static bNodeSocketTemplate sh_node_vector_math_in[] = {
+    {SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
     {SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
     {SOCK_VECTOR, 1, N_("Vector"), 0.0f, 0.0f, 0.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
     {SOCK_FLOAT, 1, N_("Scale"), 1.0f, 1.0f, 1.0f, 1.0f, -10000.0f, 10000.0f, PROP_NONE},
@@ -63,6 +64,10 @@ static int gpu_shader_vector_math(GPUMaterial *mat,
       [NODE_VECTOR_MATH_ABSOLUTE] = "vector_math_absolute",
       [NODE_VECTOR_MATH_MINIMUM] = "vector_math_minimum",
       [NODE_VECTOR_MATH_MAXIMUM] = "vector_math_maximum",
+      [NODE_VECTOR_MATH_WRAP] = "vector_math_wrap",
+      [NODE_VECTOR_MATH_SINE] = "vector_math_sine",
+      [NODE_VECTOR_MATH_COSINE] = "vector_math_cosine",
+      [NODE_VECTOR_MATH_TANGENT] = "vector_math_tangent",
   };
 
   if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
@@ -76,6 +81,7 @@ static int gpu_shader_vector_math(GPUMaterial *mat,
 static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node)
 {
   bNodeSocket *sockB = BLI_findlink(&node->inputs, 1);
+  bNodeSocket *sockC = BLI_findlink(&node->inputs, 2);
   bNodeSocket *sockScale = nodeFindSocket(node, SOCK_IN, "Scale");
 
   bNodeSocket *sockVector = nodeFindSocket(node, SOCK_OUT, "Vector");
@@ -83,6 +89,9 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node
 
   nodeSetSocketAvailability(sockB,
                             !ELEM(node->custom1,
+                                  NODE_VECTOR_MATH_SINE,
+                                  NODE_VECTOR_MATH_COSINE,
+                                  NODE_VECTOR_MATH_TANGENT,
                                   NODE_VECTOR_MATH_CEIL,
                                   NODE_VECTOR_MATH_SCALE,
                                   NODE_VECTOR_MATH_FLOOR,
@@ -90,6 +99,7 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node
                                   NODE_VECTOR_MATH_ABSOLUTE,
                                   NODE_VECTOR_MATH_FRACTION,
                                   NODE_VECTOR_MATH_NORMALIZE));
+  nodeSetSocketAvailability(sockC, ELEM(node->custom1, NODE_VECTOR_MATH_WRAP));
   nodeSetSocketAvailability(sockScale, node->custom1 == NODE_VECTOR_MATH_SCALE);
   nodeSetSocketAvailability(sockVector,
                             !ELEM(node->custom1,
@@ -101,13 +111,30 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node
                                  NODE_VECTOR_MATH_LENGTH,
                                  NODE_VECTOR_MATH_DISTANCE,
                                  NODE_VECTOR_MATH_DOT_PRODUCT));
+
+  /* Labels */
+  if (sockB->label[0] != '\0') {
+    sockB->label[0] = '\0';
+  }
+  if (sockC->label[0] != '\0') {
+    sockC->label[0] = '\0';
+  }
+  switch (node->custom1) {
+    case NODE_VECTOR_MATH_WRAP:
+      node_sock_label(sockB, "Max");
+      node_sock_label(sockC, "Min");
+      break;
+    case NODE_VECTOR_MATH_SNAP:
+      node_sock_label(sockB, "Increment");
+      break;
+  }
 }
 
 void register_node_type_sh_vect_math(void)
 {
   static bNodeType ntype;
 
-  sh_node_type_base(&ntype, SH_NODE_VECTOR_MATH, "Vector Math", NODE_CLASS_CONVERTOR, 0);
+  sh_node_type_base(&ntype, SH_NODE_VECTOR_MATH, "Vector Math", NODE_CLASS_OP_VECTOR, 0);
   node_type_socket_templates(&ntype, sh_node_vector_math_in, sh_node_vector_math_out);
   node_type_label(&ntype, node_vector_math_label);
   node_type_gpu(&ntype, gpu_shader_vector_math);