forked from blender/blender
Implement instancing for light objects #35
@ -115,6 +115,10 @@ bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
|
|||||||
if (id == world_prim_id()) {
|
if (id == world_prim_id()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
InstancerData *i_data = instancer_data(id, true);
|
||||||
|
if (i_data) {
|
||||||
|
return i_data->visible;
|
||||||
|
}
|
||||||
return object_data(id)->visible;
|
return object_data(id)->visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ bool InstancerData::is_supported(Object *object)
|
|||||||
case OB_FONT:
|
case OB_FONT:
|
||||||
case OB_CURVES_LEGACY:
|
case OB_CURVES_LEGACY:
|
||||||
case OB_MBALL:
|
case OB_MBALL:
|
||||||
|
case OB_LAMP:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -58,9 +59,14 @@ void InstancerData::remove()
|
|||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
it.second.obj_data->remove();
|
it.second.data->remove();
|
||||||
}
|
}
|
||||||
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
||||||
|
|
||||||
|
for (auto &it : light_instances_) {
|
||||||
|
it.second.transforms.clear();
|
||||||
|
update_light_instance(it.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::update()
|
void InstancerData::update()
|
||||||
@ -100,9 +106,9 @@ bool InstancerData::update_visibility()
|
|||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
it.second.obj_data->visible = visible;
|
it.second.data->visible = visible;
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
|
||||||
it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -110,6 +116,14 @@ bool InstancerData::update_visibility()
|
|||||||
|
|
||||||
pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
|
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);
|
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);
|
auto m_it = mesh_instances_.find(id);
|
||||||
if (m_it != mesh_instances_.end()) {
|
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);
|
auto l_it = light_instances_.find(id);
|
||||||
if (l_it != light_instances_.end()) {
|
if (l_it != light_instances_.end()) {
|
||||||
@ -158,7 +172,7 @@ void InstancerData::check_update(Object *object)
|
|||||||
if (it == mesh_instances_.end()) {
|
if (it == mesh_instances_.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ObjectData *obj_data = it->second.obj_data.get();
|
ObjectData *obj_data = it->second.data.get();
|
||||||
obj_data->update();
|
obj_data->update();
|
||||||
|
|
||||||
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
|
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()) {
|
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
it->second.obj_data->remove();
|
it->second.data->remove();
|
||||||
mesh_instances_.erase(it);
|
mesh_instances_.erase(it);
|
||||||
it = mesh_instances_.begin();
|
it = mesh_instances_.begin();
|
||||||
ret = true;
|
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
|
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
|
||||||
{
|
{
|
||||||
for (auto &it : mesh_instances_) {
|
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()) {
|
if (!mat_id.IsEmpty()) {
|
||||||
paths.insert(mat_id);
|
paths.insert(mat_id);
|
||||||
}
|
}
|
||||||
@ -253,12 +267,14 @@ void InstancerData::set_instances()
|
|||||||
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];
|
||||||
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 {
|
else {
|
||||||
inst = &it->second;
|
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());
|
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));
|
||||||
}
|
}
|
||||||
@ -270,7 +286,7 @@ void InstancerData::set_instances()
|
|||||||
if (!it->second.indices.empty()) {
|
if (!it->second.indices.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
it->second.obj_data->remove();
|
it->second.data->remove();
|
||||||
mesh_instances_.erase(it);
|
mesh_instances_.erase(it);
|
||||||
it = mesh_instances_.begin();
|
it = mesh_instances_.begin();
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace blender::render::hydra {
|
|||||||
|
|
||||||
class InstancerData : public ObjectData {
|
class InstancerData : public ObjectData {
|
||||||
struct MeshInstance {
|
struct MeshInstance {
|
||||||
std::unique_ptr<ObjectData> obj_data;
|
std::unique_ptr<MeshData> data;
|
||||||
pxr::VtIntArray indices;
|
pxr::VtIntArray indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user