forked from blender/blender
Implement instancing for light objects #35
@ -172,21 +172,30 @@ pxr::SdfPathVector InstancerData::prototypes() const
|
||||
void InstancerData::check_update(Object *object)
|
||||
{
|
||||
pxr::SdfPath path = object_prim_id(object);
|
||||
auto it = mesh_instances_.find(path);
|
||||
if (it == mesh_instances_.end()) {
|
||||
return;
|
||||
}
|
||||
ObjectData *obj_data = it->second.data.get();
|
||||
obj_data->update();
|
||||
auto m_it = mesh_instances_.find(path);
|
||||
if (m_it != mesh_instances_.end()) {
|
||||
m_it->second.data->update();
|
||||
|
||||
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
|
||||
if (object->id.recalc & ID_RECALC_TRANSFORM) {
|
||||
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;
|
||||
}
|
||||
|
||||
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<std::string> &available_objects)
|
||||
@ -206,6 +215,17 @@ void InstancerData::check_remove(std::set<std::string> &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<pxr::SdfPath> &paths) const
|
||||
@ -233,6 +253,20 @@ 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()
|
||||
{
|
||||
mesh_transforms_.clear();
|
||||
@ -339,7 +373,8 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
||||
else {
|
||||
/* Update light instances*/
|
||||
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();
|
||||
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
|
||||
|
@ -50,10 +50,10 @@ class InstancerData : public ObjectData {
|
||||
|
||||
private:
|
||||
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;
|
||||
void set_instances();
|
||||
void update_light_instance(LightInstance &inst);
|
||||
|
||||
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
|
||||
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;
|
||||
|
@ -113,7 +113,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 +121,9 @@ void LightData::update()
|
||||
write_transform();
|
||||
bits = pxr::HdLight::DirtyTransform;
|
||||
}
|
||||
if (bits != pxr::HdChangeTracker::Clean) {
|
||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits);
|
||||
}
|
||||
}
|
||||
|
||||
pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
|
||||
|
Loading…
Reference in New Issue
Block a user