diff options
8 files changed, 52 insertions, 124 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h index 5b8273def66..27ac6d98688 100644 --- a/source/blender/blenkernel/BKE_geometry_set.h +++ b/source/blender/blenkernel/BKE_geometry_set.h @@ -46,9 +46,7 @@ typedef struct InstancedData { } InstancedData; int BKE_geometry_set_instances(const struct GeometrySet *geometry_set, - float (**r_positions)[3], - float (**r_rotations)[3], - float (**r_scales)[3], + float (**r_transforms)[4][4], int **r_ids, struct InstancedData **r_instanced_data); diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index ad5a5d57045..3b093ae730a 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -24,6 +24,7 @@ #include <iostream> #include "BLI_float3.hh" +#include "BLI_float4x4.hh" #include "BLI_hash.hh" #include "BLI_map.hh" #include "BLI_set.hh" @@ -422,9 +423,7 @@ class PointCloudComponent : public GeometryComponent { /** A geometry component that stores instances. */ class InstancesComponent : public GeometryComponent { private: - blender::Vector<blender::float3> positions_; - blender::Vector<blender::float3> rotations_; - blender::Vector<blender::float3> scales_; + blender::Vector<blender::float4x4> transforms_; blender::Vector<int> ids_; blender::Vector<InstancedData> instanced_data_; @@ -434,30 +433,14 @@ class InstancesComponent : public GeometryComponent { GeometryComponent *copy() const override; void clear(); - void add_instance(Object *object, - blender::float3 position, - blender::float3 rotation = {0, 0, 0}, - blender::float3 scale = {1, 1, 1}, - const int id = -1); - void add_instance(Collection *collection, - blender::float3 position, - blender::float3 rotation = {0, 0, 0}, - blender::float3 scale = {1, 1, 1}, - const int id = -1); - void add_instance(InstancedData data, - blender::float3 position, - blender::float3 rotation, - blender::float3 scale, - const int id = -1); + void add_instance(Object *object, blender::float4x4 transform, const int id = -1); + void add_instance(Collection *collection, blender::float4x4 transform, const int id = -1); + void add_instance(InstancedData data, blender::float4x4 transform, const int id = -1); blender::Span<InstancedData> instanced_data() const; - blender::Span<blender::float3> positions() const; - blender::Span<blender::float3> rotations() const; - blender::Span<blender::float3> scales() const; + blender::Span<blender::float4x4> transforms() const; blender::Span<int> ids() const; - blender::MutableSpan<blender::float3> positions(); - blender::MutableSpan<blender::float3> rotations(); - blender::MutableSpan<blender::float3> scales(); + blender::MutableSpan<blender::float4x4> transforms(); int instances_amount() const; bool is_empty() const final; 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<InstancedData> InstancesComponent::instanced_data() const return instanced_data_; } -Span<float3> InstancesComponent::positions() const +Span<float4x4> InstancesComponent::transforms() const { - return positions_; -} - -Span<float3> InstancesComponent::rotations() const -{ - return rotations_; -} - -Span<float3> InstancesComponent::scales() const -{ - return scales_; + return transforms_; } Span<int> InstancesComponent::ids() const @@ -535,33 +508,21 @@ Span<int> InstancesComponent::ids() const return ids_; } -MutableSpan<float3> InstancesComponent::positions() -{ - return positions_; -} - -MutableSpan<float3> InstancesComponent::rotations() -{ - return rotations_; -} - -MutableSpan<float3> InstancesComponent::scales() +MutableSpan<float4x4> 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); diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh index 0433197b22a..d6d759ccfe4 100644 --- a/source/blender/blenlib/BLI_float4x4.hh +++ b/source/blender/blenlib/BLI_float4x4.hh @@ -45,6 +45,17 @@ struct float4x4 { return &values[0][0]; } + using c_style_float4x4 = float[4][4]; + c_style_float4x4 &ptr() + { + return values; + } + + const c_style_float4x4 &ptr() const + { + return values; + } + friend float4x4 operator*(const float4x4 &a, const float4x4 &b) { float4x4 result; diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc index e00ee9b01d8..67bc095fa31 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc @@ -233,11 +233,9 @@ static void join_components(Span<const InstancesComponent *> src_components, Geo for (const InstancesComponent *component : src_components) { const int size = component->instances_amount(); Span<InstancedData> instanced_data = component->instanced_data(); - Span<float3> positions = component->positions(); - Span<float3> rotations = component->rotations(); - Span<float3> scales = component->scales(); + Span<float4x4> transforms = component->transforms(); for (const int i : IndexRange(size)) { - dst_component.add_instance(instanced_data[i], positions[i], rotations[i], scales[i]); + dst_component.add_instance(instanced_data[i], transforms[i]); } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc index d9e69adb860..a96dc710427 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc @@ -165,7 +165,9 @@ static void add_instances_from_geometry_component(InstancesComponent &instances, for (const int i : IndexRange(domain_size)) { if (instances_data[i].has_value()) { - instances.add_instance(*instances_data[i], positions[i], rotations[i], scales[i], ids[i]); + float transform[4][4]; + loc_eul_size_to_mat4(transform, positions[i], rotations[i], scales[i]); + instances.add_instance(*instances_data[i], transform, ids[i]); } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc index 84540c283ef..1fcd1063993 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc @@ -91,27 +91,20 @@ static void transform_instances(InstancesComponent &instances, const float3 rotation, const float3 scale) { - MutableSpan<float3> positions = instances.positions(); - MutableSpan<float3> rotations = instances.rotations(); - MutableSpan<float3> scales = instances.scales(); + MutableSpan<float4x4> transforms = instances.transforms(); /* Use only translation if rotation and scale don't apply. */ if (use_translate(rotation, scale)) { - for (float3 &position : positions) { - add_v3_v3(position, translation); + for (float4x4 &transform : transforms) { + add_v3_v3(transform.ptr()[3], translation); } } else { float mat[4][4]; - float instance_mat[4][4]; - float quaternion[4]; loc_eul_size_to_mat4(mat, translation, rotation, scale); - for (int i = 0; i < positions.size(); i++) { - loc_eul_size_to_mat4(instance_mat, positions[i], rotations[i], scales[i]); - mul_m4_m4_pre(instance_mat, mat); - mat4_decompose(positions[i], quaternion, scales[i], instance_mat); - quat_to_eul(rotations[i], quaternion); + for (float4x4 &transform : transforms) { + mul_m4_m4_pre(transform.ptr(), mat); } } } |