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.
17 changed files with 747 additions and 189 deletions
Showing only changes of commit 9c01a58ceb - Show all commits

View File

@ -143,12 +143,13 @@ class NODE_MT_geometry_node_GEO_INPUT(Menu):
node_add_menu.add_node_type(layout, "FunctionNodeInputInt")
node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")
node_add_menu.add_node_type(layout, "GeometryNodeInputMaterial")
node_add_menu.add_node_type(layout, "FunctionNodeInputMatrix3x3")
node_add_menu.add_node_type(layout, "FunctionNodeInputMatrix4x4")
node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo")
node_add_menu.add_node_type(layout, "GeometryNodeSelfObject")
node_add_menu.add_node_type(layout, "FunctionNodeInputString")
node_add_menu.add_node_type(layout, "ShaderNodeValue")
node_add_menu.add_node_type(layout, "FunctionNodeInputVector")
node_add_menu.add_node_type(layout, "FunctionNodeInputMatrix4x4")
layout.separator()
node_add_menu.add_node_type(layout, "GeometryNodeInputID")
node_add_menu.add_node_type(layout, "GeometryNodeInputIndex")
@ -200,8 +201,11 @@ class NODE_MT_category_GEO_MATRIX(Menu):
def draw(self, _context):
layout = self.layout
node_add_menu.add_node_type(layout, "FunctionNodeCombineMatrix3x3")
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, "FunctionNodeMatrix3x3Math")
node_add_menu.add_node_type(layout, "FunctionNodeMatrix4x4Math")
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)

View File

@ -1567,10 +1567,14 @@ struct TexResult;
#define FN_NODE_INPUT_INT 1220
#define FN_NODE_SEPARATE_COLOR 1221
#define FN_NODE_COMBINE_COLOR 1222
#define FN_NODE_INPUT_MATRIX_4X4 1223
#define FN_NODE_SEPARATE_MATRIX_4X4 1224
#define FN_NODE_COMBINE_MATRIX_4X4 1225
#define FN_NODE_MATRIX_4X4_MATH 1226
#define FN_NODE_INPUT_MATRIX_3X3 1223
#define FN_NODE_INPUT_MATRIX_4X4 1224
#define FN_NODE_SEPARATE_MATRIX_3X3 1225
#define FN_NODE_SEPARATE_MATRIX_4X4 1226
#define FN_NODE_COMBINE_MATRIX_3X3 1227
#define FN_NODE_COMBINE_MATRIX_4X4 1228
#define FN_NODE_MATRIX_3X3_MATH 1229
#define FN_NODE_MATRIX_4X4_MATH 1230
/** \} */

View File

@ -1599,13 +1599,13 @@ typedef struct NodeShaderMix {
char _pad[3];
} NodeShaderMix;
typedef struct NodeInputMatrix {
float vec0[3];
float vec1[3];
float vec2[3];
float vec3[3];
float elements[4][4];
} NodeInputMatrix;
typedef struct NodeInputMatrix3x3 {
float matrix[3][3];
} NodeInputMatrix3x3;
typedef struct NodeInputMatrix4x4 {
float matrix[4][4];
} NodeInputMatrix4x4;
/* script node mode */
#define NODE_SCRIPT_INTERNAL 0

View File

