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
4 changed files with 47 additions and 11 deletions
Showing only changes of commit 33efcca4f6 - Show all commits

View File

@ -32,6 +32,12 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id) pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
{ {
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText()); CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
pxr::SdfPath i_id = instancer_prim_id(id);
if (!i_id.IsEmpty()) {
InstancerData *i_data = instancer_data(i_id);
return i_data->get_transform(id);
}
ObjectData *obj_data = object_data(id); ObjectData *obj_data = object_data(id);
if (obj_data) { if (obj_data) {
return obj_data->transform; return obj_data->transform;
@ -212,6 +218,18 @@ pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(Object *object) const
return prim_id((ID *)object, "I"); return prim_id((ID *)object, "I");
} }
pxr::SdfPath BlenderSceneDelegate::instancer_prim_id(pxr::SdfPath const &child_id) const
{
int n = child_id.GetPathElementCount();
if (n == 3) {
return child_id.GetParentPath();
}
if (n == 4) {
return child_id.GetParentPath().GetParentPath();
}
return pxr::SdfPath();
}
pxr::SdfPath BlenderSceneDelegate::world_prim_id() const pxr::SdfPath BlenderSceneDelegate::world_prim_id() const
{ {
return GetDelegateID().AppendElementString("World"); return GetDelegateID().AppendElementString("World");

View File

@ -64,6 +64,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
pxr::SdfPath object_prim_id(Object *object) const; pxr::SdfPath object_prim_id(Object *object) const;
pxr::SdfPath material_prim_id(Material *mat) const; pxr::SdfPath material_prim_id(Material *mat) const;
pxr::SdfPath instancer_prim_id(Object *object) const; pxr::SdfPath instancer_prim_id(Object *object) const;
pxr::SdfPath instancer_prim_id(pxr::SdfPath const &child_id) const;
pxr::SdfPath world_prim_id() const; pxr::SdfPath world_prim_id() const;
ObjectData *object_data(pxr::SdfPath const &id) const; ObjectData *object_data(pxr::SdfPath const &id) const;

View File

@ -107,6 +107,11 @@ bool InstancerData::update_visibility()
return ret; return ret;
} }
pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
{
return pxr::GfMatrix4d(1.0);
}
pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors( pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
pxr::HdInterpolation interpolation) const pxr::HdInterpolation interpolation) const
{ {
@ -146,7 +151,6 @@ void InstancerData::check_update(Object *object)
} }
ObjectData *obj_data = it->second.obj_data.get(); ObjectData *obj_data = it->second.obj_data.get();
obj_data->update(); obj_data->update();
obj_data->transform = pxr::GfMatrix4d(1.0);
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean; pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
if (object->id.recalc & ID_RECALC_TRANSFORM) { if (object->id.recalc & ID_RECALC_TRANSFORM) {
@ -211,25 +215,37 @@ void InstancerData::set_instances()
int index = 0; int index = 0;
Instance *inst; Instance *inst;
pxr::SdfPath p_id; pxr::SdfPath p_id;
Object *ob;
ListBase *lb = object_duplilist( ListBase *lb = object_duplilist(
scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id); scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id);
LISTBASE_FOREACH (DupliObject *, dupli, lb) { LISTBASE_FOREACH (DupliObject *, dupli, lb) {
ob = dupli->ob;
if (!is_supported(ob)) {
continue;
}
p_id = object_prim_id(dupli->ob); p_id = object_prim_id(dupli->ob);
if (ob->type == OB_LAMP) {
auto it = mesh_instances_.find(p_id); auto it = mesh_instances_.find(p_id);
if (it == mesh_instances_.end()) { if (it == mesh_instances_.end()) {
inst = &mesh_instances_[p_id]; inst = &mesh_instances_[p_id];
if (!is_supported(dupli->ob)) { inst->obj_data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
continue; inst->obj_data->init();
}
inst->obj_data = ObjectData::create(scene_delegate_, dupli->ob, p_id);
/* Instance's transform should be identity */
inst->obj_data->transform = pxr::GfMatrix4d(1.0);
} }
else { else {
inst = &it->second; inst = &it->second;
} }
}
else {
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);
}
else {
inst = &it->second;
}
}
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat)); mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
inst->indices.push_back(index); inst->indices.push_back(index);
ID_LOG(2, "%s %d", inst->obj_data->id->name, index); ID_LOG(2, "%s %d", inst->obj_data->id->name, index);

View File

@ -31,6 +31,7 @@ class InstancerData : public ObjectData {
pxr::VtValue get_data(pxr::TfToken const &key) const override; pxr::VtValue get_data(pxr::TfToken const &key) const override;
bool update_visibility() override; bool update_visibility() override;
pxr::GfMatrix4d get_transform(pxr::SdfPath const &id) const;
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const; pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
pxr::VtIntArray indices(pxr::SdfPath const &id) const; pxr::VtIntArray indices(pxr::SdfPath const &id) const;
ObjectData *object_data(pxr::SdfPath const &id) const; ObjectData *object_data(pxr::SdfPath const &id) const;