diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc index b1a67394e5e7..840a996fe3bf 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.cc @@ -32,43 +32,42 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); + InstancerData *i_data = instancer_data(id, true); + if (i_data) { + return i_data->get_transform(id); + } ObjectData *obj_data = object_data(id); if (obj_data) { return obj_data->transform; } - if (id == world_prim_id()) { return world_data_->transform; } - return pxr::GfMatrix4d(); } pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText()); - ObjectData *obj_data = object_data(id); if (obj_data) { return obj_data->get_data(key); } - MaterialData *mat_data = material_data(id); if (mat_data) { return mat_data->get_data(key); } - InstancerData *i_data = instancer_data(id); if (i_data) { return i_data->get_data(key); } - return pxr::VtValue(); } pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id, pxr::TfToken const &key) { + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText()); LightData *l_data = light_data(id); if (l_data) { return l_data->get_data(key); @@ -83,27 +82,26 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors( pxr::SdfPath const &id, pxr::HdInterpolation interpolation) { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %d", id.GetText(), interpolation); - MeshData *m_data = mesh_data(id); if (m_data) { return m_data->primvar_descriptors(interpolation); } - InstancerData *i_data = instancer_data(id); if (i_data) { return i_data->primvar_descriptors(interpolation); } - return pxr::HdPrimvarDescriptorVector(); } pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id) { + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText()); return mesh_data(rprim_id)->material_id(); } pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) { + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); MaterialData *mat_data = material_data(id); if (mat_data) { return mat_data->get_material_resource(); @@ -113,10 +111,14 @@ pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id) bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id) { + CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); if (id == world_prim_id()) { return true; } - + InstancerData *i_data = instancer_data(id, true); + if (i_data) { + return i_data->visible; + } return object_data(id)->visible; } @@ -175,11 +177,9 @@ void BlenderSceneDelegate::clear() for (auto &it : objects_) { it.second->remove(); } - for (auto &it : instancers_) { it.second->remove(); } - for (auto &it : materials_) { it.second->remove(); } @@ -223,7 +223,7 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const if (it != objects_.end()) { return it->second.get(); } - InstancerData *i_data = instancer_data(id.GetParentPath()); + InstancerData *i_data = instancer_data(id, true); if (i_data) { return i_data->object_data(id); } @@ -249,9 +249,23 @@ MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const return it->second.get(); } -InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) const +InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool child_id) const { - auto it = instancers_.find(id); + pxr::SdfPath p_id; + if (child_id) { + int n = id.GetPathElementCount(); + if (n == 3) { + p_id = id.GetParentPath(); + } + else if (n == 4) { + p_id = id.GetParentPath().GetParentPath(); + } + } + else { + p_id = id; + } + + auto it = instancers_.find(p_id); if (it != instancers_.end()) { return it->second.get(); } @@ -266,6 +280,7 @@ void BlenderSceneDelegate::update_objects(Object *object) pxr::SdfPath id = object_prim_id(object); ObjectData *obj_data = object_data(id); if (obj_data) { + obj_data->update_parent(); obj_data->update(); return; } @@ -274,6 +289,9 @@ void BlenderSceneDelegate::update_objects(Object *object) } objects_[id] = ObjectData::create(this, object, id); obj_data = object_data(id); + obj_data->update_parent(); + obj_data->init(); + obj_data->insert(); obj_data->update_visibility(); } @@ -302,8 +320,10 @@ void BlenderSceneDelegate::update_instancers(Object *object) if (view3d && !BKE_object_is_visible_in_viewport(view3d, object)) { return; } - instancers_[id] = InstancerData::create(this, object, id); + instancers_[id] = std::make_unique(this, object, id); i_data = instancer_data(id); + i_data->init(); + i_data->insert(); i_data->update_visibility(); } @@ -312,7 +332,9 @@ void BlenderSceneDelegate::update_world() World *world = scene->world; if (!world_data_) { if (world) { - world_data_ = WorldData::create(this, world, world_prim_id()); + world_data_ = std::make_unique(this, world, world_prim_id()); + world_data_->init(); + world_data_->insert(); } } else { diff --git a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h index e542a3e7d11b..73cd5f1f1111 100644 --- a/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h +++ b/source/blender/render/hydra/scene_delegate/blender_scene_delegate.h @@ -21,7 +21,8 @@ namespace blender::render::hydra { extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegate */ class BlenderSceneDelegate : public pxr::HdSceneDelegate { - friend MeshData; /* has access to materials and instances */ + friend ObjectData; /* has access to instances */ + friend MeshData; /* has access to materials */ public: enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW }; @@ -70,7 +71,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate { MeshData *mesh_data(pxr::SdfPath const &id) const; LightData *light_data(pxr::SdfPath const &id) const; MaterialData *material_data(pxr::SdfPath const &id) const; - InstancerData *instancer_data(pxr::SdfPath const &id) const; + InstancerData *instancer_data(pxr::SdfPath const &id, bool child_id = false) const; void update_objects(Object *object); void update_instancers(Object *object); diff --git a/source/blender/render/hydra/scene_delegate/instancer.cc b/source/blender/render/hydra/scene_delegate/instancer.cc index d87e5e7a5625..50bc558c20fb 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.cc +++ b/source/blender/render/hydra/scene_delegate/instancer.cc @@ -2,6 +2,7 @@ * Copyright 2011-2022 Blender Foundation */ #include +#include #include "blender_scene_delegate.h" #include "instancer.h" @@ -15,16 +16,6 @@ InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate, { } -std::unique_ptr InstancerData::create(BlenderSceneDelegate *scene_delegate, - Object *object, - pxr::SdfPath const &prim_id) -{ - auto data = std::make_unique(scene_delegate, object, prim_id); - data->init(); - data->insert(); - return data; -} - bool InstancerData::is_supported(Object *object) { switch (object->type) { @@ -33,6 +24,7 @@ bool InstancerData::is_supported(Object *object) case OB_FONT: case OB_CURVES_LEGACY: case OB_MBALL: + case OB_LAMP: return true; default: @@ -56,29 +48,27 @@ void InstancerData::insert() void InstancerData::remove() { CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText()); - for (auto &it : instances_) { - it.second.obj_data->remove(); + for (auto &it : mesh_instances_) { + it.second.data->remove(); } scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id); + + for (auto &it : light_instances_) { + it.second.transforms.clear(); + update_light_instance(it.second); + } } void InstancerData::update() { ID_LOG(2, ""); - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; - Object *object = (Object *)id; - if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { + if (id->recalc & ID_RECALC_GEOMETRY || ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY || + id->recalc & ID_RECALC_TRANSFORM) { set_instances(); - bits |= pxr::HdChangeTracker::AllDirty; - } - else if (id->recalc & ID_RECALC_TRANSFORM) { - set_instances(); - bits |= pxr::HdChangeTracker::DirtyTransform; - } - if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( + prim_id, pxr::HdChangeTracker::AllDirty); } } @@ -87,7 +77,7 @@ pxr::VtValue InstancerData::get_data(pxr::TfToken const &key) const ID_LOG(3, "%s", key.GetText()); pxr::VtValue ret; if (key == pxr::HdInstancerTokens->instanceTransform) { - ret = transforms_; + ret = mesh_transforms_; } return ret; } @@ -96,17 +86,36 @@ bool InstancerData::update_visibility() { bool ret = ObjectData::update_visibility(); if (ret) { - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( - prim_id, pxr::HdChangeTracker::DirtyVisibility); - for (auto &it : instances_) { - it.second.obj_data->visible = visible; - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( - it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility); + auto &change_tracker = scene_delegate_->GetRenderIndex().GetChangeTracker(); + change_tracker.MarkInstancerDirty(prim_id, pxr::HdChangeTracker::DirtyVisibility); + for (auto &it : mesh_instances_) { + it.second.data->visible = visible; + change_tracker.MarkRprimDirty(it.second.data->prim_id, + pxr::HdChangeTracker::DirtyVisibility); + } + char name[16]; + for (auto &it : light_instances_) { + for (int i = 0; i < it.second.count; ++i) { + snprintf(name, 16, "L_%08x", i); + change_tracker.MarkRprimDirty(it.second.data->prim_id.AppendElementString(name), + pxr::HdChangeTracker::DirtyVisibility); + } } } return ret; } +pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const +{ + if (id.GetPathElementCount() == 4) { + const auto &inst = light_instances_.find(id.GetParentPath())->second; + return inst.transforms[light_prim_id_index(id)]; + } + + /* Mesh instance transform must be identity */ + return pxr::GfMatrix4d(1.0); +} + pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::HdInterpolation interpolation) const { @@ -120,18 +129,26 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const { - return instances_.find(id)->second.indices; + return mesh_instances_.find(id)->second.indices; } ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const { - return instances_.find(id)->second.obj_data.get(); + auto m_it = mesh_instances_.find(id); + if (m_it != mesh_instances_.end()) { + return m_it->second.data.get(); + } + auto l_it = light_instances_.find(id.GetParentPath()); + if (l_it != light_instances_.end()) { + return l_it->second.data.get(); + } + return nullptr; } pxr::SdfPathVector InstancerData::prototypes() const { pxr::SdfPathVector paths; - for (auto &it : instances_) { + for (auto &it : mesh_instances_) { paths.push_back(it.first); } return paths; @@ -140,34 +157,39 @@ pxr::SdfPathVector InstancerData::prototypes() const void InstancerData::check_update(Object *object) { pxr::SdfPath path = object_prim_id(object); - auto it = instances_.find(path); - if (it == instances_.end()) { + auto m_it = mesh_instances_.find(path); + if (m_it != mesh_instances_.end()) { + m_it->second.data->update(); + + if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) { + set_instances(); + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( + prim_id, pxr::HdChangeTracker::AllDirty); + } return; } - ObjectData *obj_data = it->second.obj_data.get(); - obj_data->update(); - obj_data->transform = pxr::GfMatrix4d(1.0); - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; - if (object->id.recalc & ID_RECALC_TRANSFORM) { - set_instances(); - bits |= pxr::HdChangeTracker::DirtyTransform; - } - if (bits != pxr::HdChangeTracker::Clean) { - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits); + auto l_it = light_instances_.find(path); + if (l_it != light_instances_.end()) { + Object *obj = (Object *)l_it->second.data->id; + if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) || + ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) { + set_instances(); + } + return; } } void InstancerData::check_remove(std::set &available_objects) { bool ret = false; - for (auto it = instances_.begin(); it != instances_.end(); ++it) { + for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) { if (available_objects.find(it->first.GetName()) != available_objects.end()) { continue; } - it->second.obj_data->remove(); - instances_.erase(it); - it = instances_.begin(); + it->second.data->remove(); + mesh_instances_.erase(it); + it = mesh_instances_.begin(); ret = true; } if (ret) { @@ -175,12 +197,23 @@ void InstancerData::check_remove(std::set &available_objects) scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( prim_id, pxr::HdChangeTracker::AllDirty); } + + for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) { + if (available_objects.find(it->first.GetName()) != available_objects.end()) { + continue; + } + it->second.transforms.clear(); + update_light_instance(it->second); + + light_instances_.erase(it); + it = light_instances_.begin(); + } } void InstancerData::available_materials(std::set &paths) const { - for (auto &it : instances_) { - pxr::SdfPath mat_id = ((MeshData *)it.second.obj_data.get())->material_id(); + for (auto &it : mesh_instances_) { + pxr::SdfPath mat_id = ((MeshData *)it.second.data.get())->material_id(); if (!mat_id.IsEmpty()) { paths.insert(mat_id); } @@ -202,49 +235,144 @@ pxr::SdfPath InstancerData::object_prim_id(Object *object) const return prim_id.AppendElementString(str); } +pxr::SdfPath InstancerData::light_prim_id(LightInstance const &inst, int index) const +{ + char name[16]; + snprintf(name, 16, "L_%08x", index); + return inst.data->prim_id.AppendElementString(name); +} + +int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const +{ + int index; + sscanf_s(id.GetName().c_str(), "L_%x", &index); + return index; +} + void InstancerData::set_instances() { - transforms_.clear(); - for (auto &it : instances_) { + mesh_transforms_.clear(); + for (auto &it : mesh_instances_) { it.second.indices.clear(); } - int index = 0; - Instance *inst; - pxr::SdfPath p_id; + for (auto &it : light_instances_) { + it.second.transforms.clear(); + } ListBase *lb = object_duplilist( scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id); LISTBASE_FOREACH (DupliObject *, dupli, lb) { - p_id = object_prim_id(dupli->ob); - auto it = instances_.find(p_id); - if (it == instances_.end()) { - inst = &instances_[p_id]; - if (!is_supported(dupli->ob)) { - continue; - } - inst->obj_data = ObjectData::create(scene_delegate_, dupli->ob, p_id); + Object *ob = dupli->ob; + if (!is_supported(ob)) { + continue; + } - /* Instance's transform should be identity */ - inst->obj_data->transform = pxr::GfMatrix4d(1.0); + pxr::SdfPath p_id = object_prim_id(ob); + if (ob->type == OB_LAMP) { + LightInstance *inst; + auto it = light_instances_.find(p_id); + if (it == light_instances_.end()) { + inst = &light_instances_[p_id]; + inst->data = std::make_unique(scene_delegate_, ob, p_id); + inst->data->init(); + } + else { + inst = &it->second; + } + ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size()); + inst->transforms.push_back(gf_matrix_from_transform(dupli->mat)); } else { - inst = &it->second; + MeshInstance *inst; + auto it = mesh_instances_.find(p_id); + if (it == mesh_instances_.end()) { + inst = &mesh_instances_[p_id]; + inst->data = std::make_unique(scene_delegate_, ob, p_id); + inst->data->init(); + inst->data->insert(); + } + else { + inst = &it->second; + } + ID_LOG(2, "Mesh %s %d", inst->data->id->name, mesh_transforms_.size()); + inst->indices.push_back(mesh_transforms_.size()); + mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); } - transforms_.push_back(gf_matrix_from_transform(dupli->mat)); - inst->indices.push_back(index); - ID_LOG(2, "%s %d", inst->obj_data->id->name, index); - ++index; } free_object_duplilist(lb); - /* Remove intances without indices */ - for (auto it = instances_.begin(); it != instances_.end(); ++it) { + /* Remove mesh intances without indices */ + for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) { if (!it->second.indices.empty()) { continue; } - it->second.obj_data->remove(); - instances_.erase(it); - it = instances_.begin(); + it->second.data->remove(); + mesh_instances_.erase(it); + it = mesh_instances_.begin(); + } + + /* Update light intances and remove instances without transforms */ + for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) { + update_light_instance(it->second); + if (it->second.transforms.empty()) { + light_instances_.erase(it); + it = light_instances_.begin(); + } + } +} + +void InstancerData::update_light_instance(LightInstance &inst) +{ + auto &render_index = scene_delegate_->GetRenderIndex(); + LightData &l_data = *inst.data; + + int i; + pxr::SdfPath p; + + /* Remove old light instances */ + while (inst.count > inst.transforms.size()) { + --inst.count; + p = light_prim_id(inst, inst.count); + render_index.RemoveSprim(l_data.prim_type_, p); + ID_LOG(2, "Remove %s", p.GetText()); + } + + /* Update current light instances */ + if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) { + /* Recreate instances when prim_type was changed */ + for (i = 0; i < inst.count; ++i) { + p = light_prim_id(inst, i); + render_index.RemoveSprim(l_data.prim_type_, p); + ID_LOG(2, "Remove %s", p.GetText()); + } + inst.data->init(); + for (i = 0; i < inst.count; ++i) { + p = light_prim_id(inst, i); + render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); + ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); + } + } + else { + /* Update light instances*/ + pxr::HdDirtyBits bits = pxr::HdLight::DirtyTransform; + Object *obj = (Object *)inst.data->id; + if (obj->id.recalc & ID_RECALC_GEOMETRY || ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) { + l_data.init(); + bits = pxr::HdLight::AllDirty; + } + for (i = 0; i < inst.count; ++i) { + p = light_prim_id(inst, i); + render_index.GetChangeTracker().MarkSprimDirty(p, bits); + ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name); + } + } + + /* Add new light instances */ + while (inst.count < inst.transforms.size()) { + p = light_prim_id(inst, inst.count); + render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); + ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); + ++inst.count; } } diff --git a/source/blender/render/hydra/scene_delegate/instancer.h b/source/blender/render/hydra/scene_delegate/instancer.h index 02affd283958..cb9410768431 100644 --- a/source/blender/render/hydra/scene_delegate/instancer.h +++ b/source/blender/render/hydra/scene_delegate/instancer.h @@ -5,22 +5,25 @@ #include "BKE_duplilist.h" +#include "light.h" #include "mesh.h" namespace blender::render::hydra { class InstancerData : public ObjectData { - struct Instance { - std::unique_ptr obj_data; + struct MeshInstance { + std::unique_ptr data; pxr::VtIntArray indices; }; + struct LightInstance { + std::unique_ptr data; + pxr::VtMatrix4dArray transforms; + int count = 0; + }; + public: InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); - - static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, - Object *object, - pxr::SdfPath const &prim_id); static bool is_supported(Object *object); void init() override; @@ -31,6 +34,7 @@ class InstancerData : public ObjectData { pxr::VtValue get_data(pxr::TfToken const &key) const override; bool update_visibility() override; + pxr::GfMatrix4d get_transform(pxr::SdfPath const &id) const; pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const; pxr::VtIntArray indices(pxr::SdfPath const &id) const; ObjectData *object_data(pxr::SdfPath const &id) const; @@ -42,10 +46,14 @@ class InstancerData : public ObjectData { private: pxr::SdfPath object_prim_id(Object *object) const; + pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const; + int light_prim_id_index(pxr::SdfPath const &id) const; void set_instances(); + void update_light_instance(LightInstance &inst); - pxr::TfHashMap instances_; - pxr::VtMatrix4dArray transforms_; + pxr::TfHashMap mesh_instances_; + pxr::TfHashMap light_instances_; + pxr::VtMatrix4dArray mesh_transforms_; }; using InstancerDataMap = diff --git a/source/blender/render/hydra/scene_delegate/light.cc b/source/blender/render/hydra/scene_delegate/light.cc index ab4642f86389..22d4657cc658 100644 --- a/source/blender/render/hydra/scene_delegate/light.cc +++ b/source/blender/render/hydra/scene_delegate/light.cc @@ -104,7 +104,8 @@ void LightData::update() { ID_LOG(2, ""); - Light *light = (Light *)((Object *)id)->data; + Object *object = (Object *)id; + Light *light = (Light *)object->data; if (prim_type(light) != prim_type_) { remove(); init(); @@ -113,7 +114,7 @@ void LightData::update() } pxr::HdDirtyBits bits = pxr::HdLight::Clean; - if (id->recalc & ID_RECALC_GEOMETRY) { + if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY) { init(); bits = pxr::HdLight::AllDirty; } @@ -121,7 +122,9 @@ void LightData::update() write_transform(); bits = pxr::HdLight::DirtyTransform; } - scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits); + if (bits != pxr::HdChangeTracker::Clean) { + scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits); + } } pxr::VtValue LightData::get_data(pxr::TfToken const &key) const diff --git a/source/blender/render/hydra/scene_delegate/light.h b/source/blender/render/hydra/scene_delegate/light.h index 003f23997783..215b82c773c9 100644 --- a/source/blender/render/hydra/scene_delegate/light.h +++ b/source/blender/render/hydra/scene_delegate/light.h @@ -13,7 +13,11 @@ namespace blender::render::hydra { +class InstancerData; + class LightData : public ObjectData { + friend InstancerData; + public: LightData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id); diff --git a/source/blender/render/hydra/scene_delegate/material.cc b/source/blender/render/hydra/scene_delegate/material.cc index 380d9826d352..9033c25cfea5 100644 --- a/source/blender/render/hydra/scene_delegate/material.cc +++ b/source/blender/render/hydra/scene_delegate/material.cc @@ -27,16 +27,6 @@ MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate, { } -std::unique_ptr MaterialData::create(BlenderSceneDelegate *scene_delegate, - Material *material, - pxr::SdfPath const &prim_id) -{ - auto data = std::make_unique(scene_delegate, material, prim_id); - data->init(); - data->insert(); - return data; -} - void MaterialData::init() { ID_LOG(2, ""); diff --git a/source/blender/render/hydra/scene_delegate/material.h b/source/blender/render/hydra/scene_delegate/material.h index 2f6371cd3438..985e95acb786 100644 --- a/source/blender/render/hydra/scene_delegate/material.h +++ b/source/blender/render/hydra/scene_delegate/material.h @@ -19,10 +19,6 @@ class MaterialData : public IdData { Material *material, pxr::SdfPath const &prim_id); - static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, - Material *material, - pxr::SdfPath const &prim_id); - void init() override; void insert() override; void remove() override; diff --git a/source/blender/render/hydra/scene_delegate/mesh.cc b/source/blender/render/hydra/scene_delegate/mesh.cc index 7c9063288668..be5636d08888 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.cc +++ b/source/blender/render/hydra/scene_delegate/mesh.cc @@ -17,7 +17,7 @@ namespace blender::render::hydra { MeshData::MeshData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : ObjectData(scene_delegate, object, prim_id), parent_(object->parent) + : ObjectData(scene_delegate, object, prim_id) { } @@ -66,20 +66,6 @@ void MeshData::remove() void MeshData::update() { Object *object = (Object *)id; - if (parent_ != object->parent) { - parent_ = object->parent; - - /* Looking for corresponded instancer and update it as parent */ - for (Object *ob = parent_; ob != nullptr; ob = ob->parent) { - pxr::SdfPath i_id = scene_delegate_->instancer_prim_id(ob); - InstancerData *i_data = scene_delegate_->instancer_data(i_id); - if (i_data) { - i_data->update_as_parent(); - break; - } - } - } - pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) { init(); @@ -126,9 +112,6 @@ pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const else if (key == pxr::HdPrimvarRoleTokens->textureCoordinate) { ret = uvs_; } - else if (key == pxr::HdInstancerTokens->instanceTransform) { - ret = instances_; - } return ret; } @@ -235,8 +218,10 @@ void MeshData::write_material() pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat); mat_data_ = scene_delegate_->material_data(p_id); if (!mat_data_) { - scene_delegate_->materials_[p_id] = MaterialData::create(scene_delegate_, mat, p_id); + scene_delegate_->materials_[p_id] = std::make_unique(scene_delegate_, mat, p_id); mat_data_ = scene_delegate_->material_data(p_id); + mat_data_->init(); + mat_data_->insert(); } } diff --git a/source/blender/render/hydra/scene_delegate/mesh.h b/source/blender/render/hydra/scene_delegate/mesh.h index 8d551a14f119..da62c1f70003 100644 --- a/source/blender/render/hydra/scene_delegate/mesh.h +++ b/source/blender/render/hydra/scene_delegate/mesh.h @@ -40,10 +40,8 @@ class MeshData : public ObjectData { pxr::VtVec3fArray vertices_; pxr::VtVec2fArray uvs_; pxr::VtVec3fArray normals_; - pxr::VtMatrix4dArray instances_; MaterialData *mat_data_ = nullptr; - Object *parent_; }; } // namespace blender::render::hydra diff --git a/source/blender/render/hydra/scene_delegate/object.cc b/source/blender/render/hydra/scene_delegate/object.cc index 658960dcdce5..3e750df0c72b 100644 --- a/source/blender/render/hydra/scene_delegate/object.cc +++ b/source/blender/render/hydra/scene_delegate/object.cc @@ -13,7 +13,7 @@ namespace blender::render::hydra { ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id) - : IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)), visible(true) + : IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)) { } @@ -39,10 +39,6 @@ std::unique_ptr ObjectData::create(BlenderSceneDelegate *scene_deleg default: break; } - if (data) { - data->init(); - data->insert(); - } return data; } @@ -78,6 +74,25 @@ bool ObjectData::update_visibility() return ret; } +void ObjectData::update_parent() +{ + Object *object = (Object *)id; + if (parent_ != object->parent) { + ID_LOG(2, ""); + parent_ = object->parent; + + /* Looking for corresponded instancer and update it as parent */ + for (Object *ob = parent_; ob != nullptr; ob = ob->parent) { + InstancerData *i_data = scene_delegate_->instancer_data( + scene_delegate_->instancer_prim_id(ob)); + if (i_data) { + i_data->update_as_parent(); + break; + } + } + } +} + void ObjectData::write_transform() { transform = gf_matrix_from_transform(((Object *)id)->object_to_world); diff --git a/source/blender/render/hydra/scene_delegate/object.h b/source/blender/render/hydra/scene_delegate/object.h index b0a7371e27a9..b6d5e4e48d5e 100644 --- a/source/blender/render/hydra/scene_delegate/object.h +++ b/source/blender/render/hydra/scene_delegate/object.h @@ -24,12 +24,15 @@ class ObjectData : public IdData { static bool is_supported(Object *object); virtual bool update_visibility(); + void update_parent(); pxr::GfMatrix4d transform; - bool visible; + bool visible = true; protected: void write_transform(); + + Object *parent_ = nullptr; }; using ObjectDataMap = diff --git a/source/blender/render/hydra/scene_delegate/world.cc b/source/blender/render/hydra/scene_delegate/world.cc index 3fca6378aae1..184555ff0a3b 100644 --- a/source/blender/render/hydra/scene_delegate/world.cc +++ b/source/blender/render/hydra/scene_delegate/world.cc @@ -34,16 +34,6 @@ WorldData::WorldData(BlenderSceneDelegate *scene_delegate, { } -std::unique_ptr WorldData::create(BlenderSceneDelegate *scene_delegate, - World *world, - pxr::SdfPath const &prim_id) -{ - auto data = std::make_unique(scene_delegate, world, prim_id); - data->init(); - data->insert(); - return data; -} - void WorldData::init() { ID_LOG(2, ""); diff --git a/source/blender/render/hydra/scene_delegate/world.h b/source/blender/render/hydra/scene_delegate/world.h index 083e0daff78a..2eb62555c555 100644 --- a/source/blender/render/hydra/scene_delegate/world.h +++ b/source/blender/render/hydra/scene_delegate/world.h @@ -22,10 +22,6 @@ class WorldData : public IdData { public: WorldData(BlenderSceneDelegate *scene_delegate, World *world, pxr::SdfPath const &prim_id); - static std::unique_ptr create(BlenderSceneDelegate *scene_delegate, - World *world, - pxr::SdfPath const &prim_id); - void init() override; void insert() override; void remove() override;