@ -5209,12 +5209,33 @@ static void def_fn_combsep_color(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_fn_input_matrix_3x3(StructRNA *srna)
{
static const float default_elements[] = {
1.0f,
0.0f,
0.0f,
0.0f,
1.0f,
0.0f,
0.0f,
0.0f,
1.0f,
};
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeInputMatrix3x3", "storage");
prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "matrix");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_3x3);
RNA_def_property_float_array_default(prop, default_elements);
RNA_def_property_ui_text(prop, "Matrix", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_fn_input_matrix_4x4(StructRNA *srna)
{
static const float default_vec0[] = {1.0f, 0.0f, 0.0f};
static const float default_vec1[] = {0.0f, 1.0f, 0.0f};
static const float default_vec2[] = {0.0f, 0.0f, 1.0f};
static const float default_vec3[] = {0.0f, 0.0f, 0.0f};
static const float default_elements[] = {
1.0f,
0.0f,
@ -5235,48 +5256,13 @@ static void def_fn_input_matrix_4x4(StructRNA *srna)
};
PropertyRNA *prop;
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_node_combsep_matrix_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of matrix composition");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
RNA_def_struct_sdna_from(srna, "NodeInputInt", "storage");
RNA_def_struct_sdna_from(srna, "NodeInputMatrix4x4", "storage");
RNA_def_struct_sdna_from(srna, "NodeInputMatrix", "storage");
prop = RNA_def_property(srna, "vec0", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vec0");
RNA_def_property_array(prop, 3);
RNA_def_property_float_array_default(prop, default_vec0);
RNA_def_property_ui_text(prop, "Vector 0", "Row or column vector");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "vec1", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vec1");
RNA_def_property_array(prop, 3);
RNA_def_property_float_array_default(prop, default_vec1);
RNA_def_property_ui_text(prop, "Vector 1", "Row or column vector");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "vec2", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vec2");
RNA_def_property_array(prop, 3);
RNA_def_property_float_array_default(prop, default_vec2);
RNA_def_property_ui_text(prop, "Vector 2", "Row or column vector");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "vec3", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "vec3");
RNA_def_property_array(prop, 3);
RNA_def_property_float_array_default(prop, default_vec3);
RNA_def_property_ui_text(prop, "Vector 3", "Row or column vector");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "elements", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "elements");
RNA_def_property_array(prop, 16);
prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "matrix");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_float_array_default(prop, default_elements);
RNA_def_property_ui_text(prop, "Integer", "Input value used for unconnected socket");
RNA_def_property_ui_text(prop, "Matrix", "Input value used for unconnected socket");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
@ -5291,6 +5277,17 @@ static void def_fn_combsep_matrix(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_fn_matrix_3x3_math(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_enum_node_matrix_math_items);
RNA_def_property_ui_text(prop, "Operation", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_fn_matrix_4x4_math(StructRNA *srna)
{
PropertyRNA *prop;
@ -5299,7 +5296,7 @@ static void def_fn_matrix_4x4_math(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_enum_node_matrix_math_items);
RNA_def_property_ui_text(prop, "Operation", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
/* -- Shader Nodes ---------------------------------------------------------- */

View File

@ -264,25 +264,29 @@ DefNode(TextureNode, TEX_NODE_PROC+TEX_DISTNOISE, 0, "TEX_DI
DefNode(FunctionNode, FN_NODE_ALIGN_EULER_TO_VECTOR, def_fn_align_euler_to_vector, "ALIGN_EULER_TO_VECTOR", AlignEulerToVector, "Align Euler to Vector", "")
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
DefNode(FunctionNode, FN_NODE_COMBINE_COLOR, def_fn_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "")
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_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", "")
DefNode(FunctionNode, FN_NODE_INPUT_INT, def_fn_input_int, "INPUT_INT", InputInt, "Integer", "")
DefNode(FunctionNode, FN_NODE_INPUT_MATRIX_3X3, def_fn_input_matrix_3x3, "INPUT_MATRIX_3X3", InputMatrix3x3, "3x3 Matrix", "")
DefNode(FunctionNode, FN_NODE_INPUT_MATRIX_4X4, def_fn_input_matrix_4x4, "INPUT_MATRIX_4X4", InputMatrix4x4, "4x4 Matrix", "")
DefNode(FunctionNode, FN_NODE_INPUT_SPECIAL_CHARACTERS, 0, "INPUT_SPECIAL_CHARACTERS", InputSpecialCharacters, "Special Characters", "")
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_MATRIX_3X3_MATH, def_fn_matrix_3x3_math, "MATRIX_3X3_MATH", Matrix3x3Math, "3x3 Matrix Math", "")
DefNode(FunctionNode, FN_NODE_MATRIX_4X4_MATH, def_fn_matrix_4x4_math, "MATRIX_4X4_MATH", Matrix4x4Math, "4x4 Matrix Math", "")
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_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_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")
DefNode(FunctionNode, FN_NODE_INPUT_MATRIX_4X4, def_fn_input_matrix_4x4, "INPUT_MATRIX_4X4", InputMatrix4x4, "4x4 Matrix", "")
DefNode(FunctionNode, FN_NODE_SEPARATE_MATRIX_4X4, def_fn_combsep_matrix, "SEPARATE_MATRIX_4X4", SeparateMatrix4x4, "Separate 4x4 Matrix", "")
DefNode(FunctionNode, FN_NODE_COMBINE_MATRIX_4X4, def_fn_combsep_matrix, "COMBINE_MATRIX_4X4", CombineMatrix4x4, "Combine 4x4 Matrix", "")
DefNode(FunctionNode, FN_NODE_MATRIX_4X4_MATH, def_fn_matrix_4x4_math, "MATRIX_4X4_MATH", Matrix4x4Math, "4x4 Matrix Math", "")
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")
DefNode(GeometryNode, GEO_NODE_ATTRIBUTE_DOMAIN_SIZE, def_geo_attribute_domain_size, "ATTRIBUTE_DOMAIN_SIZE", AttributeDomainSize, "Domain Size", "Retrieve the number of elements in a geometry for each attribute domain")

View File

@ -21,22 +21,26 @@ set(SRC
nodes/node_fn_align_euler_to_vector.cc
nodes/node_fn_boolean_math.cc
nodes/node_fn_combine_color.cc
nodes/node_fn_combine_matrix.cc
nodes/node_fn_combine_matrix3x3.cc
nodes/node_fn_combine_matrix4x4.cc
nodes/node_fn_compare.cc
nodes/node_fn_float_to_int.cc
nodes/node_fn_input_bool.cc
nodes/node_fn_input_color.cc
nodes/node_fn_input_int.cc
nodes/node_fn_input_matrix.cc
nodes/node_fn_input_matrix3x3.cc
nodes/node_fn_input_matrix4x4.cc
nodes/node_fn_input_special_characters.cc
nodes/node_fn_input_string.cc
nodes/node_fn_input_vector.cc
nodes/node_fn_matrix_math.cc
nodes/node_fn_matrix3x3_math.cc
nodes/node_fn_matrix4x4_math.cc
nodes/node_fn_random_value.cc
nodes/node_fn_replace_string.cc
nodes/node_fn_rotate_euler.cc
nodes/node_fn_separate_color.cc
nodes/node_fn_separate_matrix.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_value_to_string.cc

View File

@ -9,21 +9,25 @@ void register_function_nodes()
register_node_type_fn_align_euler_to_vector();
register_node_type_fn_boolean_math();
register_node_type_fn_combine_color();
register_node_type_fn_combine_matrix_3x3();
register_node_type_fn_combine_matrix_4x4();
register_node_type_fn_compare();
register_node_type_fn_float_to_int();
register_node_type_fn_input_bool();
register_node_type_fn_input_color();
register_node_type_fn_input_int();
register_node_type_fn_input_matrix_3x3();
register_node_type_fn_input_matrix_4x4();
register_node_type_fn_input_special_characters();
register_node_type_fn_input_string();
register_node_type_fn_input_vector();
register_node_type_fn_matrix_3x3_math();
register_node_type_fn_matrix_4x4_math();
register_node_type_fn_random_value();
register_node_type_fn_replace_string();
register_node_type_fn_rotate_euler();
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();

View File

@ -5,21 +5,25 @@
void register_node_type_fn_align_euler_to_vector();
void register_node_type_fn_boolean_math();
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_float_to_int();
void register_node_type_fn_input_bool();
void register_node_type_fn_input_color();
void register_node_type_fn_input_int();
void register_node_type_fn_input_matrix_3x3();
void register_node_type_fn_input_matrix_4x4();
void register_node_type_fn_input_special_characters();
void register_node_type_fn_input_string();
void register_node_type_fn_input_vector();
void register_node_type_fn_matrix_3x3_math();
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_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();

View File

@ -0,0 +1,167 @@
/* 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_combine_matrix3x3_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Vector>(N_("Vec0")).default_value({1.0f, 0.0f, 0.0f});
b.add_input<decl::Vector>(N_("Vec1")).default_value({0.0f, 1.0f, 0.0f});
b.add_input<decl::Vector>(N_("Vec2")).default_value({0.0f, 0.0f, 1.0f});
b.add_input<decl::Float>(N_("Row 0 Col 0")).default_value(1.0f);
b.add_input<decl::Float>(N_("Row 1 Col 0")).default_value(0.0f);
b.add_input<decl::Float>(N_("Row 2 Col 0")).default_value(0.0f);
b.add_input<decl::Float>(N_("Row 0 Col 1")).default_value(0.0f);
b.add_input<decl::Float>(N_("Row 1 Col 1")).default_value(1.0f);
b.add_input<decl::Float>(N_("Row 2 Col 1")).default_value(0.0f);
b.add_input<decl::Float>(N_("Row 0 Col 2")).default_value(0.0f);
b.add_input<decl::Float>(N_("Row 1 Col 2")).default_value(0.0f);
b.add_input<decl::Float>(N_("Row 2 Col 2")).default_value(1.0f);
b.add_output<decl::Matrix3x3>(N_("Matrix"));
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
static void node_update(bNodeTree *tree, bNode *node)
{
const NodeCombSepMatrixMode mode = (NodeCombSepMatrixMode)node->custom1;
const IndexRange vector_sockets(0, 4);
const IndexRange scalar_sockets(3, 9);
const bool show_vector_sockets = ELEM(
mode, NODE_COMBSEP_MATRIX_COLUMNS, NODE_COMBSEP_MATRIX_ROWS);
const bool show_scalar_sockets = ELEM(mode, NODE_COMBSEP_MATRIX_ELEMENTS);
for (const int i : vector_sockets) {
nodeSetSocketAvailability(
tree, (bNodeSocket *)BLI_findlink(&node->inputs, i), show_vector_sockets);
}
for (const int i : scalar_sockets) {
nodeSetSocketAvailability(
tree, (bNodeSocket *)BLI_findlink(&node->inputs, i), show_scalar_sockets);
}
switch (mode) {
case NODE_COMBSEP_MATRIX_COLUMNS:
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[0]), "Column 0");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[1]), "Column 1");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[2]), "Column 2");
break;
case NODE_COMBSEP_MATRIX_ROWS:
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[0]), "Row 0");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[1]), "Row 1");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[2]), "Row 2");
break;
case NODE_COMBSEP_MATRIX_ELEMENTS:
break;
}
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = NODE_COMBSEP_MATRIX_COLUMNS;
}
static const fn::MultiFunction *get_multi_function(const bNode &bnode)
{
const NodeCombSepMatrixMode mode = (NodeCombSepMatrixMode)bnode.custom1;
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3x3>
columns_to_matrix_fn{
"columns_to_matrix",
[](const float3 &c0, const float3 &c1, const float3 &c2) {
float4x4 m;
copy_v3_v3(m[0], c0);
copy_v3_v3(m[1], c1);
copy_v3_v3(m[2], c2);
return m;
}};
static fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3x3> rows_to_matrix_fn{
"rows_to_matrix",
[](const float3 &r0, const float3 &r1, const float3 &r2) {
float4x4 m;
m[0][0] = r0[0];
m[0][1] = r1[0];
m[0][2] = r2[0];
m[1][0] = r0[1];
m[1][1] = r1[1];
m[1][2] = r2[1];
m[2][0] = r0[2];
m[2][1] = r1[2];
m[2][2] = r2[2];
return m;
}};
using Element = fn::MFParamTag<fn::MFParamCategory::SingleInput, float>;
using Matrix = fn::MFParamTag<fn::MFParamCategory::SingleOutput, float3x3>;
static fn::CustomMF<Element,
Element,
Element,
Element,
Element,
Element,
Element,
Element,
Element,
Matrix>
elements_to_matrix_fn{
"elements_to_matrix",
[](float m00,
float m01,
float m02,
float m10,
float m11,
float m12,
float m20,
float m21,
float m22,
float3x3 *result) {
const float elements[] = {m00, m01, m02, m10, m11, m12, m20, m21, m22};
*result = float3x3(elements);
}};
switch (mode) {
case NODE_COMBSEP_MATRIX_COLUMNS:
return &columns_to_matrix_fn;
case NODE_COMBSEP_MATRIX_ROWS:
return &rows_to_matrix_fn;
case NODE_COMBSEP_MATRIX_ELEMENTS:
return &elements_to_matrix_fn;
}
BLI_assert_unreachable();
return nullptr;
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}
} // namespace blender::nodes::node_fn_combine_matrix3x3_cc
void register_node_type_fn_combine_matrix_3x3(void)
{
namespace file_ns = blender::nodes::node_fn_combine_matrix3x3_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_COMBINE_MATRIX_3X3, "Combine 3x3 Matrix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.updatefunc = file_ns::node_update;
ntype.initfunc = file_ns::node_init;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -108,18 +108,18 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode)
m[0][0] = r0[0];
m[0][1] = r1[0];
m[0][2] = r2[0];
m[0][3] = 0.0f;
m[0][3] = r3[0];
m[1][0] = r0[1];
m[1][1] = r1[1];
m[1][2] = r2[1];
m[1][3] = 0.0f;
m[1][3] = r3[1];
m[2][0] = r0[2];
m[2][1] = r1[2];
m[2][2] = r2[2];
m[2][3] = 0.0f;
m[3][0] = r0[3];
m[3][1] = r1[3];
m[3][2] = r2[3];
m[2][3] = r3[2];
m[3][0] = 0.0f;
m[3][1] = 0.0f;
m[3][2] = 0.0f;
m[3][3] = 1.0f;
return m;
}};

View File

@ -1,114 +0,0 @@
/* 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_input_matrix4x4_cc {
NODE_STORAGE_FUNCS(NodeInputMatrix);
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Matrix4x4>(N_("Matrix"));
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
const bNode *node = (const bNode *)ptr->data;
const NodeCombSepMatrixMode mode = (NodeCombSepMatrixMode)node->custom1;
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
switch (mode) {
case NODE_COMBSEP_MATRIX_COLUMNS:
uiItemR(layout, ptr, "vec0", 0, "Column 0", ICON_NONE);
uiItemR(layout, ptr, "vec1", 0, "Column 1", ICON_NONE);
uiItemR(layout, ptr, "vec2", 0, "Column 2", ICON_NONE);
uiItemR(layout, ptr, "vec3", 0, "Column 3", ICON_NONE);
break;
case NODE_COMBSEP_MATRIX_ROWS:
uiItemR(layout, ptr, "vec0", 0, "Row 0", ICON_NONE);
uiItemR(layout, ptr, "vec1", 0, "Row 1", ICON_NONE);
uiItemR(layout, ptr, "vec2", 0, "Row 2", ICON_NONE);
uiItemR(layout, ptr, "vec3", 0, "Row 3", ICON_NONE);
break;
case NODE_COMBSEP_MATRIX_ELEMENTS:
uiItemR(layout, ptr, "elements", 0, "", ICON_NONE);
break;
}
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = NODE_COMBSEP_MATRIX_COLUMNS;
NodeInputMatrix *data = MEM_new<NodeInputMatrix>(__func__);
copy_v3_v3(data->vec0, float3(1.0f, 0.0f, 0.0f));
copy_v3_v3(data->vec1, float3(0.0f, 1.0f, 0.0f));
copy_v3_v3(data->vec2, float3(0.0f, 0.0f, 1.0f));
copy_v3_v3(data->vec3, float3(0.0f, 0.0f, 0.0f));
unit_m4(data->elements);
node->storage = data;
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeInputMatrix &storage = node_storage(builder.node());
const NodeCombSepMatrixMode mode = (NodeCombSepMatrixMode)builder.node().custom1;
float4x4 matrix;
switch (mode) {
case NODE_COMBSEP_MATRIX_COLUMNS:
copy_v3_v3(matrix[0], storage.vec0);
matrix[0][3] = 0.0f;
copy_v3_v3(matrix[1], storage.vec1);
matrix[1][3] = 0.0f;
copy_v3_v3(matrix[2], storage.vec2);
matrix[2][3] = 0.0f;
copy_v3_v3(matrix[3], storage.vec3);
matrix[3][3] = 1.0f;
break;
case NODE_COMBSEP_MATRIX_ROWS:
matrix[0][0] = storage.vec0[0];
matrix[0][1] = storage.vec1[0];
matrix[0][2] = storage.vec2[0];
matrix[0][3] = storage.vec3[0];
matrix[1][0] = storage.vec0[1];
matrix[1][1] = storage.vec1[1];
matrix[1][2] = storage.vec2[1];
matrix[1][3] = storage.vec3[1];
matrix[2][0] = storage.vec0[2];
matrix[2][1] = storage.vec1[2];
matrix[2][2] = storage.vec2[2];
matrix[2][3] = storage.vec3[2];
matrix[3][0] = 0.0f;
matrix[3][1] = 0.0f;
matrix[3][2] = 0.0f;
matrix[3][3] = 1.0f;
break;
case NODE_COMBSEP_MATRIX_ELEMENTS:
matrix = float4x4(storage.elements);
break;
}
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<float4x4>>(matrix);
}
} // namespace blender::nodes::node_fn_input_matrix4x4_cc
void register_node_type_fn_input_matrix_4x4(void)
{
namespace file_ns = blender::nodes::node_fn_input_matrix4x4_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_INPUT_MATRIX_4X4, "4x4 Matrix", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.initfunc = file_ns::node_init;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,52 @@
/* 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_input_matrix3x3_cc {
NODE_STORAGE_FUNCS(NodeInputMatrix3x3);
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Matrix4x4>(N_("Matrix"));
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "matrix", 0, "", ICON_NONE);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeInputMatrix3x3 *data = MEM_new<NodeInputMatrix3x3>(__func__);
unit_m3(data->matrix);
node->storage = data;
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeInputMatrix3x3 &storage = node_storage(builder.node());
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<float3x3>>(float3x3{storage.matrix});
}
} // namespace blender::nodes::node_fn_input_matrix3x3_cc
void register_node_type_fn_input_matrix_3x3(void)
{
namespace file_ns = blender::nodes::node_fn_input_matrix3x3_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_INPUT_MATRIX_3X3, "3x3 Matrix", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.initfunc = file_ns::node_init;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,52 @@
/* 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_input_matrix4x4_cc {
NODE_STORAGE_FUNCS(NodeInputMatrix4x4);
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_output<decl::Matrix4x4>(N_("Matrix"));
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "matrix", 0, "", ICON_NONE);
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
NodeInputMatrix4x4 *data = MEM_new<NodeInputMatrix4x4>(__func__);
unit_m4(data->matrix);
node->storage = data;
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeInputMatrix4x4 &storage = node_storage(builder.node());
builder.construct_and_set_matching_fn<fn::CustomMF_Constant<float4x4>>(float4x4{storage.matrix});
}
} // namespace blender::nodes::node_fn_input_matrix4x4_cc
void register_node_type_fn_input_matrix_4x4(void)
{
namespace file_ns = blender::nodes::node_fn_input_matrix4x4_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_INPUT_MATRIX_4X4, "4x4 Matrix", NODE_CLASS_INPUT);
ntype.declare = file_ns::node_declare;
ntype.initfunc = file_ns::node_init;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,134 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "BKE_node_runtime.hh"
#include "NOD_socket_search_link.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::math {
/* XXX These are placeholder functions based on BLI math until SIMD versions are available */
inline float3x3 [[nodiscard]] add(const float3x3 &a, const float3x3 &b)
{
float3x3 r;
add_m3_m3m3(r.ptr(), a.ptr(), b.ptr());
return r;
}
inline float3x3 [[nodiscard]] subtract(const float3x3 &a, const float3x3 &b)
{
float3x3 r;
sub_m3_m3m3(r.ptr(), a.ptr(), b.ptr());
return r;
}
}
namespace blender::nodes::node_fn_matrix3x3_math_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Matrix4x4>(N_("Matrix"));
b.add_input<decl::Matrix4x4>(N_("Matrix"), "Matrix_001");
b.add_input<decl::Float>(N_("Scale")).default_value(1.0f);
b.add_output<decl::Matrix4x4>(N_("Matrix"));
b.add_output<decl::Float>(N_("Value"));
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "operation", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
static void node_update(bNodeTree *tree, bNode *node)
{
const NodeMatrixMathOperation op = (NodeMatrixMathOperation)node->custom1;
bNodeSocket *in_matrix_a = (bNodeSocket *)BLI_findlink(&node->inputs, 0);
bNodeSocket *in_matrix_b = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
bNodeSocket *in_scale = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
bNodeSocket *out_matrix = (bNodeSocket *)BLI_findlink(&node->inputs, 3);
bNodeSocket *out_value = (bNodeSocket *)BLI_findlink(&node->inputs, 4);
nodeSetSocketAvailability(tree, in_matrix_a, true);
nodeSetSocketAvailability(
tree,
in_matrix_b,
ELEM(op, NODE_MATRIX_MATH_ADD, NODE_MATRIX_MATH_SUBTRACT, NODE_MATRIX_MATH_MULTIPLY));
nodeSetSocketAvailability(tree, in_scale, ELEM(op, NODE_MATRIX_MATH_SCALAR_MULTIPLY));
nodeSetSocketAvailability(tree,
out_matrix,
ELEM(op,
NODE_MATRIX_MATH_ADD,
NODE_MATRIX_MATH_SUBTRACT,
NODE_MATRIX_MATH_SCALAR_MULTIPLY,
NODE_MATRIX_MATH_MULTIPLY,
NODE_MATRIX_MATH_TRANSPOSE,
NODE_MATRIX_MATH_INVERSE));
nodeSetSocketAvailability(
tree, out_value, ELEM(op, NODE_MATRIX_MATH_DETERMINANT, NODE_MATRIX_MATH_TRACE));
/* Labels */
node_sock_label_clear(in_matrix_a);
node_sock_label_clear(in_matrix_b);
node_sock_label_clear(in_scale);
switch (op) {
}
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = NODE_MATRIX_MATH_ADD;
}
static const fn::MultiFunction *get_multi_function(NodeMatrixMathOperation op)
{
static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle();
static auto exec_preset_slow = fn::CustomMF_presets::Materialized();
const fn::MultiFunction *multi_fn = nullptr;
switch (op) {
case NODE_MATRIX_MATH_ADD: {
static fn::CustomMF_SI_SI_SO<float3x3, float3x3, float3x3> fn{
"add",
[](const float3x3 &a, const float3x3 &b) -> float3x3 { return math::add(a, b); },
exec_preset_fast};
return &fn;
}
}
return nullptr;
}
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeMatrixMathOperation op = (NodeMatrixMathOperation)builder.node().custom1;
const fn::MultiFunction *fn = get_multi_function(op);
builder.set_matching_fn(fn);
}
} // namespace blender::nodes::node_fn_matrix3x3_math_cc
void register_node_type_fn_matrix_3x3_math(void)
{
namespace file_ns = blender::nodes::node_fn_matrix3x3_math_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_MATRIX_3X3_MATH, "3x3 Matrix Math", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.updatefunc = file_ns::node_update;
ntype.initfunc = file_ns::node_init;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -93,8 +93,6 @@ static const fn::MultiFunction *get_multi_function(NodeMatrixMathOperation op)
static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle();
static auto exec_preset_slow = fn::CustomMF_presets::Materialized();
const fn::MultiFunction *multi_fn = nullptr;
switch (op) {
case NODE_MATRIX_MATH_ADD: {
static fn::CustomMF_SI_SI_SO<float4x4, float4x4, float4x4> fn{

View File

@ -0,0 +1,246 @@
/* 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_separate_matrix3x3_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Matrix4x4>(N_("Matrix")).default_value(float4x4::identity());
b.add_output<decl::Vector>(N_("Vec0"));
b.add_output<decl::Vector>(N_("Vec1"));
b.add_output<decl::Vector>(N_("Vec2"));
b.add_output<decl::Vector>(N_("Vec3"));
b.add_output<decl::Float>(N_("Row 0 Col 0"));
b.add_output<decl::Float>(N_("Row 1 Col 0"));
b.add_output<decl::Float>(N_("Row 2 Col 0"));
b.add_output<decl::Float>(N_("Row 3 Col 0"));
b.add_output<decl::Float>(N_("Row 0 Col 1"));
b.add_output<decl::Float>(N_("Row 1 Col 1"));
b.add_output<decl::Float>(N_("Row 2 Col 1"));
b.add_output<decl::Float>(N_("Row 3 Col 1"));
b.add_output<decl::Float>(N_("Row 0 Col 2"));
b.add_output<decl::Float>(N_("Row 1 Col 2"));
b.add_output<decl::Float>(N_("Row 2 Col 2"));
b.add_output<decl::Float>(N_("Row 3 Col 2"));
b.add_output<decl::Float>(N_("Row 0 Col 3"));
b.add_output<decl::Float>(N_("Row 1 Col 3"));
b.add_output<decl::Float>(N_("Row 2 Col 3"));
b.add_output<decl::Float>(N_("Row 3 Col 3"));
};
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
static void node_update(bNodeTree *tree, bNode *node)
{
const NodeCombSepMatrixMode mode = (NodeCombSepMatrixMode)node->custom1;
const IndexRange vector_sockets(0, 3);
const IndexRange scalar_sockets(3, 9);
const bool show_vector_sockets = ELEM(
mode, NODE_COMBSEP_MATRIX_COLUMNS, NODE_COMBSEP_MATRIX_ROWS);
const bool show_scalar_sockets = ELEM(mode, NODE_COMBSEP_MATRIX_ELEMENTS);
for (const int i : vector_sockets) {
nodeSetSocketAvailability(
tree, (bNodeSocket *)BLI_findlink(&node->outputs, i), show_vector_sockets);
}
for (const int i : scalar_sockets) {
nodeSetSocketAvailability(
tree, (bNodeSocket *)BLI_findlink(&node->outputs, i), show_scalar_sockets);
}
switch (mode) {
case NODE_COMBSEP_MATRIX_COLUMNS:
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[0]), "Column 0");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[1]), "Column 1");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[2]), "Column 2");
break;
case NODE_COMBSEP_MATRIX_ROWS:
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[0]), "Row 0");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[1]), "Row 1");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[2]), "Row 2");
break;
case NODE_COMBSEP_MATRIX_ELEMENTS:
break;
}
}
static void node_init(bNodeTree * /*tree*/, bNode *node)
{
node->custom1 = NODE_COMBSEP_MATRIX_COLUMNS;
}
class SeparateColumnsFunction : public fn::MultiFunction {
public:
SeparateColumnsFunction()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Separate Matrix 3x3"};
signature.single_input<float3x3>("Matrix");
signature.single_output<float3>("Column0");
signature.single_output<float3>("Column1");
signature.single_output<float3>("Column2");
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> col0 = params.uninitialized_single_output<float3>(1, "Column0");
MutableSpan<float3> col1 = params.uninitialized_single_output<float3>(2, "Column1");
MutableSpan<float3> col2 = params.uninitialized_single_output<float3>(3, "Column2");
for (int64_t i : mask) {
const float3x3 &mat = matrices[i];
col0[i] = float3(mat[0]);
col1[i] = float3(mat[1]);
col2[i] = float3(mat[2]);
}
}
};
class SeparateRowsFunction : public fn::MultiFunction {
public:
SeparateRowsFunction()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Separate Matrix 3x3"};
signature.single_input<float3x3>("Matrix");
signature.single_output<float3>("Row0");
signature.single_output<float3>("Row1");
signature.single_output<float3>("Row2");
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> row0 = params.uninitialized_single_output<float3>(1, "Row0");
MutableSpan<float3> row1 = params.uninitialized_single_output<float3>(2, "Row1");
MutableSpan<float3> row2 = params.uninitialized_single_output<float3>(3, "Row2");
for (int64_t i : mask) {
const float3x3 &mat = matrices[i];
row0[i] = float3(mat[0][0], mat[1][0], mat[2][0]);
row1[i] = float3(mat[0][1], mat[1][1], mat[2][1]);
row2[i] = float3(mat[0][2], mat[1][2], mat[2][2]);
}
}
};
class SeparateElementsFunction : public fn::MultiFunction {
public:
SeparateElementsFunction()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Separate Matrix 3x3"};
signature.single_input<float3x3>("Matrix");
signature.single_output<float>("Row0Column0");
signature.single_output<float>("Row0Column1");
signature.single_output<float>("Row0Column2");
signature.single_output<float>("Row1Column0");
signature.single_output<float>("Row1Column1");
signature.single_output<float>("Row1Column2");
signature.single_output<float>("Row2Column0");
signature.single_output<float>("Row2Column1");
signature.single_output<float>("Row2Column2");
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<float> m00 = params.uninitialized_single_output<float>(0, "Row0Column0");
MutableSpan<float> m10 = params.uninitialized_single_output<float>(1, "Row0Column1");
MutableSpan<float> m20 = params.uninitialized_single_output<float>(2, "Row0Column2");
MutableSpan<float> m01 = params.uninitialized_single_output<float>(3, "Row1Column0");
MutableSpan<float> m11 = params.uninitialized_single_output<float>(4, "Row1Column1");
MutableSpan<float> m21 = params.uninitialized_single_output<float>(5, "Row1Column2");
MutableSpan<float> m02 = params.uninitialized_single_output<float>(6, "Row2Column0");
MutableSpan<float> m12 = params.uninitialized_single_output<float>(7, "Row2Column1");
MutableSpan<float> m22 = params.uninitialized_single_output<float>(8, "Row2Column2");
for (int64_t i : mask) {
const float3x3 &mat = matrices[i];
m00[i] = mat[0][0];
m01[i] = mat[0][1];
m02[i] = mat[0][2];
m10[i] = mat[1][0];
m11[i] = mat[1][1];
m12[i] = mat[1][2];
m20[i] = mat[2][0];
m21[i] = mat[2][1];
m22[i] = mat[2][2];
}
}
};
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeCombSepMatrixMode mode = (NodeCombSepMatrixMode)builder.node().custom1;
switch (mode) {
case NODE_COMBSEP_MATRIX_COLUMNS: {
static SeparateColumnsFunction fn;
builder.set_matching_fn(fn);
break;
}
case NODE_COMBSEP_MATRIX_ROWS: {
static SeparateRowsFunction fn;
builder.set_matching_fn(fn);
break;
}
case NODE_COMBSEP_MATRIX_ELEMENTS: {
static SeparateElementsFunction fn;
builder.set_matching_fn(fn);
break;
}
default: {
BLI_assert_unreachable();
break;
}
}
}
} // namespace blender::nodes::node_fn_separate_matrix3x3_cc
void register_node_type_fn_separate_matrix_3x3(void)
{
namespace file_ns = blender::nodes::node_fn_separate_matrix3x3_cc;
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_SEPARATE_MATRIX_3X3, "Separate 3x3 Matrix", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare;
ntype.updatefunc = file_ns::node_update;
ntype.initfunc = file_ns::node_init;
ntype.build_multi_function = file_ns::node_build_multi_function;
ntype.draw_buttons = file_ns::node_layout;
nodeRegisterType(&ntype);
}

View File

@ -51,10 +51,12 @@ static void node_update(bNodeTree *tree, bNode *node)
const bool show_scalar_sockets = ELEM(mode, NODE_COMBSEP_MATRIX_ELEMENTS);
for (const int i : vector_sockets) {
nodeSetSocketAvailability(tree, &node->output_socket(i), show_vector_sockets);
nodeSetSocketAvailability(
tree, (bNodeSocket *)BLI_findlink(&node->outputs, i), show_vector_sockets);
}
for (const int i : scalar_sockets) {
nodeSetSocketAvailability(tree, &node->output_socket(i), show_scalar_sockets);
nodeSetSocketAvailability(
tree, (bNodeSocket *)BLI_findlink(&node->outputs, i), show_scalar_sockets);
}
switch (mode) {