Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarrett Johnson <jarrett.johnson>2021-10-03 04:04:45 +0300
committerHans Goudey <h.goudey@me.com>2021-10-03 04:04:45 +0300
commitc5c94e3eae74a7023c84cf0906cfa814c39f84dd (patch)
treef278960c94a812219931630049ee993f91b330a9
parent34cf33eb12099d3a1940de070d7dc7e88e3bebc7 (diff)
Geometry Nodes: Add Rotate Euler Node
This commit introduces the Rotate Euler function node which modifies an input euler rotation. The node replaces the "Point Rotate" node. Addresses T91375. Differential Revision: https://developer.blender.org/D12531
-rw-r--r--release/scripts/startup/nodeitems_builtins.py1
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.cc1
-rw-r--r--source/blender/makesdna/DNA_node_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c45
-rw-r--r--source/blender/nodes/CMakeLists.txt1
-rw-r--r--source/blender/nodes/NOD_function.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h3
-rw-r--r--source/blender/nodes/function/nodes/node_fn_rotate_euler.cc138
9 files changed, 200 insertions, 1 deletions
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index ab810b54a69..37d5c5997ad 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -624,6 +624,7 @@ geometry_node_categories = [
NodeItem("ShaderNodeClamp"),
NodeItem("ShaderNodeMath"),
NodeItem("FunctionNodeBooleanMath"),
+ NodeItem("FunctionNodeRotateEuler"),
NodeItem("FunctionNodeFloatCompare"),
NodeItem("FunctionNodeFloatToInt"),
NodeItem("GeometryNodeSwitch"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 0ad92f8d190..c4c3733f3a9 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1529,6 +1529,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_STRING_SUBSTRING 1212
#define FN_NODE_INPUT_SPECIAL_CHARACTERS 1213
#define FN_NODE_RANDOM_VALUE 1214
+#define FN_NODE_ROTATE_EULER 1215
/** \} */
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index aeb43b4a017..73060caa2f8 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5824,6 +5824,7 @@ static void registerFunctionNodes()
register_node_type_fn_input_string();
register_node_type_fn_input_vector();
register_node_type_fn_random_value();
+ register_node_type_fn_rotate_euler();
register_node_type_fn_string_length();
register_node_type_fn_string_substring();
register_node_type_fn_value_to_string();
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 35be6a4b48e..ea87cef1118 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -2032,6 +2032,11 @@ typedef enum GeometryNodeRotatePointsType {
GEO_NODE_POINT_ROTATE_TYPE_AXIS_ANGLE = 1,
} GeometryNodeRotatePointsType;
+typedef enum FunctionNodeRotatePointsType {
+ FN_NODE_ROTATE_EULER_TYPE_EULER = 0,
+ FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE = 1,
+} FunctionNodeRotatePointsType;
+
typedef enum GeometryNodeAttributeVectorRotateMode {
GEO_NODE_VECTOR_ROTATE_TYPE_AXIS = 0,
GEO_NODE_VECTOR_ROTATE_TYPE_AXIS_X = 1,
@@ -2052,6 +2057,11 @@ typedef enum GeometryNodeRotatePointsSpace {
GEO_NODE_POINT_ROTATE_SPACE_POINT = 1,
} GeometryNodeRotatePointsSpace;
+typedef enum FunctionNodeRotateEulerSpace {
+ FN_NODE_ROTATE_EULER_SPACE_OBJECT = 0,
+ FN_NODE_ROTATE_EULER_SPACE_POINT = 1,
+} FunctionNodeRotateEulerSpace;
+
typedef enum GeometryNodeAlignRotationToVectorAxis {
GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_X = 0,
GEO_NODE_ALIGN_ROTATION_TO_VECTOR_AXIS_Y = 1,
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 20fcff58990..df1be412bc4 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -9818,6 +9818,51 @@ static void def_geo_point_rotate(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
+static void def_fn_rotate_euler(StructRNA *srna)
+{
+ static const EnumPropertyItem type_items[] = {
+ {FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE,
+ "AXIS_ANGLE",
+ ICON_NONE,
+ "Axis Angle",
+ "Rotate around an axis by an angle"},
+ {FN_NODE_ROTATE_EULER_TYPE_EULER,
+ "EULER",
+ ICON_NONE,
+ "Euler",
+ "Rotate around the X, Y, and Z axes"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static const EnumPropertyItem space_items[] = {
+ {FN_NODE_ROTATE_EULER_SPACE_OBJECT,
+ "OBJECT",
+ ICON_NONE,
+ "Object",
+ "Rotate the input rotation in the local space of the object"},
+ {FN_NODE_ROTATE_EULER_SPACE_POINT,
+ "POINT",
+ ICON_NONE,
+ "Point",
+ "Rotate the input rotation in its local space"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, type_items);
+ RNA_def_property_ui_text(prop, "Type", "Method used to describe the rotation");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
+
+ prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom2");
+ RNA_def_property_enum_items(prop, space_items);
+ RNA_def_property_ui_text(prop, "Space", "Base orientation of the points");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
static void def_geo_align_rotation_to_vector(StructRNA *srna)
{
static const EnumPropertyItem axis_items[] = {
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 78b6ee1d7a6..903a30dd383 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -142,6 +142,7 @@ set(SRC
function/nodes/node_fn_input_string.cc
function/nodes/node_fn_input_vector.cc
function/nodes/node_fn_random_value.cc
+ function/nodes/node_fn_rotate_euler.cc
function/nodes/node_fn_string_length.cc
function/nodes/node_fn_string_substring.cc
function/nodes/node_fn_value_to_string.cc
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index 9aa4c04000e..450e999bea4 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -29,6 +29,7 @@ void register_node_type_fn_input_special_characters(void);
void register_node_type_fn_input_string(void);
void register_node_type_fn_input_vector(void);
void register_node_type_fn_random_value(void);
+void register_node_type_fn_rotate_euler(void);
void register_node_type_fn_string_length(void);
void register_node_type_fn_string_substring(void);
void register_node_type_fn_value_to_string(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index d328efe9cba..c13ab199691 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -272,9 +272,10 @@ DefNode(FunctionNode, FN_NODE_INPUT_SPECIAL_CHARACTERS, 0, "INPUT_SPECIAL_CHARAC
DefNode(FunctionNode, FN_NODE_INPUT_STRING, def_fn_input_string, "INPUT_STRING", InputString, "String", "")
DefNode(FunctionNode, FN_NODE_INPUT_VECTOR, def_fn_input_vector, "INPUT_VECTOR", InputVector, "Vector", "")
DefNode(FunctionNode, FN_NODE_RANDOM_VALUE, def_fn_random_value, "RANDOM_VALUE", RandomValue, "Random Value", "")
-DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
+DefNode(FunctionNode, FN_NODE_ROTATE_EULER, def_fn_rotate_euler, "ROTATE_EULER", RotateEuler, "Rotate Euler", "")
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
DefNode(FunctionNode, FN_NODE_STRING_SUBSTRING, 0, "STRING_SUBSTRING", StringSubstring, "String Substring", "")
+DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
DefNode(GeometryNode, GEO_NODE_LEGACY_ALIGN_ROTATION_TO_VECTOR, def_geo_align_rotation_to_vector, "LEGACY_ALIGN_ROTATION_TO_VECTOR", LegacyAlignRotationToVector, "Align Rotation to Vector", "")
DefNode(GeometryNode, GEO_NODE_LEGACY_ATTRIBUTE_CLAMP, def_geo_attribute_clamp, "LEGACY_ATTRIBUTE_CLAMP", LegacyAttributeClamp, "Attribute Clamp", "")
diff --git a/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc
new file mode 100644
index 00000000000..cbae1648663
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc
@@ -0,0 +1,138 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "RNA_enum_types.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "node_function_util.hh"
+
+namespace blender::nodes {
+static void fn_node_rotate_euler_declare(NodeDeclarationBuilder &b)
+{
+ b.is_function_node();
+ b.add_input<decl::Vector>("Rotation").subtype(PROP_EULER).hide_value();
+ b.add_input<decl::Vector>("Rotate By").subtype(PROP_EULER);
+ b.add_input<decl::Vector>("Axis").default_value({0.0, 0.0, 1.0}).subtype(PROP_XYZ);
+ b.add_input<decl::Float>("Angle").subtype(PROP_ANGLE);
+ b.add_output<decl::Vector>("Rotation");
+};
+
+static void fn_node_rotate_euler_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *rotate_by_socket = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 1));
+ bNodeSocket *axis_socket = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 2));
+ bNodeSocket *angle_socket = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 3));
+
+ nodeSetSocketAvailability(rotate_by_socket,
+ ELEM(node->custom1, FN_NODE_ROTATE_EULER_TYPE_EULER));
+ nodeSetSocketAvailability(axis_socket,
+ ELEM(node->custom1, FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE));
+ nodeSetSocketAvailability(angle_socket,
+ ELEM(node->custom1, FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE));
+}
+
+static void fn_node_rotate_euler_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "type", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE);
+}
+
+static const fn::MultiFunction *get_multi_function(bNode &bnode)
+{
+ static fn::CustomMF_SI_SI_SO<float3, float3, float3> obj_euler_rot{
+ "Rotate Euler by Euler/Object", [](const float3 &input, const float3 &rotation) {
+ float input_mat[3][3];
+ eul_to_mat3(input_mat, input);
+ float rot_mat[3][3];
+ eul_to_mat3(rot_mat, rotation);
+ float mat_res[3][3];
+ mul_m3_m3m3(mat_res, rot_mat, input_mat);
+ float3 result;
+ mat3_to_eul(result, mat_res);
+ return result;
+ }};
+ static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> obj_AA_rot{
+ "Rotate Euler by AxisAngle/Object",
+ [](const float3 &input, const float3 &axis, float angle) {
+ float input_mat[3][3];
+ eul_to_mat3(input_mat, input);
+ float rot_mat[3][3];
+ axis_angle_to_mat3(rot_mat, axis, angle);
+ float mat_res[3][3];
+ mul_m3_m3m3(mat_res, rot_mat, input_mat);
+ float3 result;
+ mat3_to_eul(result, mat_res);
+ return result;
+ }};
+ static fn::CustomMF_SI_SI_SO<float3, float3, float3> point_euler_rot{
+ "Rotate Euler by Euler/Point", [](const float3 &input, const float3 &rotation) {
+ float input_mat[3][3];
+ eul_to_mat3(input_mat, input);
+ float rot_mat[3][3];
+ eul_to_mat3(rot_mat, rotation);
+ float mat_res[3][3];
+ mul_m3_m3m3(mat_res, input_mat, rot_mat);
+ float3 result;
+ mat3_to_eul(result, mat_res);
+ return result;
+ }};
+ static fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> point_AA_rot{
+ "Rotate Euler by AxisAngle/Point", [](const float3 &input, const float3 &axis, float angle) {
+ float input_mat[3][3];
+ eul_to_mat3(input_mat, input);
+ float rot_mat[3][3];
+ axis_angle_to_mat3(rot_mat, axis, angle);
+ float mat_res[3][3];
+ mul_m3_m3m3(mat_res, input_mat, rot_mat);
+ float3 result;
+ mat3_to_eul(result, mat_res);
+ return result;
+ }};
+ short type = bnode.custom1;
+ short space = bnode.custom2;
+ if (type == FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE) {
+ return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? &obj_AA_rot : &point_AA_rot;
+ }
+ if (type == FN_NODE_ROTATE_EULER_TYPE_EULER) {
+ return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? &obj_euler_rot : &point_euler_rot;
+ }
+ BLI_assert_unreachable();
+ return nullptr;
+}
+
+static void fn_node_rotate_euler_build_multi_function(NodeMultiFunctionBuilder &builder)
+{
+ const fn::MultiFunction *fn = get_multi_function(builder.node());
+ builder.set_matching_fn(fn);
+}
+
+} // namespace blender::nodes
+
+void register_node_type_fn_rotate_euler()
+{
+ static bNodeType ntype;
+ fn_node_type_base(&ntype, FN_NODE_ROTATE_EULER, "Rotate Euler", NODE_CLASS_CONVERTER, 0);
+ ntype.declare = blender::nodes::fn_node_rotate_euler_declare;
+ ntype.draw_buttons = blender::nodes::fn_node_rotate_euler_layout;
+ node_type_update(&ntype, blender::nodes::fn_node_rotate_euler_update);
+ ntype.build_multi_function = blender::nodes::fn_node_rotate_euler_build_multi_function;
+ nodeRegisterType(&ntype);
+}