diff options
Diffstat (limited to 'source/blender/blenkernel/BKE_geometry_set.hh')
-rw-r--r-- | source/blender/blenkernel/BKE_geometry_set.hh | 98 |
1 files changed, 87 insertions, 11 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index 2d0f099e5ce..106af8172d1 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -30,6 +30,7 @@ #include "BLI_map.hh" #include "BLI_set.hh" #include "BLI_user_counter.hh" +#include "BLI_vector_set.hh" #include "BKE_attribute_access.hh" #include "BKE_geometry_set.h" @@ -505,12 +506,81 @@ class CurveComponent : public GeometryComponent { const blender::bke::ComponentAttributeProviders *get_attribute_providers() const final; }; +class InstanceReference { + public: + enum class Type { + /** + * An empty instance. This allows an `InstanceReference` to be default constructed without + * being in an invalid state. There might also be other use cases that we haven't explored much + * yet (such as changing the instance later on, and "disabling" some instances). + */ + None, + Object, + Collection, + }; + + private: + Type type_ = Type::None; + /** Depending on the type this is either null, an Object or Collection pointer. */ + void *data_ = nullptr; + + public: + InstanceReference() = default; + + InstanceReference(Object &object) : type_(Type::Object), data_(&object) + { + } + + InstanceReference(Collection &collection) : type_(Type::Collection), data_(&collection) + { + } + + Type type() const + { + return type_; + } + + Object &object() const + { + BLI_assert(type_ == Type::Object); + return *(Object *)data_; + } + + Collection &collection() const + { + BLI_assert(type_ == Type::Collection); + return *(Collection *)data_; + } + + uint64_t hash() const + { + return blender::get_default_hash(data_); + } + + friend bool operator==(const InstanceReference &a, const InstanceReference &b) + { + return a.data_ == b.data_; + } +}; + /** A geometry component that stores instances. */ class InstancesComponent : public GeometryComponent { private: - blender::Vector<blender::float4x4> transforms_; - blender::Vector<int> ids_; - blender::Vector<InstancedData> instanced_data_; + /** + * Indexed set containing information about the data that is instanced. + * Actual instances store an index ("handle") into this set. + */ + blender::VectorSet<InstanceReference> references_; + + /** Index into `references_`. Determines what data is instanced. */ + blender::Vector<int> instance_reference_handles_; + /** Transformation of the instances. */ + blender::Vector<blender::float4x4> instance_transforms_; + /** + * IDs of the instances. They are used for consistency over multiple frames for things like + * motion blur. + */ + blender::Vector<int> instance_ids_; /* These almost unique ids are generated based on `ids_`, which might not contain unique ids at * all. They are *almost* unique, because under certain very unlikely circumstances, they are not @@ -525,14 +595,20 @@ class InstancesComponent : public GeometryComponent { GeometryComponent *copy() const override; void clear(); - 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::float4x4> transforms() const; - blender::Span<int> ids() const; - blender::MutableSpan<blender::float4x4> transforms(); + + void reserve(int min_capacity); + + int add_reference(InstanceReference reference); + void add_instance(int instance_handle, const blender::float4x4 &transform, const int id = -1); + + blender::Span<InstanceReference> references() const; + + blender::Span<int> instance_reference_handles() const; + blender::MutableSpan<blender::float4x4> instance_transforms(); + blender::Span<blender::float4x4> instance_transforms() const; + blender::MutableSpan<int> instance_ids(); + blender::Span<int> instance_ids() const; + int instances_amount() const; blender::Span<int> almost_unique_ids() const; |