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 31 additions and 11 deletions
Showing only changes of commit 278f4d7175 - Show all commits

View File

@ -115,6 +115,10 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
if (id == world_prim_id()) {
return true;
}
InstancerData *i_data = instancer_data(id, true);
if (i_data) {
return i_data->visible;
}
return object_data(id)->visible;
}

View File

@ -34,6 +34,7 @@ bool InstancerData::is_supported(Object *object)
case OB_FONT:
case OB_CURVES_LEGACY:
case OB_MBALL:
case OB_LAMP:
return true;
default:
@ -58,9 +59,14 @@ void InstancerData::remove()
{
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
for (auto &it : mesh_instances_) {
it.second.obj_data->remove();
it.second.data->remove();
}
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
for (auto &it : light_instances_) {
it.second.transforms.clear();
update_light_instance(it.second);
}
}
void InstancerData::update()
@ -100,9 +106,9 @@ bool InstancerData::update_visibility()
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
prim_id, pxr::HdChangeTracker::DirtyVisibility);
for (auto &it : mesh_instances_) {
it.second.obj_data->visible = visible;
it.second.data->visible = visible;
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
}
}
return ret;
@ -110,6 +116,14 @@ bool InstancerData::update_visibility()
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 pxr::GfMatrix4d(1.0);
}
@ -133,7 +147,7 @@ ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
{
auto m_it = mesh_instances_.find(id);
if (m_it != mesh_instances_.end()) {
return m_it->second.obj_data.get();
return m_it->second.data.get();
}
auto l_it = light_instances_.find(id);
if (l_it != light_instances_.end()) {
@ -158,7 +172,7 @@ void InstancerData::check_update(Object *object)
if (it == mesh_instances_.end()) {
return;
}
ObjectData *obj_data = it->second.obj_data.get();
ObjectData *obj_data = it->second.data.get();
obj_data->update();
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
@ -178,7 +192,7 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
continue;
}
it->second.obj_data->remove();
it->second.data->remove();
mesh_instances_.erase(it);
it = mesh_instances_.begin();
ret = true;
@ -193,7 +207,7 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
{
for (auto &it : mesh_instances_) {
pxr::SdfPath mat_id = ((MeshData *)it.second.obj_data.get())->material_id();
pxr::SdfPath mat_id = ((MeshData *)it.second.data.get())->material_id();
if (!mat_id.IsEmpty()) {
paths.insert(mat_id);
}
@ -253,12 +267,14 @@ void InstancerData::set_instances()
auto it = mesh_instances_.find(p_id);
if (it == mesh_instances_.end()) {
inst = &mesh_instances_[p_id];
inst->obj_data = ObjectData::create(scene_delegate_, ob, p_id);
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
inst->data->init();
inst->data->insert();
}
else {
inst = &it->second;
}
ID_LOG(2, "Mesh %s %d", inst->obj_data->id->name, mesh_transforms_.size());
ID_LOG(2, "Mesh %s %d", inst->data->id->name, mesh_transforms_.size());
inst->indices.push_back(mesh_transforms_.size());
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
}
@ -270,7 +286,7 @@ void InstancerData::set_instances()
if (!it->second.indices.empty()) {
continue;
}
it->second.obj_data->remove();
it->second.data->remove();
mesh_instances_.erase(it);
it = mesh_instances_.begin();
}

View File

@ -12,7 +12,7 @@ namespace blender::render::hydra {
class InstancerData : public ObjectData {
struct MeshInstance {
std::unique_ptr<ObjectData> obj_data;
std::unique_ptr<MeshData> data;
pxr::VtIntArray indices;
};