[Bf-blender-cvs] [e12ad2bce0c] master: Geometry Nodes: support Vector Rotate node

Leon Leno noreply at git.blender.org
Mon Mar 8 11:40:25 CET 2021


Commit: e12ad2bce0cca84a10915d8da1417b71142432d1
Author: Leon Leno
Date:   Mon Mar 8 11:37:37 2021 +0100
Branches: master
https://developer.blender.org/rBe12ad2bce0cca84a10915d8da1417b71142432d1

Geometry Nodes: support Vector Rotate node

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

===================================================================

M	release/scripts/startup/nodeitems_builtins.py
M	source/blender/functions/FN_multi_function_builder.hh
M	source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc

===================================================================

diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index ba0a22af0d1..e013317b547 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -543,6 +543,7 @@ geometry_node_categories = [
         NodeItem("ShaderNodeSeparateXYZ"),
         NodeItem("ShaderNodeCombineXYZ"),
         NodeItem("ShaderNodeVectorMath"),
+        NodeItem("ShaderNodeVectorRotate"),
     ]),
     GeometryNodeCategory("GEO_GROUP", "Group", items=node_group_items),
     GeometryNodeCategory("GEO_LAYOUT", "Layout", items=[
diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh
index 6d5ca7f64ad..0cd1bc262be 100644
--- a/source/blender/functions/FN_multi_function_builder.hh
+++ b/source/blender/functions/FN_multi_function_builder.hh
@@ -168,6 +168,63 @@ class CustomMF_SI_SI_SI_SO : public MultiFunction {
   }
 };
 
+/**
+ * Generates a multi-function with the following parameters:
+ * 1. single input (SI) of type In1
+ * 2. single input (SI) of type In2
+ * 3. single input (SI) of type In3
+ * 4. single input (SI) of type In4
+ * 5. single output (SO) of type Out1
+ */
+template<typename In1, typename In2, typename In3, typename In4, typename Out1>
+class CustomMF_SI_SI_SI_SI_SO : public MultiFunction {
+ private:
+  using FunctionT = std::function<void(
+      IndexMask, VSpan<In1>, VSpan<In2>, VSpan<In3>, VSpan<In4>, MutableSpan<Out1>)>;
+  FunctionT function_;
+
+ public:
+  CustomMF_SI_SI_SI_SI_SO(StringRef name, FunctionT function) : function_(std::move(function))
+  {
+    MFSignatureBuilder signature = this->get_builder(name);
+    signature.single_input<In1>("In1");
+    signature.single_input<In2>("In2");
+    signature.single_input<In3>("In3");
+    signature.single_input<In4>("In4");
+    signature.single_output<Out1>("Out1");
+  }
+
+  template<typename ElementFuncT>
+  CustomMF_SI_SI_SI_SI_SO(StringRef name, ElementFuncT element_fn)
+      : CustomMF_SI_SI_SI_SI_SO(name, CustomMF_SI_SI_SI_SI_SO::create_function(element_fn))
+  {
+  }
+
+  template<typename ElementFuncT> static FunctionT create_function(ElementFuncT element_fn)
+  {
+    return [=](IndexMask mask,
+               VSpan<In1> in1,
+               VSpan<In2> in2,
+               VSpan<In3> in3,
+               VSpan<In4> in4,
+               MutableSpan<Out1> out1) {
+      mask.foreach_index([&](int i) {
+        new (static_cast<void *>(&out1[i])) Out1(element_fn(in1[i], in2[i], in3[i], in4[i]));
+      });
+    };
+  }
+
+  void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+  {
+    VSpan<In1> in1 = params.readonly_single_input<In1>(0);
+    VSpan<In2> in2 = params.readonly_single_input<In2>(1);
+    VSpan<In3> in3 = params.readonly_single_input<In3>(2);
+    VSpan<In4> in4 = params.readonly_single_input<In4>(3);
+    MutableSpan<Out1> out1 = params.uninitialized_single_output<Out1>(4);
+    function_(mask, in1, in2, in3, in4, out1);
+  }
+};
+
 /**
  * Generates a multi-function with the following parameters:
  * 1. single mutable (SM) of type Mut1
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
index d6ead5a8b99..30b043439b8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc
@@ -71,6 +71,128 @@ static int gpu_shader_vector_rotate(GPUMaterial *mat,
   return 0;
 }
 
+using blender::float3;
+
+static float3 sh_node_vector_rotate_around_axis(const float3 vector,
+                                                const float3 center,
+                                                const float3 axis,
+                                                const float angle)
+{
+  float3 result = vector - center;
+  float mat[3][3];
+  axis_angle_to_mat3(mat, axis, angle);
+  mul_m3_v3(mat, result);
+  return result + center;
+}
+
+static float3 sh_node_vector_rotate_euler(const float3 vector,
+                                          const float3 center,
+                                          const float3 rotation,
+                                          const bool invert)
+{
+  float mat[3][3];
+  float3 result = vector - center;
+  eul_to_mat3(mat, rotation);
+  if (invert) {
+    invert_m3(mat);
+  }
+  mul_m3_v3(mat, result);
+  return result + center;
+}
+
+static const blender::fn::MultiFunction &get_multi_function(
+    blender::nodes::NodeMFNetworkBuilder &builder)
+{
+  bool invert = builder.bnode().custom2;
+  const int mode = builder.bnode().custom1;
+
+  switch (mode) {
+    case NODE_VECTOR_ROTATE_TYPE_AXIS: {
+      if (invert) {
+        static blender::fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float3, float, float3> fn{
+            "Rotate Axis", [](float3 in, float3 center, float3 axis, float angle) {
+              return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
+            }};
+        return fn;
+      }
+      static blender::fn::CustomMF_SI_SI_SI_SI_SO<float3, float3, float3, float, float3> fn{
+          "Rotate Axis", [](float3 in, float3 center, float3 axis, float angle) {
+            return sh_node_vector_rotate_around_axis(in, center, axis, angle);
+          }};
+      return fn;
+    }
+    case NODE_VECTOR_ROTATE_TYPE_AXIS_X: {
+      float3 axis = float3(1.0f, 0.0f, 0.0f);
+      if (invert) {
+        static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{
+            "Rotate X-Axis", [=](float3 in, float3 center, float angle) {
+              return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
+            }};
+        return fn;
+      }
+      static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{
+          "Rotate X-Axis", [=](float3 in, float3 center, float angle) {
+            return sh_node_vector_rotate_around_axis(in, center, axis, angle);
+          }};
+      return fn;
+    }
+    case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: {
+      float3 axis = float3(0.0f, 1.0f, 0.0f);
+      if (invert) {
+        static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{
+            "Rotate Y-Axis", [=](float3 in, float3 center, float angle) {
+              return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
+            }};
+        return fn;
+      }
+      static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{
+          "Rotate Y-Axis", [=](float3 in, float3 center, float angle) {
+            return sh_node_vector_rotate_around_axis(in, center, axis, angle);
+          }};
+      return fn;
+    }
+    case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: {
+      float3 axis = float3(0.0f, 0.0f, 1.0f);
+      if (invert) {
+        static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{
+            "Rotate Z-Axis", [=](float3 in, float3 center, float angle) {
+              return sh_node_vector_rotate_around_axis(in, center, axis, -angle);
+            }};
+        return fn;
+      }
+      static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{
+          "Rotate Z-Axis", [=](float3 in, float3 center, float angle) {
+            return sh_node_vector_rotate_around_axis(in, center, axis, angle);
+          }};
+      return fn;
+    }
+    case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: {
+      if (invert) {
+        static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3> fn{
+            "Rotate Euler", [](float3 in, float3 center, float3 rotation) {
+              return sh_node_vector_rotate_euler(in, center, rotation, true);
+            }};
+        return fn;
+      }
+      static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3> fn{
+          "Rotate Euler", [](float3 in, float3 center, float3 rotation) {
+            return sh_node_vector_rotate_euler(in, center, rotation, false);
+          }};
+      return fn;
+    }
+    default:
+      BLI_assert(false);
+      return builder.get_not_implemented_fn();
+  }
+}
+
+static void sh_node_vector_rotate_expand_in_mf_network(
+    blender::nodes::NodeMFNetworkBuilder &builder)
+{
+  const blender::fn::MultiFunction &fn = get_multi_function(builder);
+  builder.set_matching_fn(fn);
+}
+
 static void node_shader_update_vector_rotate(bNodeTree *UNUSED(ntree), bNode *node)
 {
   bNodeSocket *sock_rotation = nodeFindSocket(node, SOCK_IN, "Rotation");
@@ -85,10 +207,11 @@ void register_node_type_sh_vector_rotate(void)
 {
   static bNodeType ntype;
 
-  sh_node_type_base(&ntype, SH_NODE_VECTOR_ROTATE, "Vector Rotate", NODE_CLASS_OP_VECTOR, 0);
+  sh_fn_node_type_base(&ntype, SH_NODE_VECTOR_ROTATE, "Vector Rotate", NODE_CLASS_OP_VECTOR, 0);
   node_type_socket_templates(&ntype, sh_node_vector_rotate_in, sh_node_vector_rotate_out);
   node_type_gpu(&ntype, gpu_shader_vector_rotate);
   node_type_update(&ntype, node_shader_update_vector_rotate);
+  ntype.expand_in_mf_network = sh_node_vector_rotate_expand_in_mf_network;
 
   nodeRegisterType(&ntype);
 }



More information about the Bf-blender-cvs mailing list