Geometry Nodes: Small improvements to object info node

This commit contains a few mostly-related changes to this node:
 -  Add a warning when retrieving the geometry from the modifier object.
 - Only create the output geometry when it is necessary.
 - Decompose transform matrices in a more friendly way.
 - Use default return callbacks like other newer nodes.

Differential Revision: https://developer.blender.org/D13232
This commit is contained in:
Hans Goudey 2021-11-16 15:09:00 -06:00
parent c9fb08e075
commit cf83719761
Notes: blender-bot 2023-12-29 23:59:18 +01:00
Referenced by issue #104926, Geometry nodes: Object Info does not return negative Scale values
1 changed files with 53 additions and 40 deletions

View File

@ -47,51 +47,64 @@ static void geo_node_object_info_exec(GeoNodeExecParams params)
const bool transform_space_relative = (node_storage->transform_space ==
GEO_NODE_TRANSFORM_SPACE_RELATIVE);
auto default_transform = [&]() {
params.set_output("Location", float3(0));
params.set_output("Rotation", float3(0));
params.set_output("Scale", float3(0));
};
auto default_geometry = [&]() { params.set_output("Geometry", GeometrySet()); };
Object *object = params.get_input<Object *>("Object");
float3 location = {0, 0, 0};
float3 rotation = {0, 0, 0};
float3 scale = {0, 0, 0};
GeometrySet geometry_set;
const Object *self_object = params.self_object();
if (object != nullptr) {
const float4x4 transform = float4x4(self_object->imat) * float4x4(object->obmat);
float quaternion[4];
if (transform_space_relative) {
mat4_decompose(location, quaternion, scale, transform.values);
}
else {
mat4_decompose(location, quaternion, scale, object->obmat);
}
quat_to_eul(rotation, quaternion);
if (object != self_object) {
if (params.get_input<bool>("As Instance")) {
InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
const int handle = instances.add_reference(*object);
if (transform_space_relative) {
instances.add_instance(handle, transform);
}
else {
instances.add_instance(handle, float4x4::identity());
}
}
else {
geometry_set = bke::object_get_evaluated_geometry_set(*object);
if (transform_space_relative) {
transform_geometry_set(geometry_set, transform, *params.depsgraph());
}
}
}
if (object == nullptr) {
default_transform();
default_geometry();
return;
}
params.set_output("Location", location);
params.set_output("Rotation", rotation);
params.set_output("Scale", scale);
params.set_output("Geometry", geometry_set);
const float4x4 &object_matrix = object->obmat;
const float4x4 transform = float4x4(self_object->imat) * object_matrix;
if (transform_space_relative) {
params.set_output("Location", transform.translation());
params.set_output("Rotation", transform.to_euler());
params.set_output("Scale", transform.scale());
}
else {
params.set_output("Location", object_matrix.translation());
params.set_output("Rotation", object_matrix.to_euler());
params.set_output("Scale", object_matrix.scale());
}
if (params.output_is_required("Geometry")) {
if (object == self_object) {
params.error_message_add(NodeWarningType::Error,
TIP_("Geometry cannot be retrieved from the modifier object"));
default_geometry();
return;
}
GeometrySet geometry_set;
if (params.get_input<bool>("As Instance")) {
InstancesComponent &instances = geometry_set.get_component_for_write<InstancesComponent>();
const int handle = instances.add_reference(*object);
if (transform_space_relative) {
instances.add_instance(handle, transform);
}
else {
instances.add_instance(handle, float4x4::identity());
}
}
else {
geometry_set = bke::object_get_evaluated_geometry_set(*object);
if (transform_space_relative) {
transform_geometry_set(geometry_set, transform, *params.depsgraph());
}
}
params.set_output("Geometry", geometry_set);
}
}
static void geo_node_object_info_node_init(bNodeTree *UNUSED(tree), bNode *node)