Matrix operations and sockets for geometry nodes #105408

Closed
Lukas Tönne wants to merge 37 commits from LukasTonne/blender:nodes-matrix-types into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
11 changed files with 306 additions and 0 deletions
Showing only changes of commit 8ee84bc82d - Show all commits

View File

@ -207,8 +207,13 @@ class NODE_MT_category_GEO_MATRIX(Menu):
node_add_menu.add_node_type(layout, "FunctionNodeCombineMatrix4x4")
node_add_menu.add_node_type(layout, "FunctionNodeSeparateMatrix3x3")
node_add_menu.add_node_type(layout, "FunctionNodeSeparateMatrix4x4")
node_add_menu.add_node_type(layout, "FunctionNodeDecomposeMatrix3x3")
node_add_menu.add_node_type(layout, "FunctionNodeDecomposeMatrix4x4")
node_add_menu.add_node_type(layout, "FunctionNodeMatrix3x3Math")
node_add_menu.add_node_type(layout, "FunctionNodeMatrix4x4Math")
node_add_menu.add_node_type(layout, "FunctionNodeRotateMatrix3x3")
node_add_menu.add_node_type(layout, "FunctionNodeScaleMatrix3x3")
node_add_menu.add_node_type(layout, "FunctionNodeTranslateMatrix4x4")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)

View File

@ -1581,6 +1581,11 @@ struct TexResult;
#define FN_NODE_COMBINE_MATRIX_4X4 1228
#define FN_NODE_MATRIX_3X3_MATH 1229
#define FN_NODE_MATRIX_4X4_MATH 1230
#define FN_NODE_DECOMPOSE_MATRIX_3X3 1231
#define FN_NODE_DECOMPOSE_MATRIX_4X4 1232
#define FN_NODE_ROTATE_MATRIX_3X3 1233
#define FN_NODE_SCALE_MATRIX_3X3 1234
#define FN_NODE_TRANSLATE_MATRIX_4X4 1235
/** \} */

View File

@ -267,6 +267,8 @@ DefNode(FunctionNode, FN_NODE_COMBINE_COLOR, def_fn_combsep_color, "COMBINE_COLO
DefNode(FunctionNode, FN_NODE_COMBINE_MATRIX_3X3, def_fn_combsep_matrix, "COMBINE_MATRIX_3X3", CombineMatrix3x3, "Combine 3x3 Matrix", "")
DefNode(FunctionNode, FN_NODE_COMBINE_MATRIX_4X4, def_fn_combsep_matrix, "COMBINE_MATRIX_4X4", CombineMatrix4x4, "Combine 4x4 Matrix", "")
DefNode(FunctionNode, FN_NODE_COMPARE, def_compare, "COMPARE", Compare, "Compare", "")
DefNode(FunctionNode, FN_NODE_DECOMPOSE_MATRIX_3X3, 0, "DECOMPOSE_MATRIX_3X3", DecomposeMatrix3x3, "Decompose 3x3 Matrix", "")
DefNode(FunctionNode, FN_NODE_DECOMPOSE_MATRIX_4X4, 0, "DECOMPOSE_MATRIX_4X4", DecomposeMatrix4x4, "Decompose 4x4 Matrix", "")
DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "")
DefNode(FunctionNode, FN_NODE_INPUT_BOOL, def_fn_input_bool, "INPUT_BOOL", InputBool, "Boolean", "")
DefNode(FunctionNode, FN_NODE_INPUT_COLOR, def_fn_input_color, "INPUT_COLOR", InputColor, "Color", "")
@ -281,11 +283,14 @@ DefNode(FunctionNode, FN_NODE_MATRIX_4X4_MATH, def_fn_matrix_4x4_math, "MATRIX_4
DefNode(FunctionNode, FN_NODE_RANDOM_VALUE, def_fn_random_value, "RANDOM_VALUE", RandomValue, "Random Value", "")
DefNode(FunctionNode, FN_NODE_REPLACE_STRING, 0, "REPLACE_STRING", ReplaceString, "Replace String", "")
DefNode(FunctionNode, FN_NODE_ROTATE_EULER, def_fn_rotate_euler, "ROTATE_EULER", RotateEuler, "Rotate Euler", "")
DefNode(FunctionNode, FN_NODE_ROTATE_MATRIX_3X3, 0, "ROTATE_MATRIX_3X3", RotateMatrix3x3, "Rotate Matrix", "")
DefNode(FunctionNode, FN_NODE_SCALE_MATRIX_3X3, 0, "SCALE_MATRIX_3X3", ScaleMatrix3x3, "Scale Matrix", "")
DefNode(FunctionNode, FN_NODE_SEPARATE_COLOR, def_fn_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "")
DefNode(FunctionNode, FN_NODE_SEPARATE_MATRIX_3X3, def_fn_combsep_matrix, "SEPARATE_MATRIX_3X3", SeparateMatrix3x3, "Separate 3x3 Matrix", "")
DefNode(FunctionNode, FN_NODE_SEPARATE_MATRIX_4X4, def_fn_combsep_matrix, "SEPARATE_MATRIX_4X4", SeparateMatrix4x4, "Separate 4x4 Matrix", "")
DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, "SLICE_STRING", SliceString, "Slice String", "")
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
DefNode(FunctionNode, FN_NODE_TRANSLATE_MATRIX_4X4, 0, "TRANSLATE_MATRIX_4X4", TranslateMatrix4x4, "Translate Matrix", "")
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
DefNode(GeometryNode, GEO_NODE_ACCUMULATE_FIELD, def_geo_accumulate_field, "ACCUMULATE_FIELD", AccumulateField, "Accumulate Field", "Add the values of an evaluated field together and output the running total for each element")

