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.
7 changed files with 35 additions and 100 deletions
Showing only changes of commit 83e4fef23c - Show all commits

View File

@ -2395,8 +2395,3 @@ typedef enum NodeCombSepMatrixMode {
NODE_COMBSEP_MATRIX_ROWS = 1,
NODE_COMBSEP_MATRIX_ELEMENTS = 2,
} NodeCombSepMatrixMode;
typedef enum GeometryNodeTransformInputMode {
GEO_NODE_TRANSFORM_INPUT_MATRIX = 0,
GEO_NODE_TRANSFORM_INPUT_LOCROTSCALE = 1,
} GeometryNodeTransformInputMode;

View File

@ -562,11 +562,6 @@ static EnumPropertyItem rna_node_geometry_mesh_circle_fill_type_items[] = {
{GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN, "TRIANGLE_FAN", 0, "Triangles", ""},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem rna_node_geometry_transform_input_mode_items[] = {
{GEO_NODE_TRANSFORM_INPUT_MATRIX, "LEFT", ICON_NONE, "Matrix", "Use instance transforms matrix"},
{GEO_NODE_TRANSFORM_INPUT_LOCROTSCALE, "LOCROTSCALE", ICON_NONE, "LocRotScale", "Use instance location, rotation, and scale"},
{0, NULL, 0, NULL, NULL}};
#endif
#ifndef RNA_RUNTIME
@ -11015,17 +11010,6 @@ static void def_geo_field_at_index(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
}
static void def_geo_instance_on_points(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "transform_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_node_geometry_transform_input_mode_items);
RNA_def_property_ui_text(prop, "Transform Mode", "Mode of defining transform for instances");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update");
}
static void def_geo_interpolate_domain(StructRNA *srna)
{
PropertyRNA *prop;

View File

@ -356,7 +356,7 @@ DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_CYCLIC, 0, "INPUT_SPLINE_CYCLIC",Inp
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_LENGTH, 0, "SPLINE_LENGTH", SplineLength, "Spline Length", "Retrieve the total length of each spline, as a distance or as a number of points")
DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_RESOLUTION, 0, "INPUT_SPLINE_RESOLUTION", InputSplineResolution, "Spline Resolution", "Retrieve the number of evaluated points that will be generated for every control point on curves")
DefNode(GeometryNode, GEO_NODE_INPUT_TANGENT, 0, "INPUT_TANGENT", InputTangent, "Curve Tangent", "Retrieve the direction of curves at each control point")
DefNode(GeometryNode, GEO_NODE_INSTANCE_ON_POINTS, def_geo_instance_on_points, "INSTANCE_ON_POINTS", InstanceOnPoints, "Instance on Points", "Generate a reference to geometry at each of the input points, without duplicating its underlying data")
DefNode(GeometryNode, GEO_NODE_INSTANCE_ON_POINTS, 0, "INSTANCE_ON_POINTS", InstanceOnPoints, "Instance on Points", "Generate a reference to geometry at each of the input points, without duplicating its underlying data")
DefNode(GeometryNode, GEO_NODE_INSTANCES_TO_POINTS, 0, "INSTANCES_TO_POINTS",InstancesToPoints, "Instances to Points","Generate points at the origins of instances.\nNote: Nested instances are not affected by this node")
DefNode(GeometryNode, GEO_NODE_INTERPOLATE_DOMAIN, def_geo_interpolate_domain, "FIELD_ON_DOMAIN", FieldOnDomain, "Interpolate Domain", "Retrieve values from a field on a different domain besides the domain from the context")
DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "Retrieve whether the nodes are being evaluated for the viewport rather than the final render")

View File

@ -51,26 +51,24 @@ 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, (bNodeSocket *)BLI_findlink(&node->inputs, i), show_vector_sockets);
nodeSetSocketAvailability(tree, &node->input_socket(i), show_vector_sockets);
}
for (const int i : scalar_sockets) {
nodeSetSocketAvailability(
tree, (bNodeSocket *)BLI_findlink(&node->inputs, i), show_scalar_sockets);
nodeSetSocketAvailability(tree, &node->input_socket(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");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[3]), "Column 3");
node_sock_label(&node->input_socket(vector_sockets[0]), "Column 0");
node_sock_label(&node->input_socket(vector_sockets[1]), "Column 1");
node_sock_label(&node->input_socket(vector_sockets[2]), "Column 2");
node_sock_label(&node->input_socket(vector_sockets[3]), "Column 3");
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");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[3]), "Row 3");
node_sock_label(&node->input_socket(vector_sockets[0]), "Row 0");
node_sock_label(&node->input_socket(vector_sockets[1]), "Row 1");
node_sock_label(&node->input_socket(vector_sockets[2]), "Row 2");
node_sock_label(&node->input_socket(vector_sockets[3]), "Row 3");
break;
case NODE_COMBSEP_MATRIX_ELEMENTS:
break;

View File

@ -50,21 +50,21 @@ 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);
bNodeSocket *inMatrixA = &node->input_socket(0);
bNodeSocket *inMatrixB = &node->input_socket(1);
bNodeSocket *inScale = &node->input_socket(2);
bNodeSocket *outMatrix = &node->output_socket(3);
bNodeSocket *outValue = &node->output_socket(4);
nodeSetSocketAvailability(tree, in_matrix_a, true);
nodeSetSocketAvailability(tree, inMatrixA, true);
nodeSetSocketAvailability(
tree,
in_matrix_b,
inMatrixB,
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, inScale, ELEM(op, NODE_MATRIX_MATH_SCALAR_MULTIPLY));
nodeSetSocketAvailability(tree,
out_matrix,
outMatrix,
ELEM(op,
NODE_MATRIX_MATH_ADD,
NODE_MATRIX_MATH_SUBTRACT,
@ -73,12 +73,12 @@ static void node_update(bNodeTree *tree, bNode *node)
NODE_MATRIX_MATH_TRANSPOSE,
NODE_MATRIX_MATH_INVERSE));
nodeSetSocketAvailability(
tree, out_value, ELEM(op, NODE_MATRIX_MATH_DETERMINANT, NODE_MATRIX_MATH_TRACE));
tree, outValue, 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);
node_sock_label_clear(inMatrixA);
node_sock_label_clear(inMatrixB);
node_sock_label_clear(inScale);
switch (op) {
}
}

