Blender V4.3
node_fn_combine_matrix.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_matrix.hh"
6
9
10#include "node_function_util.hh"
11
13
15{
16 b.is_function_node();
17 b.use_custom_socket_order();
18
19 b.add_output<decl::Matrix>("Matrix");
20
21 PanelDeclarationBuilder &column_a = b.add_panel("Column 1").default_closed(true);
22 column_a.add_input<decl::Float>("Column 1 Row 1").default_value(1.0f);
23 column_a.add_input<decl::Float>("Column 1 Row 2");
24 column_a.add_input<decl::Float>("Column 1 Row 3");
25 column_a.add_input<decl::Float>("Column 1 Row 4");
26
27 PanelDeclarationBuilder &column_b = b.add_panel("Column 2").default_closed(true);
28 column_b.add_input<decl::Float>("Column 2 Row 1");
29 column_b.add_input<decl::Float>("Column 2 Row 2").default_value(1.0f);
30 column_b.add_input<decl::Float>("Column 2 Row 3");
31 column_b.add_input<decl::Float>("Column 2 Row 4");
32
33 PanelDeclarationBuilder &column_c = b.add_panel("Column 3").default_closed(true);
34 column_c.add_input<decl::Float>("Column 3 Row 1");
35 column_c.add_input<decl::Float>("Column 3 Row 2");
36 column_c.add_input<decl::Float>("Column 3 Row 3").default_value(1.0f);
37 column_c.add_input<decl::Float>("Column 3 Row 4");
38
39 PanelDeclarationBuilder &column_d = b.add_panel("Column 4").default_closed(true);
40 column_d.add_input<decl::Float>("Column 4 Row 1");
41 column_d.add_input<decl::Float>("Column 4 Row 2");
42 column_d.add_input<decl::Float>("Column 4 Row 3");
43 column_d.add_input<decl::Float>("Column 4 Row 4").default_value(1.0f);
44}
45
46static void copy_with_stride(const IndexMask &mask,
47 const VArray<float> &src,
48 const int64_t src_step,
49 const int64_t src_begin,
50 const int64_t dst_step,
51 const int64_t dst_begin,
53{
54 BLI_assert(src_begin < src_step);
55 BLI_assert(dst_begin < dst_step);
56 devirtualize_varray(src, [&](const auto src) {
57 mask.foreach_index_optimized<int>([&](const int64_t index) {
58 dst[dst_begin + dst_step * index] = src[src_begin + src_step * index];
59 });
60 });
61}
62
64 public:
66 {
67 static const mf::Signature signature = []() {
69 mf::SignatureBuilder builder{"Combine Matrix", signature};
70 builder.single_input<float>("Column 1 Row 1");
71 builder.single_input<float>("Column 1 Row 2");
72 builder.single_input<float>("Column 1 Row 3");
73 builder.single_input<float>("Column 1 Row 4");
74
75 builder.single_input<float>("Column 2 Row 1");
76 builder.single_input<float>("Column 2 Row 2");
77 builder.single_input<float>("Column 2 Row 3");
78 builder.single_input<float>("Column 2 Row 4");
79
80 builder.single_input<float>("Column 3 Row 1");
81 builder.single_input<float>("Column 3 Row 2");
82 builder.single_input<float>("Column 3 Row 3");
83 builder.single_input<float>("Column 3 Row 4");
84
85 builder.single_input<float>("Column 4 Row 1");
86 builder.single_input<float>("Column 4 Row 2");
87 builder.single_input<float>("Column 4 Row 3");
88 builder.single_input<float>("Column 4 Row 4");
89
90 builder.single_output<float4x4>("Matrix");
91 return signature;
92 }();
93 this->set_signature(&signature);
94 }
95
96 void call(const IndexMask &mask, mf::Params params, mf::Context /*context*/) const override
97 {
98 const VArray<float> &column_1_row_1 = params.readonly_single_input<float>(0, "Column 1 Row 1");
99 const VArray<float> &column_1_row_2 = params.readonly_single_input<float>(1, "Column 1 Row 2");
100 const VArray<float> &column_1_row_3 = params.readonly_single_input<float>(2, "Column 1 Row 3");
101 const VArray<float> &column_1_row_4 = params.readonly_single_input<float>(3, "Column 1 Row 4");
102
103 const VArray<float> &column_2_row_1 = params.readonly_single_input<float>(4, "Column 2 Row 1");
104 const VArray<float> &column_2_row_2 = params.readonly_single_input<float>(5, "Column 2 Row 2");
105 const VArray<float> &column_2_row_3 = params.readonly_single_input<float>(6, "Column 2 Row 3");
106 const VArray<float> &column_2_row_4 = params.readonly_single_input<float>(7, "Column 2 Row 4");
107
108 const VArray<float> &column_3_row_1 = params.readonly_single_input<float>(8, "Column 3 Row 1");
109 const VArray<float> &column_3_row_2 = params.readonly_single_input<float>(9, "Column 3 Row 2");
110 const VArray<float> &column_3_row_3 = params.readonly_single_input<float>(10,
111 "Column 3 Row 3");
112 const VArray<float> &column_3_row_4 = params.readonly_single_input<float>(11,
113 "Column 3 Row 4");
114
115 const VArray<float> &column_4_row_1 = params.readonly_single_input<float>(12,
116 "Column 4 Row 1");
117 const VArray<float> &column_4_row_2 = params.readonly_single_input<float>(13,
118 "Column 4 Row 2");
119 const VArray<float> &column_4_row_3 = params.readonly_single_input<float>(14,
120 "Column 4 Row 3");
121 const VArray<float> &column_4_row_4 = params.readonly_single_input<float>(15,
122 "Column 4 Row 4");
123
124 MutableSpan<float4x4> matrices = params.uninitialized_single_output<float4x4>(16, "Matrix");
125 MutableSpan<float> components = matrices.cast<float>();
126
127 copy_with_stride(mask, column_1_row_1, 1, 0, 16, 0, components);
128 copy_with_stride(mask, column_1_row_2, 1, 0, 16, 1, components);
129 copy_with_stride(mask, column_1_row_3, 1, 0, 16, 2, components);
130 copy_with_stride(mask, column_1_row_4, 1, 0, 16, 3, components);
131
132 copy_with_stride(mask, column_2_row_1, 1, 0, 16, 4, components);
133 copy_with_stride(mask, column_2_row_2, 1, 0, 16, 5, components);
134 copy_with_stride(mask, column_2_row_3, 1, 0, 16, 6, components);
135 copy_with_stride(mask, column_2_row_4, 1, 0, 16, 7, components);
136
137 copy_with_stride(mask, column_3_row_1, 1, 0, 16, 8, components);
138 copy_with_stride(mask, column_3_row_2, 1, 0, 16, 9, components);
139 copy_with_stride(mask, column_3_row_3, 1, 0, 16, 10, components);
140 copy_with_stride(mask, column_3_row_4, 1, 0, 16, 11, components);
141
142 copy_with_stride(mask, column_4_row_1, 1, 0, 16, 12, components);
143 copy_with_stride(mask, column_4_row_2, 1, 0, 16, 13, components);
144 copy_with_stride(mask, column_4_row_3, 1, 0, 16, 14, components);
145 copy_with_stride(mask, column_4_row_4, 1, 0, 16, 15, components);
146 }
147};
148
150{
151 const static CombineMatrixFunction fn;
152 builder.set_matching_fn(fn);
153}
154
156{
157 using namespace value_elem;
158
159 std::array<std::array<FloatElem, 4>, 4> input_elems;
160 for (const int col : IndexRange(4)) {
161 for (const int row : IndexRange(4)) {
162 const bNodeSocket &socket = params.node.input_socket(col * 4 + row);
163 input_elems[col][row] = params.get_input_elem<FloatElem>(socket.identifier);
164 }
165 }
166
167 MatrixElem matrix_elem;
168 matrix_elem.translation.x = input_elems[3][0];
169 matrix_elem.translation.y = input_elems[3][1];
170 matrix_elem.translation.z = input_elems[3][2];
171
172 bool any_inner_3x3 = false;
173 for (const int col : IndexRange(3)) {
174 for (const int row : IndexRange(3)) {
175 any_inner_3x3 |= input_elems[col][row];
176 }
177 }
178 if (any_inner_3x3) {
179 matrix_elem.rotation = RotationElem::all();
180 matrix_elem.scale = VectorElem::all();
181 }
182
183 const bool any_non_transform = input_elems[0][3] || input_elems[1][3] || input_elems[2][3] ||
184 input_elems[3][3];
185 if (any_non_transform) {
186 matrix_elem.any_non_transform = FloatElem::all();
187 }
188
189 params.set_output_elem("Matrix", matrix_elem);
190}
191
193{
194 using namespace value_elem;
195
196 const MatrixElem matrix_elem = params.get_output_elem<MatrixElem>("Matrix");
197 std::array<std::array<FloatElem, 4>, 4> input_elems;
198
199 input_elems[3][0] = matrix_elem.translation.x;
200 input_elems[3][1] = matrix_elem.translation.y;
201 input_elems[3][2] = matrix_elem.translation.z;
202
203 if (matrix_elem.rotation || matrix_elem.scale) {
204 for (const int col : IndexRange(3)) {
205 for (const int row : IndexRange(3)) {
206 input_elems[col][row] = FloatElem::all();
207 }
208 }
209 }
210
211 if (matrix_elem.any_non_transform) {
212 for (const int col : IndexRange(4)) {
213 input_elems[col][3] = FloatElem::all();
214 }
215 }
216
217 for (const int col : IndexRange(4)) {
218 for (const int row : IndexRange(4)) {
219 const bNodeSocket &socket = params.node.input_socket(col * 4 + row);
220 params.set_input_elem(socket.identifier, input_elems[col][row]);
221 }
222 }
223}
224
226{
227 const float4x4 matrix = params.get_output<float4x4>("Matrix");
228 for (const int col : IndexRange(4)) {
229 for (const int row : IndexRange(4)) {
230 const bNodeSocket &socket = params.node.input_socket(col * 4 + row);
231 params.set_input(socket.identifier, matrix[col][row]);
232 }
233 }
234}
235
236static void node_register()
237{
238 static blender::bke::bNodeType ntype;
239 fn_node_type_base(&ntype, FN_NODE_COMBINE_MATRIX, "Combine Matrix", NODE_CLASS_CONVERTER);
240 ntype.declare = node_declare;
246}
248
249} // namespace blender::nodes::node_fn_combine_matrix_cc
#define NODE_CLASS_CONVERTER
Definition BKE_node.hh:410
#define BLI_assert(a)
Definition BLI_assert.h:50
#define NOD_REGISTER_NODE(REGISTER_FUNC)
constexpr MutableSpan< NewT > cast() const
Definition BLI_span.hh:736
void set_signature(const Signature *signature)
void set_matching_fn(const mf::MultiFunction *fn)
void call(const IndexMask &mask, mf::Params params, mf::Context) const override
local_group_size(16, 16) .push_constant(Type b
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void node_register_type(bNodeType *ntype)
Definition node.cc:1708
static void copy_with_stride(const IndexMask &mask, const VArray< float > &src, const int64_t src_step, const int64_t src_begin, const int64_t dst_step, const int64_t dst_begin, MutableSpan< float > dst)
static void node_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_eval_inverse_elem(value_elem::InverseElemEvalParams &params)
static void node_declare(NodeDeclarationBuilder &b)
static void node_eval_elem(value_elem::ElemEvalParams &params)
static void node_eval_inverse(inverse_eval::InverseEvalParams &params)
void devirtualize_varray(const VArray< T > &varray, const Func &func, bool enable=true)
void fn_node_type_base(blender::bke::bNodeType *ntype, int type, const char *name, short nclass)
__int64 int64_t
Definition stdint.h:89
char identifier[64]
Defines a node type.
Definition BKE_node.hh:218
NodeInverseElemEvalFunction eval_inverse_elem
Definition BKE_node.hh:378
NodeInverseEvalFunction eval_inverse
Definition BKE_node.hh:385
NodeElemEvalFunction eval_elem
Definition BKE_node.hh:372
NodeMultiFunctionBuildFunction build_multi_function
Definition BKE_node.hh:336
NodeDeclareFunction declare
Definition BKE_node.hh:347