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