forked from blender/blender
Implement instancing for light objects #35
@ -103,12 +103,18 @@ bool InstancerData::update_visibility()
|
||||
{
|
||||
bool ret = ObjectData::update_visibility();
|
||||
if (ret) {
|
||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||
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;
|
||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
|
||||
it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||
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;
|
||||
@ -118,12 +124,10 @@ pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
|
||||
{
|
||||
if (id.GetPathElementCount() == 4) {
|
||||
const auto &inst = light_instances_.find(id.GetParentPath())->second;
|
||||
std::string name = id.GetName();
|
||||
int index;
|
||||
sscanf_s(name.c_str(), "L_%x", &index);
|
||||
return inst.transforms[index];
|
||||
return inst.transforms[light_prim_id_index(id)];
|
||||
}
|
||||
|
||||
/* Mesh instance transform must be identity */
|
||||
return pxr::GfMatrix4d(1.0);
|
||||
}
|
||||
|
||||
@ -306,15 +310,13 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
||||
auto &render_index = scene_delegate_->GetRenderIndex();
|
||||
LightData &l_data = *inst.data;
|
||||
|
||||
char name[16];
|
||||
int i;
|
||||
pxr::SdfPath p;
|
||||
|
||||
/* Remove old light instances */
|
||||
while (inst.count > inst.transforms.size()) {
|
||||
--inst.count;
|
||||
snprintf(name, 16, "L_%08x", inst.count);
|
||||
p = l_data.prim_id.AppendElementString(name);
|
||||
p = light_prim_id(inst, inst.count);
|
||||
render_index.RemoveSprim(l_data.prim_type_, p);
|
||||
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_) {
|
||||
/* Recreate instances when prim_type was changed */
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
snprintf(name, 16, "L_%08x", i);
|
||||
p = l_data.prim_id.AppendElementString(name);
|
||||
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) {
|
||||
snprintf(name, 16, "L_%08x", i);
|
||||
p = l_data.prim_id.AppendElementString(name);
|
||||
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);
|
||||
}
|
||||
@ -344,8 +344,7 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
||||
bits = pxr::HdLight::AllDirty;
|
||||
}
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
snprintf(name, 16, "L_%08x", i);
|
||||
p = l_data.prim_id.AppendElementString(name);
|
||||
p = light_prim_id(inst, i);
|
||||
render_index.GetChangeTracker().MarkSprimDirty(p, bits);
|
||||
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 */
|
||||
while (inst.count < inst.transforms.size()) {
|
||||
snprintf(name, 16, "L_%08x", inst.count);
|
||||
p = inst.data->prim_id.AppendElementString(name);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -52,6 +52,8 @@ class InstancerData : public ObjectData {
|
||||
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;
|
||||
int light_prim_id_index(pxr::SdfPath const &id) const;
|
||||
|
||||
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
|
||||
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;
|
||||
|
Loading…
Reference in New Issue
Block a user