Implement instancing for light objects #35

Merged
Bogdan Nagirniak merged 18 commits from BLEN-395 into hydra-render 2023-05-04 15:12:27 +02:00
3 changed files with 53 additions and 30 deletions
Showing only changes of commit a0ce1b09dd - Show all commits

View File

@ -172,20 +172,29 @@ pxr::SdfPathVector InstancerData::prototypes() const
void InstancerData::check_update(Object *object) void InstancerData::check_update(Object *object)
{ {
pxr::SdfPath path = object_prim_id(object); pxr::SdfPath path = object_prim_id(object);
auto it = mesh_instances_.find(path); auto m_it = mesh_instances_.find(path);
if (it == mesh_instances_.end()) { if (m_it != mesh_instances_.end()) {
m_it->second.data->update();
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) {
set_instances();
bits |= pxr::HdChangeTracker::DirtyTransform;
}
if (bits != pxr::HdChangeTracker::Clean) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits);
}
return; return;
} }
ObjectData *obj_data = it->second.data.get();
obj_data->update();
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; auto l_it = light_instances_.find(path);
if (object->id.recalc & ID_RECALC_TRANSFORM) { if (l_it != light_instances_.end()) {
set_instances(); Object *obj = (Object *)l_it->second.data->id;
bits |= pxr::HdChangeTracker::DirtyTransform; if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) ||
} ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) {
if (bits != pxr::HdChangeTracker::Clean) { set_instances();
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits); }
return;
} }
} }
@ -206,6 +215,17 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::AllDirty); 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<pxr::SdfPath> &paths) const void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
@ -233,6 +253,20 @@ pxr::SdfPath InstancerData::object_prim_id(Object *object) const
return prim_id.AppendElementString(str); 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() void InstancerData::set_instances()
{ {
mesh_transforms_.clear(); mesh_transforms_.clear();
@ -339,7 +373,8 @@ void InstancerData::update_light_instance(LightInstance &inst)
else { else {
/* Update light instances*/ /* Update light instances*/
pxr::HdDirtyBits bits = pxr::HdLight::DirtyTransform; pxr::HdDirtyBits bits = pxr::HdLight::DirtyTransform;
if (id->recalc & ID_RECALC_GEOMETRY) { Object *obj = (Object *)inst.data->id;
if (obj->id.recalc & ID_RECALC_GEOMETRY || ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) {
l_data.init(); l_data.init();
bits = pxr::HdLight::AllDirty; bits = pxr::HdLight::AllDirty;
} }
@ -359,18 +394,4 @@ void InstancerData::update_light_instance(LightInstance &inst)
} }
} }
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;
}
} // namespace blender::render::hydra } // namespace blender::render::hydra

View File

@ -50,10 +50,10 @@ class InstancerData : public ObjectData {
private: private:
pxr::SdfPath object_prim_id(Object *object) const; pxr::SdfPath object_prim_id(Object *object) const;
void set_instances();
void update_light_instance(LightInstance &inst);
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const; pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
int light_prim_id_index(pxr::SdfPath const &id) const; int light_prim_id_index(pxr::SdfPath const &id) const;
void set_instances();
void update_light_instance(LightInstance &inst);
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_; pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_; pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;

View File

@ -113,7 +113,7 @@ void LightData::update()
} }
pxr::HdDirtyBits bits = pxr::HdLight::Clean; 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(); init();
bits = pxr::HdLight::AllDirty; bits = pxr::HdLight::AllDirty;
} }
@ -121,7 +121,9 @@ void LightData::update()
write_transform(); write_transform();
bits = pxr::HdLight::DirtyTransform; 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 pxr::VtValue LightData::get_data(pxr::TfToken const &key) const