From abd6b1d7b281c85fce748e0535f1f769916cd9b3 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Tue, 26 Jan 2021 18:21:12 +0100 Subject: Fix T85049: Geometry Nodes: How to handle instances with shear? Use transform matrices instead of loc, rot, scale variables to store instance transforms. Reviewed By: JacquesLucke Differential Revision: http://developer.blender.org/D10211 --- source/blender/blenkernel/intern/geometry_set.cc | 77 ++++++------------------ source/blender/blenkernel/intern/object_dupli.c | 26 ++------ 2 files changed, 23 insertions(+), 80 deletions(-) (limited to 'source/blender/blenkernel/intern') diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index 81958b81213..bb315bc0289 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -25,6 +25,7 @@ #include "MEM_guardedalloc.h" using blender::float3; +using blender::float4x4; using blender::MutableSpan; using blender::Span; using blender::StringRef; @@ -458,9 +459,7 @@ InstancesComponent::InstancesComponent() : GeometryComponent(GeometryComponentTy GeometryComponent *InstancesComponent::copy() const { InstancesComponent *new_component = new InstancesComponent(); - new_component->positions_ = positions_; - new_component->rotations_ = rotations_; - new_component->scales_ = scales_; + new_component->transforms_ = transforms_; new_component->instanced_data_ = instanced_data_; return new_component; } @@ -468,45 +467,29 @@ GeometryComponent *InstancesComponent::copy() const void InstancesComponent::clear() { instanced_data_.clear(); - positions_.clear(); - rotations_.clear(); - scales_.clear(); + transforms_.clear(); } -void InstancesComponent::add_instance(Object *object, - blender::float3 position, - blender::float3 rotation, - blender::float3 scale, - const int id) +void InstancesComponent::add_instance(Object *object, float4x4 transform, const int id) { InstancedData data; data.type = INSTANCE_DATA_TYPE_OBJECT; data.data.object = object; - this->add_instance(data, position, rotation, scale, id); + this->add_instance(data, transform, id); } -void InstancesComponent::add_instance(Collection *collection, - blender::float3 position, - blender::float3 rotation, - blender::float3 scale, - const int id) +void InstancesComponent::add_instance(Collection *collection, float4x4 transform, const int id) { InstancedData data; data.type = INSTANCE_DATA_TYPE_COLLECTION; data.data.collection = collection; - this->add_instance(data, position, rotation, scale, id); + this->add_instance(data, transform, id); } -void InstancesComponent::add_instance(InstancedData data, - blender::float3 position, - blender::float3 rotation, - blender::float3 scale, - const int id) +void InstancesComponent::add_instance(InstancedData data, float4x4 transform, const int id) { instanced_data_.append(data); - positions_.append(position); - rotations_.append(rotation); - scales_.append(scale); + transforms_.append(transform); ids_.append(id); } @@ -515,19 +498,9 @@ Span InstancesComponent::instanced_data() const return instanced_data_; } -Span InstancesComponent::positions() const +Span InstancesComponent::transforms() const { - return positions_; -} - -Span InstancesComponent::rotations() const -{ - return rotations_; -} - -Span InstancesComponent::scales() const -{ - return scales_; + return transforms_; } Span InstancesComponent::ids() const @@ -535,33 +508,21 @@ Span InstancesComponent::ids() const return ids_; } -MutableSpan InstancesComponent::positions() -{ - return positions_; -} - -MutableSpan InstancesComponent::rotations() -{ - return rotations_; -} - -MutableSpan InstancesComponent::scales() +MutableSpan InstancesComponent::transforms() { - return scales_; + return transforms_; } int InstancesComponent::instances_amount() const { const int size = instanced_data_.size(); - BLI_assert(positions_.size() == size); - BLI_assert(rotations_.size() == size); - BLI_assert(scales_.size() == size); + BLI_assert(transforms_.size() == size); return size; } bool InstancesComponent::is_empty() const { - return positions_.size() == 0; + return transforms_.size() == 0; } /** \} */ @@ -581,9 +542,7 @@ bool BKE_geometry_set_has_instances(const GeometrySet *geometry_set) } int BKE_geometry_set_instances(const GeometrySet *geometry_set, - float (**r_positions)[3], - float (**r_rotations)[3], - float (**r_scales)[3], + float (**r_transforms)[4][4], int **r_ids, InstancedData **r_instanced_data) { @@ -591,9 +550,7 @@ int BKE_geometry_set_instances(const GeometrySet *geometry_set, if (component == nullptr) { return 0; } - *r_positions = (float(*)[3])component->positions().data(); - *r_rotations = (float(*)[3])component->rotations().data(); - *r_scales = (float(*)[3])component->scales().data(); + *r_transforms = (float(*)[4][4])component->transforms().data(); *r_ids = (int *)component->ids().data(); *r_instanced_data = (InstancedData *)component->instanced_data().data(); *r_instanced_data = (InstancedData *)component->instanced_data().data(); diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index d5317864480..6c8a57f8599 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -813,40 +813,26 @@ static const DupliGenerator gen_dupli_verts_pointcloud = { static void make_duplis_instances_component(const DupliContext *ctx) { - float(*positions)[3]; - float(*rotations)[3]; - float(*scales)[3]; + float(*instance_offset_matrices)[4][4]; int *ids; InstancedData *instanced_data; - const int amount = BKE_geometry_set_instances(ctx->object->runtime.geometry_set_eval, - &positions, - &rotations, - &scales, - &ids, - &instanced_data); + const int amount = BKE_geometry_set_instances( + ctx->object->runtime.geometry_set_eval, &instance_offset_matrices, &ids, &instanced_data); for (int i = 0; i < amount; i++) { InstancedData *data = &instanced_data[i]; - float scale_matrix[4][4]; - size_to_mat4(scale_matrix, scales[i]); - float rotation_matrix[4][4]; - eul_to_mat4(rotation_matrix, rotations[i]); - float instance_offset_matrix[4][4]; - mul_m4_m4m4(instance_offset_matrix, rotation_matrix, scale_matrix); - copy_v3_v3(instance_offset_matrix[3], positions[i]); - const int id = ids[i] != -1 ? ids[i] : 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); + mul_m4_m4m4(matrix, ctx->object->obmat, instance_offset_matrices[i]); make_dupli(ctx, object, matrix, id); float space_matrix[4][4]; - mul_m4_m4m4(space_matrix, instance_offset_matrix, object->imat); + mul_m4_m4m4(space_matrix, instance_offset_matrices[i], object->imat); mul_m4_m4_pre(space_matrix, ctx->object->obmat); make_recursive_duplis(ctx, object, space_matrix, id); } @@ -857,7 +843,7 @@ static void make_duplis_instances_component(const DupliContext *ctx) 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, instance_offset_matrices[i]); mul_m4_m4_pre(collection_matrix, ctx->object->obmat); eEvaluationMode mode = DEG_get_mode(ctx->depsgraph); -- cgit v1.2.3