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()) {
|
||||
return true;
|
||||
}
|
||||
InstancerData *i_data = instancer_data(id, true);
|
||||
if (i_data) {
|
||||
return i_data->visible;
|
||||
}
|
||||
return object_data(id)->visible;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ bool InstancerData::is_supported(Object *object)
|
||||
case OB_FONT:
|
||||
case OB_CURVES_LEGACY:
|
||||
case OB_MBALL:
|
||||
case OB_LAMP:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@ -58,9 +59,14 @@ void InstancerData::remove()
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
||||
for (auto &it : mesh_instances_) {
|
||||
it.second.obj_data->remove();
|
||||
it.second.data->remove();
|
||||
}
|
||||
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
||||
|
||||
for (auto &it : light_instances_) {
|
||||
it.second.transforms.clear();
|
||||
update_light_instance(it.second);
|
||||
}
|
||||
}
|
||||
|
||||
void InstancerData::update()
|
||||
@ -100,9 +106,9 @@ bool InstancerData::update_visibility()
|
||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||
prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||
for (auto &it : mesh_instances_) {
|
||||
it.second.obj_data->visible = visible;
|
||||
it.second.data->visible = visible;
|
||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
|
||||
it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||
it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -110,6 +116,14 @@ bool InstancerData::update_visibility()
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -133,7 +147,7 @@ ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
||||
{
|
||||
auto m_it = mesh_instances_.find(id);
|
||||
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);
|
||||
if (l_it != light_instances_.end()) {
|
||||
@ -158,7 +172,7 @@ void InstancerData::check_update(Object *object)
|
||||
if (it == mesh_instances_.end()) {
|
||||
return;
|
||||
}
|
||||
ObjectData *obj_data = it->second.obj_data.get();
|
||||
ObjectData *obj_data = it->second.data.get();
|
||||
obj_data->update();
|
||||
|
||||
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()) {
|
||||
continue;
|
||||
}
|
||||
it->second.obj_data->remove();
|
||||
it->second.data->remove();
|
||||
mesh_instances_.erase(it);
|
||||
it = mesh_instances_.begin();
|
||||
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
|
||||
{
|
||||
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()) {
|
||||
paths.insert(mat_id);
|
||||
}
|
||||
@ -253,12 +267,14 @@ void InstancerData::set_instances()
|
||||
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);
|
||||
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
|
||||
inst->data->init();
|
||||
inst->data->insert();
|
||||
}
|
||||
else {
|
||||
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());
|
||||
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
|
||||
}
|
||||
@ -270,7 +286,7 @@ void InstancerData::set_instances()
|
||||
if (!it->second.indices.empty()) {
|
||||
continue;
|
||||
}
|
||||
it->second.obj_data->remove();
|
||||
it->second.data->remove();
|
||||
mesh_instances_.erase(it);
|
||||
it = mesh_instances_.begin();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace blender::render::hydra {
|
||||
|
||||
class InstancerData : public ObjectData {
|
||||
struct MeshInstance {
|
||||
std::unique_ptr<ObjectData> obj_data;
|
||||
std::unique_ptr<MeshData> data;
|
||||
pxr::VtIntArray indices;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user