forked from blender/blender
Implement instancing for light objects #35
@ -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
|
||||||
|
@ -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_;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user