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
2 changed files with 33 additions and 19 deletions
Showing only changes of commit 18fafb9f42 - Show all commits

View File

@ -103,12 +103,18 @@ bool InstancerData::update_visibility()
{ {
bool ret = ObjectData::update_visibility(); bool ret = ObjectData::update_visibility();
if (ret) { if (ret) {
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty( auto &change_tracker = scene_delegate_->GetRenderIndex().GetChangeTracker();
prim_id, pxr::HdChangeTracker::DirtyVisibility); change_tracker.MarkInstancerDirty(prim_id, pxr::HdChangeTracker::DirtyVisibility);
for (auto &it : mesh_instances_) { for (auto &it : mesh_instances_) {
it.second.data->visible = visible; it.second.data->visible = visible;
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty( change_tracker.MarkRprimDirty(it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
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; return ret;
@ -118,12 +124,10 @@ pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
{ {
if (id.GetPathElementCount() == 4) { if (id.GetPathElementCount() == 4) {
const auto &inst = light_instances_.find(id.GetParentPath())->second; const auto &inst = light_instances_.find(id.GetParentPath())->second;
std::string name = id.GetName(); return inst.transforms[light_prim_id_index(id)];
int index;
sscanf_s(name.c_str(), "L_%x", &index);
return inst.transforms[index];
} }
/* Mesh instance transform must be identity */
return pxr::GfMatrix4d(1.0); return pxr::GfMatrix4d(1.0);
} }
@ -306,15 +310,13 @@ void InstancerData::update_light_instance(LightInstance &inst)
auto &render_index = scene_delegate_->GetRenderIndex(); auto &render_index = scene_delegate_->GetRenderIndex();
LightData &l_data = *inst.data; LightData &l_data = *inst.data;
char name[16];
int i; int i;
pxr::SdfPath p; pxr::SdfPath p;
/* Remove old light instances */ /* Remove old light instances */
while (inst.count > inst.transforms.size()) { while (inst.count > inst.transforms.size()) {
--inst.count; --inst.count;
snprintf(name, 16, "L_%08x", inst.count); p = light_prim_id(inst, inst.count);
p = l_data.prim_id.AppendElementString(name);
render_index.RemoveSprim(l_data.prim_type_, p); render_index.RemoveSprim(l_data.prim_type_, p);
ID_LOG(2, "Remove %s", p.GetText()); ID_LOG(2, "Remove %s", p.GetText());
} }
@ -323,15 +325,13 @@ void InstancerData::update_light_instance(LightInstance &inst)
if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) { if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) {
/* Recreate instances when prim_type was changed */ /* Recreate instances when prim_type was changed */
for (i = 0; i < inst.count; ++i) { for (i = 0; i < inst.count; ++i) {
snprintf(name, 16, "L_%08x", i); p = light_prim_id(inst, i);
p = l_data.prim_id.AppendElementString(name);
render_index.RemoveSprim(l_data.prim_type_, p); render_index.RemoveSprim(l_data.prim_type_, p);
ID_LOG(2, "Remove %s", p.GetText()); ID_LOG(2, "Remove %s", p.GetText());
} }
inst.data->init(); inst.data->init();
for (i = 0; i < inst.count; ++i) { for (i = 0; i < inst.count; ++i) {
snprintf(name, 16, "L_%08x", i); p = light_prim_id(inst, i);
p = l_data.prim_id.AppendElementString(name);
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
} }
@ -344,8 +344,7 @@ void InstancerData::update_light_instance(LightInstance &inst)
bits = pxr::HdLight::AllDirty; bits = pxr::HdLight::AllDirty;
} }
for (i = 0; i < inst.count; ++i) { for (i = 0; i < inst.count; ++i) {
snprintf(name, 16, "L_%08x", i); p = light_prim_id(inst, i);
p = l_data.prim_id.AppendElementString(name);
render_index.GetChangeTracker().MarkSprimDirty(p, bits); render_index.GetChangeTracker().MarkSprimDirty(p, bits);
ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name); ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name);
} }
@ -353,12 +352,25 @@ void InstancerData::update_light_instance(LightInstance &inst)
/* Add new light instances */ /* Add new light instances */
while (inst.count < inst.transforms.size()) { while (inst.count < inst.transforms.size()) {
snprintf(name, 16, "L_%08x", inst.count); p = light_prim_id(inst, inst.count);
p = inst.data->prim_id.AppendElementString(name);
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p); render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name); ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
++inst.count; ++inst.count;
} }
} }
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

@ -52,6 +52,8 @@ class InstancerData : public ObjectData {
pxr::SdfPath object_prim_id(Object *object) const; pxr::SdfPath object_prim_id(Object *object) const;
void set_instances(); void set_instances();
void update_light_instance(LightInstance &inst); void update_light_instance(LightInstance &inst);
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
int light_prim_id_index(pxr::SdfPath const &id) const;
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_;