[Bf-blender-cvs] [547f7d23caf] master: Geometry Nodes: support outputting collection children as instances

Jacques Lucke noreply at git.blender.org
Mon Sep 27 10:17:28 CEST 2021


Commit: 547f7d23cafb682d3ac6d1348d70caef411ecc51
Author: Jacques Lucke
Date:   Mon Sep 27 09:51:41 2021 +0200
Branches: master
https://developer.blender.org/rB547f7d23cafb682d3ac6d1348d70caef411ecc51

Geometry Nodes: support outputting collection children as instances

This adds two new input sockets to the Collection Info node:
* `Separate Children`: When turned off, the entire collection is output as a single
  collection instance (same behavior as before). When turned on, each child of
  the collection is output as a separate instance (children can be objects and collections).
  Toggling this input should not change the visual transforms of the output geometry.
* `Reset Children`: Only used when `Separate Children` is on. When used, the transforms
  of the instances are reset to the origin. This is useful when one wants to e.g. instance
  the collection children separately in the upcoming instancing node.

Part of D12478.

===================================================================

M	source/blender/nodes/geometry/nodes/node_geo_collection_info.cc

===================================================================

diff --git a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
index f4c295b06fb..d03221703f0 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_collection_info.cc
@@ -21,6 +21,8 @@
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "BKE_collection.h"
+
 #include "node_geometry_util.hh"
 
 namespace blender::nodes {
@@ -28,6 +30,12 @@ namespace blender::nodes {
 static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
 {
   b.add_input<decl::Collection>("Collection").hide_label();
+  b.add_input<decl::Bool>("Separate Children")
+      .description("Output each child of the collection as a separate instance");
+  b.add_input<decl::Bool>("Reset Children")
+      .description(
+          "Reset the transforms of every child instance in the output. Only used when Separate "
+          "Children is enabled");
   b.add_output<decl::Geometry>("Geometry");
 }
 
@@ -57,23 +65,66 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
 
   const bNode &bnode = params.node();
   NodeGeometryCollectionInfo *node_storage = (NodeGeometryCollectionInfo *)bnode.storage;
-  const bool transform_space_relative = (node_storage->transform_space ==
-                                         GEO_NODE_TRANSFORM_SPACE_RELATIVE);
+  const bool use_relative_transform = (node_storage->transform_space ==
+                                       GEO_NODE_TRANSFORM_SPACE_RELATIVE);
 
   InstancesComponent &instances = geometry_set_out.get_component_for_write<InstancesComponent>();
 
-  float transform_mat[4][4];
-  unit_m4(transform_mat);
   const Object *self_object = params.self_object();
 
-  if (transform_space_relative) {
-    copy_v3_v3(transform_mat[3], collection->instance_offset);
-
-    mul_m4_m4_pre(transform_mat, self_object->imat);
+  const bool separate_children = params.get_input<bool>("Separate Children");
+  if (separate_children) {
+    const bool reset_children = params.get_input<bool>("Reset Children");
+    Vector<Collection *> children_collections;
+    LISTBASE_FOREACH (CollectionChild *, collection_child, &collection->children) {
+      children_collections.append(collection_child->collection);
+    }
+    Vector<Object *> children_objects;
+    LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
+      children_objects.append(collection_object->ob);
+    }
+
+    instances.reserve(children_collections.size() + children_objects.size());
+
+    for (Collection *child_collection : children_collections) {
+      float4x4 transform = float4x4::identity();
+      if (!reset_children) {
+        add_v3_v3(transform.values[3], child_collection->instance_offset);
+        if (use_relative_transform) {
+          mul_m4_m4_pre(transform.values, self_object->imat);
+        }
+        else {
+          sub_v3_v3(transform.values[3], collection->instance_offset);
+        }
+      }
+      const int handle = instances.add_reference(*child_collection);
+      instances.add_instance(handle, transform);
+    }
+    for (Object *child_object : children_objects) {
+      const int handle = instances.add_reference(*child_object);
+      float4x4 transform = float4x4::identity();
+      if (!reset_children) {
+        if (use_relative_transform) {
+          transform = self_object->imat;
+        }
+        else {
+          sub_v3_v3(transform.values[3], collection->instance_offset);
+        }
+        mul_m4_m4_post(transform.values, child_object->obmat);
+      }
+      instances.add_instance(handle, transform);
+    }
+  }
+  else {
+    float4x4 transform = float4x4::identity();
+    if (use_relative_transform) {
+      copy_v3_v3(transform.values[3], collection->instance_offset);
+      mul_m4_m4_pre(transform.values, self_object->imat);
+    }
+
+    const int handle = instances.add_reference(*collection);
+    instances.add_instance(handle, transform);
   }
-
-  const int handle = instances.add_reference(*collection);
-  instances.add_instance(handle, transform_mat, -1);
 
   params.set_output("Geometry", geometry_set_out);
 }



More information about the Bf-blender-cvs mailing list