View File

@ -24,6 +24,8 @@ set(SRC
nodes/node_fn_combine_matrix3x3.cc
nodes/node_fn_combine_matrix4x4.cc
nodes/node_fn_compare.cc
nodes/node_fn_decompose_matrix3x3.cc
nodes/node_fn_decompose_matrix4x4.cc
nodes/node_fn_float_to_int.cc
nodes/node_fn_input_bool.cc
nodes/node_fn_input_color.cc
@ -38,11 +40,14 @@ set(SRC
nodes/node_fn_random_value.cc
nodes/node_fn_replace_string.cc
nodes/node_fn_rotate_euler.cc
nodes/node_fn_rotate_matrix3x3.cc
nodes/node_fn_scale_matrix3x3.cc
nodes/node_fn_separate_color.cc
nodes/node_fn_separate_matrix3x3.cc
nodes/node_fn_separate_matrix4x4.cc
nodes/node_fn_slice_string.cc
nodes/node_fn_string_length.cc
nodes/node_fn_translate_matrix4x4.cc
nodes/node_fn_value_to_string.cc
node_function_register.cc

View File

@ -12,6 +12,8 @@ void register_function_nodes()
register_node_type_fn_combine_matrix_3x3();
register_node_type_fn_combine_matrix_4x4();
register_node_type_fn_compare();
register_node_type_fn_decompose_matrix_3x3();
register_node_type_fn_decompose_matrix_4x4();
register_node_type_fn_float_to_int();
register_node_type_fn_input_bool();
register_node_type_fn_input_color();
@ -26,10 +28,13 @@ void register_function_nodes()
register_node_type_fn_random_value();
register_node_type_fn_replace_string();
register_node_type_fn_rotate_euler();
register_node_type_fn_rotate_matrix_3x3();
register_node_type_fn_scale_matrix_3x3();
register_node_type_fn_separate_color();
register_node_type_fn_separate_matrix_3x3();
register_node_type_fn_separate_matrix_4x4();
register_node_type_fn_slice_string();
register_node_type_fn_string_length();
register_node_type_fn_translate_matrix_4x4();
register_node_type_fn_value_to_string();
}

View File

@ -8,6 +8,8 @@ void register_node_type_fn_combine_color();
void register_node_type_fn_combine_matrix_3x3();
void register_node_type_fn_combine_matrix_4x4();
void register_node_type_fn_compare();
void register_node_type_fn_decompose_matrix_3x3();
void register_node_type_fn_decompose_matrix_4x4();
void register_node_type_fn_float_to_int();
void register_node_type_fn_input_bool();
void register_node_type_fn_input_color();
@ -22,9 +24,12 @@ void register_node_type_fn_matrix_4x4_math();
void register_node_type_fn_random_value();
void register_node_type_fn_replace_string();
void register_node_type_fn_rotate_euler();
void register_node_type_fn_rotate_matrix_3x3();
void register_node_type_fn_scale_matrix_3x3();
void register_node_type_fn_separate_color();
void register_node_type_fn_separate_matrix_3x3();
void register_node_type_fn_separate_matrix_4x4();
void register_node_type_fn_slice_string();
void register_node_type_fn_string_length();
void register_node_type_fn_translate_matrix_4x4();
void register_node_type_fn_value_to_string();

View File

@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "BKE_node_runtime.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes::node_fn_decompose_matrix3x3_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Matrix3x3>(N_("Matrix"));
b.add_output<decl::Vector>(N_("Rotation"));
b.add_output<decl::Vector>(N_("Scale"));
};
class DecomposeMatrix3x3Function : public fn::MultiFunction {
public:
DecomposeMatrix3x3Function()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Decompose Matrix 3x3"};
signature.single_input<float3x3>("Matrix");
signature.single_output<float3>("Rotation");
signature.single_output<float3>("Scale");
return signature.build();
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float3x3> &matrices = params.readonly_single_input<float3x3>(0, "Matrix");
MutableSpan<float3> rotations = params.uninitialized_single_output<float3>(0, "Rotation");
MutableSpan<float3> scales = params.uninitialized_single_output<float3>(1, "Scale");
for (int64_t i : mask) {
const float3x3 &mat = matrices[i];
mat3_to_eul(rotations[i], mat.ptr());
mat3_to_size(scales[i], mat.ptr());
}
}
};
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static DecomposeMatrix3x3Function decompose_matrix_fn;
builder.set_matching_fn(&decompose_matrix_fn);
}
} // namespace blender::nodes::node_fn_decompose_matrix3x3_cc
void register_node_type_fn_decompose_matrix_3x3(void)
{
namespace file_ns = blender::nodes::node_fn_decompose_matrix3x3_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_DECOMPOSE_MATRIX_3X3, "Decompose 3x3 Matrix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.build_multi_function = file_ns::node_build_multi_function;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,74 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "BKE_node_runtime.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes::node_fn_decompose_matrix4x4_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Matrix4x4>(N_("Matrix"));
b.add_output<decl::Vector>(N_("Translation"));
b.add_output<decl::Vector>(N_("Rotation"));
b.add_output<decl::Vector>(N_("Scale"));
};
class DecomposeMatrix4x4Function : public fn::MultiFunction {
public:
DecomposeMatrix4x4Function()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Decompose Matrix 3x3"};
signature.single_input<float4x4>("Matrix");
signature.single_output<float3>("Translation");
signature.single_output<float3>("Rotation");
signature.single_output<float3>("Scale");
return signature.build();
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override
{
const VArray<float4x4> &matrices = params.readonly_single_input<float4x4>(0, "Matrix");
MutableSpan<float3> translations = params.uninitialized_single_output<float3>(0, "Translation");
MutableSpan<float3> rotations = params.uninitialized_single_output<float3>(0, "Rotation");
MutableSpan<float3> scales = params.uninitialized_single_output<float3>(1, "Scale");
for (int64_t i : mask) {
const float4x4 &mat = matrices[i];
copy_v3_v3(translations[i], mat[3]);
mat4_to_eul(rotations[i], mat.ptr());
mat4_to_size(scales[i], mat.ptr());
}
}
};
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static DecomposeMatrix4x4Function decompose_matrix_fn;
builder.set_matching_fn(&decompose_matrix_fn);
}
} // namespace blender::nodes::node_fn_decompose_matrix4x4_cc
void register_node_type_fn_decompose_matrix_4x4(void)
{
namespace file_ns = blender::nodes::node_fn_decompose_matrix4x4_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_DECOMPOSE_MATRIX_4X4, "Decompose 4x4 Matrix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.build_multi_function = file_ns::node_build_multi_function;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "BKE_node_runtime.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes::node_fn_rotate_matrix3x3_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Matrix3x3>(N_("Matrix"));
b.add_input<decl::Vector>(N_("Rotation"));
b.add_output<decl::Matrix3x3>(N_("Matrix"));
};
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static fn::CustomMF_SI_SI_SO<float3x3, float3, float3x3> rotate_matrix_fn{
"rotate_matrix", [](const float3x3 &mat, const float3 &rot) {
float3x3 rot_mat;
eulO_to_mat3(rot_mat.values, rot, EULER_ORDER_DEFAULT);
return rot_mat * mat;
}};
builder.set_matching_fn(&rotate_matrix_fn);
}
} // namespace blender::nodes::node_fn_rotate_matrix3x3_cc
void register_node_type_fn_rotate_matrix_3x3(void)
{
namespace file_ns = blender::nodes::node_fn_rotate_matrix3x3_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_ROTATE_MATRIX_3X3, "Rotate 3x3 Matrix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.build_multi_function = file_ns::node_build_multi_function;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "BKE_node_runtime.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes::node_fn_scale_matrix3x3_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Matrix3x3>(N_("Matrix"));
b.add_input<decl::Vector>(N_("Scale"));
b.add_output<decl::Matrix3x3>(N_("Matrix"));
};
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static fn::CustomMF_SI_SI_SO<float3x3, float3, float3x3> scale_matrix_fn{
"scale_matrix", [](const float3x3 &mat, const float3 &scale) {
float3x3 result;
mul_v3_v3fl(result.values[0], mat[0], scale[0]);
mul_v3_v3fl(result.values[1], mat[1], scale[1]);
mul_v3_v3fl(result.values[2], mat[2], scale[2]);
return result;
}};
builder.set_matching_fn(&scale_matrix_fn);
}
} // namespace blender::nodes::node_fn_scale_matrix3x3_cc
void register_node_type_fn_scale_matrix_3x3(void)
{
namespace file_ns = blender::nodes::node_fn_scale_matrix3x3_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_SCALE_MATRIX_3X3, "Scale 3x3 Matrix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.build_multi_function = file_ns::node_build_multi_function;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,42 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "BKE_node_runtime.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes::node_fn_translate_matrix4x4_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Matrix4x4>(N_("Matrix"));
b.add_input<decl::Vector>(N_("Translation"));
b.add_output<decl::Matrix4x4>(N_("Matrix"));
};
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
static fn::CustomMF_SI_SI_SO<float4x4, float3, float4x4> translate_matrix_fn{
"translate_matrix", [](const float4x4 &mat, const float3 &vec) {
return float4x4::from_location(vec) * mat;
}};
builder.set_matching_fn(&translate_matrix_fn);
}
} // namespace blender::nodes::node_fn_translate_matrix4x4_cc
void register_node_type_fn_translate_matrix_4x4(void)
{
namespace file_ns = blender::nodes::node_fn_translate_matrix4x4_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_TRANSLATE_MATRIX_4X4, "Translate 4x4 Matrix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.build_multi_function = file_ns::node_build_multi_function;
nodeRegisterType(&ntype);
}