56template<
class T>
static inline const T *get_original(
const T *
id)
67bool is_valid_input_id(
const ID &
id)
89class LightSetIDManager {
93 explicit LightSetIDManager(
const Scene &scene) : scene_(scene) {}
103 const uint64_t light_set_id = light_set_id_map_.lookup_or_add_cb(light_set, [&]() {
104 const uint64_t new_light_set_id = next_light_set_id_++;
107 printf(
"Maximum number of light linking sets (%d) exceeded scene \"%s\".\n",
112 return new_light_set_id;
152 return effective_included_mask & ~excluded_sets_mask;
159 emitter_data_map_.
clear();
160 next_collection_id_ = 0;
167 const Collection *collection = get_collection(emitter);
180 const uint64_t collection_id = next_collection_id_++;
186 printf(
"Maximum number of light linking collections (%d) exceeded in scene \"%s\".\n",
196 return new_emitter_data;
203 return &emitter_data;
208 const Collection *collection_eval = get_collection(emitter);
210 if (!collection_eval) {
214 const Collection *collection_orig = get_original(collection_eval);
216 return emitter_data_map_.
lookup_ptr(collection_orig);
223 const Collection *collection = get_collection(emitter);
229 return emitter_data_map_.
contains(collection);
236 light_linked_sets_.clear();
237 object_light_sets_.
clear();
244 LightSet &light_set = ensure_light_set_for(
object);
246 switch (link_state) {
263 return light_linked_sets_.lookup_or_add_as(&
object);
266void LinkingData::clear_after_build()
268 light_linked_sets_.clear_and_shrink();
273 LightSetIDManager light_set_id_manager(scene);
275 for (
const auto it : light_linked_sets_.items()) {
276 const Object *receiver = it.key;
280 if (!light_set_id_manager.get(light_set, light_set_id)) {
286 object_light_sets_.
add(receiver, light_set_id);
288 update_emitters_membership(emitter_data_map, light_set, light_set_mask);
294void LinkingData::update_emitters_membership(
EmitterDataMap &emitter_data_map,
298 for (
EmitterData &emitter_data : emitter_data_map.values()) {
312 const Object *object_orig = get_original(&
object);
326static void foreach_light_collection_object_inner(
332 foreach_light_collection_object_inner(
333 collection_light_linking, *collection_child->collection,
callback);
337 callback(collection_light_linking, *collection_object->ob);
350static void foreach_light_collection_object(
const Collection &collection, Proc &&
callback)
353 foreach_light_collection_object_inner(
354 collection_child->light_linking, *collection_child->collection,
callback);
358 callback(collection_object->light_linking, *collection_object->ob);
366 light_emitter_data_map_.
clear();
367 shadow_emitter_data_map_.
clear();
369 light_linking_.
clear();
370 shadow_linking_.
clear();
377 add_light_linking_emitter(scene, emitter);
378 add_shadow_linking_emitter(scene, emitter);
381void Cache::add_light_linking_emitter(
const Scene &scene,
const Object &emitter)
391 if (light_emitter_data) {
392 foreach_light_collection_object(
395 add_receiver_object(*light_emitter_data, collection_light_linking, receiver);
400void Cache::add_shadow_linking_emitter(
const Scene &scene,
const Object &emitter)
410 if (shadow_emitter_data) {
411 foreach_light_collection_object(
414 add_blocker_object(*shadow_emitter_data, collection_light_linking, receiver);
419void Cache::add_receiver_object(
const EmitterData &emitter_data,
429void Cache::add_blocker_object(
const EmitterData &emitter_data,
441 if (!has_light_linking()) {
445 light_linking_.
end_build(scene, light_emitter_data_map_);
446 shadow_linking_.
end_build(scene, shadow_emitter_data_map_);
454 if (!has_light_linking()) {
471 if (light_emitter_data) {
479 if (shadow_emitter_data) {
486 const bool need_runtime = (memcmp(&runtime, &runtime_no_links,
sizeof(runtime)) != 0);
497 else if (need_runtime) {
498 object_eval.
light_linking = MEM_cnew<LightLinking>(__func__);
void BKE_light_linking_free_if_empty(struct Object *object)
#define LISTBASE_FOREACH(type, var, list)
bool DEG_is_original_id(const ID *id)
ID * DEG_get_original_id(ID *id)
Object groups, one object can be in many groups at once.
eCollectionLightLinkingState
@ COLLECTION_LIGHT_LINKING_STATE_EXCLUDE
@ COLLECTION_LIGHT_LINKING_STATE_INCLUDE
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
const Value * lookup_ptr(const Key &key) const
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
Value & lookup_or_add_cb(const Key &key, const CreateValueF &create_value)
bool contains(const Key &key) const
void eval_runtime_data(Object &object_eval) const
void add_emitter(const Scene &scene, const Object &emitter)
void end_build(const Scene &scene)
bool can_skip_emitter(const Object &emitter) const
EmitterData * ensure_data_if_possible(const Scene &scene, const Object &emitter)
const EmitterData * get_data(const Object &emitter) const
static constexpr int MAX_COLLECTION_ID
EmitterSetMembership light_membership
EmitterSetMembership shadow_membership
uint64_t get_mask() const
static constexpr uint64_t SET_MEMBERSHIP_ALL
uint64_t included_sets_mask
uint64_t excluded_sets_mask
uint64_t include_collection_mask
static constexpr int MAX_ID
bool operator==(const LightSet &other) const
uint64_t exclude_collection_mask
static constexpr int DEFAULT_ID
uint64_t get_light_set_for(const Object &object) const
void end_build(const Scene &scene, EmitterDataMap &emitter_data_map)
void link_object(const EmitterData &emitter_data, eCollectionLightLinkingState link_state, const Object &object)
const Depsgraph * depsgraph
DEGForeachIDComponentCallback callback
void eval_runtime_data(const ::Depsgraph *depsgraph, Object &object_eval)
internal::EmitterData EmitterData
uint64_t get_default_hash(const T &v)
unsigned __int64 uint64_t
uint8_t blocker_shadow_set
uint8_t receiver_light_set
uint64_t light_set_membership
uint64_t shadow_set_membership
struct Collection * blocker_collection
LightLinkingRuntime runtime
struct Collection * receiver_collection
LightLinking * light_linking
light_linking::Cache light_linking_cache