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
2 changed files with 42 additions and 18 deletions
Showing only changes of commit 5cbf67c0f8 - Show all commits

View File

@ -8,6 +8,11 @@
namespace blender::render::hydra {
void InstancerData::LightInstance::update()
{
}
InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate,
Object *object,
pxr::SdfPath const &prim_id)
@ -212,34 +217,35 @@ void InstancerData::set_instances()
for (auto &it : mesh_instances_) {
it.second.indices.clear();
}
int mesh_index = 0, light_index = 0;
Instance *inst;
pxr::SdfPath p_id;
Object *ob;
for (auto &it : light_instances_) {
it.second.transforms.clear();
}
ListBase *lb = object_duplilist(
scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id);
LISTBASE_FOREACH (DupliObject *, dupli, lb) {
ob = dupli->ob;
Object *ob = dupli->ob;
if (!is_supported(ob)) {
continue;
}
p_id = object_prim_id(dupli->ob);
pxr::SdfPath p_id = object_prim_id(ob);
if (ob->type == OB_LAMP) {
LightInstance *inst;
auto it = light_instances_.find(p_id);
if (it == light_instances_.end()) {
inst = &light_instances_[p_id];
inst->obj_data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
inst->obj_data->init();
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
inst->data->init();
}
else {
inst = &it->second;
}
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
inst->indices.push_back(mesh_index);
ID_LOG(2, "%s %d", inst->data->id->name, inst->transforms.size());
inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
}
else {
MeshInstance *inst;
auto it = mesh_instances_.find(p_id);
if (it == mesh_instances_.end()) {
inst = &mesh_instances_[p_id];
@ -248,15 +254,14 @@ void InstancerData::set_instances()
else {
inst = &it->second;
}
ID_LOG(2, "%s %d", inst->obj_data->id->name, mesh_transforms_.size());
inst->indices.push_back(mesh_transforms_.size());
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
inst->indices.push_back(mesh_index);
ID_LOG(2, "%s %d", inst->obj_data->id->name, mesh_index);
++mesh_index;
}
}
free_object_duplilist(lb);
/* Remove intances without indices */
/* Remove mesh intances without indices */
for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) {
if (!it->second.indices.empty()) {
continue;
@ -265,6 +270,15 @@ void InstancerData::set_instances()
mesh_instances_.erase(it);
it = mesh_instances_.begin();
}
/* Update light intances and remove instances without transforms */
for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) {
it->second.update();
if (it->second.transforms.empty()) {
light_instances_.erase(it);
it = light_instances_.begin();
}
}
}
} // namespace blender::render::hydra

View File

@ -6,15 +6,26 @@
#include "BKE_duplilist.h"
#include "mesh.h"
#include "light.h"
namespace blender::render::hydra {
class InstancerData : public ObjectData {
struct Instance {
struct MeshInstance {
std::unique_ptr<ObjectData> obj_data;
pxr::VtIntArray indices;
};
struct LightInstance {
std::unique_ptr<LightData> data;
pxr::VtMatrix4dArray transforms;
void update();
private:
int count_ = 0;
};
public:
InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
@ -45,10 +56,9 @@ class InstancerData : public ObjectData {
pxr::SdfPath object_prim_id(Object *object) const;
void set_instances();
pxr::TfHashMap<pxr::SdfPath, Instance, pxr::SdfPath::Hash> mesh_instances_;
pxr::TfHashMap<pxr::SdfPath, Instance, pxr::SdfPath::Hash> light_instances_;
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;
pxr::VtMatrix4dArray mesh_transforms_;
pxr::VtMatrix4dArray light_transforms_;
};
using InstancerDataMap =