From f5dc34ec9c05cc8f1163313baafe634f4798c29b Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 11 Dec 2020 18:00:37 +0100 Subject: Geometry Nodes: support instancing collections The Point Instance node can instance entire collections now. Before, only individual collections were supported. Randomly selecting objects from the collection on a per point basis is not support, yet. Last part of D9739. Ref T82372. --- source/blender/blenkernel/intern/object_dupli.c | 53 +++++++++++++++++++------ 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'source/blender/blenkernel/intern/object_dupli.c') diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index d5434710e23..8fa708f31cb 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -816,15 +816,13 @@ static void make_duplis_instances_component(const DupliContext *ctx) float(*positions)[3]; float(*rotations)[3]; float(*scales)[3]; - Object **objects; + InstancedData *instanced_data; const int amount = BKE_geometry_set_instances( - ctx->object->runtime.geometry_set_eval, &positions, &rotations, &scales, &objects); + ctx->object->runtime.geometry_set_eval, &positions, &rotations, &scales, &instanced_data); for (int i = 0; i < amount; i++) { - Object *object = objects[i]; - if (object == NULL) { - continue; - } + InstancedData *data = &instanced_data[i]; + float scale_matrix[4][4]; size_to_mat4(scale_matrix, scales[i]); float rotation_matrix[4][4]; @@ -833,14 +831,43 @@ static void make_duplis_instances_component(const DupliContext *ctx) mul_m4_m4m4(instance_offset_matrix, rotation_matrix, scale_matrix); copy_v3_v3(instance_offset_matrix[3], positions[i]); - float matrix[4][4]; - mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrix); - make_dupli(ctx, object, matrix, i); + if (data->type == INSTANCE_DATA_TYPE_OBJECT) { + Object *object = data->data.object; + if (object != NULL) { + float matrix[4][4]; + mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrix); + make_dupli(ctx, object, matrix, i); + + float space_matrix[4][4]; + mul_m4_m4m4(space_matrix, instance_offset_matrix, object->imat); + mul_m4_m4_pre(space_matrix, ctx->object->obmat); + make_recursive_duplis(ctx, object, space_matrix, i); + } + } + else if (data->type == INSTANCE_DATA_TYPE_COLLECTION) { + Collection *collection = data->data.collection; + if (collection != NULL) { + float collection_matrix[4][4]; + unit_m4(collection_matrix); + sub_v3_v3(collection_matrix[3], collection->instance_offset); + mul_m4_m4_pre(collection_matrix, instance_offset_matrix); + mul_m4_m4_pre(collection_matrix, ctx->object->obmat); + + eEvaluationMode mode = DEG_get_mode(ctx->depsgraph); + FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_BEGIN (collection, object, mode) { + if (object == ctx->object) { + continue; + } + + float instance_matrix[4][4]; + mul_m4_m4m4(instance_matrix, collection_matrix, object->obmat); - float space_matrix[4][4]; - mul_m4_m4m4(space_matrix, instance_offset_matrix, object->imat); - mul_m4_m4_pre(space_matrix, ctx->object->obmat); - make_recursive_duplis(ctx, object, space_matrix, i); + make_dupli(ctx, object, instance_matrix, i); + make_recursive_duplis(ctx, object, collection_matrix, i); + } + FOREACH_COLLECTION_VISIBLE_OBJECT_RECURSIVE_END; + } + } } } -- cgit v1.2.3