View File

@ -61,16 +61,16 @@ static void node_update(bNodeTree *tree, bNode *node)
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");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[3]), "Column 3");
node_sock_label(&node->output_socket(vector_sockets[0]), "Column 0");
node_sock_label(&node->output_socket(vector_sockets[1]), "Column 1");
node_sock_label(&node->output_socket(vector_sockets[2]), "Column 2");
node_sock_label(&node->output_socket(vector_sockets[3]), "Column 3");
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");
node_sock_label((bNodeSocket *)BLI_findlink(&node->inputs, vector_sockets[3]), "Row 3");
node_sock_label(&node->output_socket(vector_sockets[0]), "Row 0");
node_sock_label(&node->output_socket(vector_sockets[1]), "Row 1");
node_sock_label(&node->output_socket(vector_sockets[2]), "Row 2");
node_sock_label(&node->output_socket(vector_sockets[3]), "Row 3");
break;
case NODE_COMBSEP_MATRIX_ELEMENTS:
break;

View File

@ -40,33 +40,10 @@ static void node_declare(NodeDeclarationBuilder &b)
.subtype(PROP_XYZ)
.supports_field()
.description(N_("Scale of the instances"));
b.add_input<decl::Matrix4x4>(N_("Matrix"))
.default_value(float4x4::identity())
.supports_field()
.description(N_("Transform matrix of the instances"));
b.add_output<decl::Geometry>(N_("Instances"));
}
static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "transform_mode", 0, "", ICON_NONE);
}
static void node_update(bNodeTree *tree, bNode *node)
{
const GeometryNodeTransformInputMode transform_mode = (GeometryNodeTransformInputMode)
node->custom1;
bNodeSocket *in_rotation = nodeFindSocket(node, SOCK_IN, "Rotation");
bNodeSocket *in_scale = nodeFindSocket(node, SOCK_IN, "Scale");
bNodeSocket *in_matrix = nodeFindSocket(node, SOCK_IN, "Matrix");
nodeSetSocketAvailability(tree, in_rotation, transform_mode == GEO_NODE_TRANSFORM_INPUT_LOCROTSCALE);
nodeSetSocketAvailability(tree, in_scale, transform_mode == GEO_NODE_TRANSFORM_INPUT_LOCROTSCALE);
nodeSetSocketAvailability(tree, in_matrix, transform_mode == GEO_NODE_TRANSFORM_INPUT_MATRIX);
}
static void add_instances_from_component(
bke::Instances &dst_component,
const GeometryComponent &src_component,
@ -76,14 +53,11 @@ static void add_instances_from_component(
{
const eAttrDomain domain = ATTR_DOMAIN_POINT;
const int domain_num = src_component.attribute_domain_size(domain);
const GeometryNodeTransformInputMode transform_mode =
(GeometryNodeTransformInputMode)params.node().custom1;
VArray<bool> pick_instance;
VArray<int> indices;
VArray<float3> rotations;
VArray<float3> scales;
VArray<float4x4> matrices;
bke::GeometryFieldContext field_context{src_component, domain};
const Field<bool> selection_field = params.get_input<Field<bool>>("Selection");
@ -93,15 +67,8 @@ static void add_instances_from_component(
* selected indices should be copied. */
evaluator.add(params.get_input<Field<bool>>("Pick Instance"), &pick_instance);
evaluator.add(params.get_input<Field<int>>("Instance Index"), &indices);
switch (transform_mode) {
case GEO_NODE_TRANSFORM_INPUT_MATRIX:
evaluator.add(params.get_input<Field<float4x4>>("Matrix"), &matrices);
break;
case GEO_NODE_TRANSFORM_INPUT_LOCROTSCALE:
evaluator.add(params.get_input<Field<float3>>("Rotation"), &rotations);
evaluator.add(params.get_input<Field<float3>>("Scale"), &scales);
break;
}
evaluator.add(params.get_input<Field<float3>>("Rotation"), &rotations);
evaluator.add(params.get_input<Field<float3>>("Scale"), &scales);
evaluator.evaluate();
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
@ -147,14 +114,7 @@ static void add_instances_from_component(
/* Compute base transform for every instances. */
float4x4 &dst_transform = dst_transforms[range_i];
switch (transform_mode) {
case GEO_NODE_TRANSFORM_INPUT_MATRIX:
dst_transform = matrices[i];
break;
case GEO_NODE_TRANSFORM_INPUT_LOCROTSCALE:
dst_transform = float4x4::from_loc_eul_scale(positions[i], rotations[i], scales[i]);
break;
}
dst_transform = float4x4::from_loc_eul_scale(positions[i], rotations[i], scales[i]);
/* Reference that will be used by this new instance. */
int dst_handle = empty_reference_handle;
@ -276,8 +236,6 @@ void register_node_type_geo_instance_on_points()
geo_node_type_base(
&ntype, GEO_NODE_INSTANCE_ON_POINTS, "Instance on Points", NODE_CLASS_GEOMETRY);
ntype.declare = file_ns::node_declare;
ntype.updatefunc = file_ns::node_update;
ntype.draw_buttons = file_ns::node_layout;
ntype.geometry_node_execute = file_ns::node_geo_exec;
nodeRegisterType(&ntype);
}