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

View File

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