forked from blender/blender
Implement instancing for light objects #35
@ -103,12 +103,18 @@ bool InstancerData::update_visibility()
|
|||||||
{
|
{
|
||||||
bool ret = ObjectData::update_visibility();
|
bool ret = ObjectData::update_visibility();
|
||||||
if (ret) {
|
if (ret) {
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
auto &change_tracker = scene_delegate_->GetRenderIndex().GetChangeTracker();
|
||||||
prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
change_tracker.MarkInstancerDirty(prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
it.second.data->visible = visible;
|
it.second.data->visible = visible;
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
|
change_tracker.MarkRprimDirty(it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
||||||
it.second.data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
}
|
||||||
|
char name[16];
|
||||||
|
for (auto &it : light_instances_) {
|
||||||
|
for (int i = 0; i < it.second.count; ++i) {
|
||||||
|
snprintf(name, 16, "L_%08x", i);
|
||||||
|
change_tracker.MarkRprimDirty(it.second.data->prim_id.AppendElementString(name), pxr::HdChangeTracker::DirtyVisibility);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -118,12 +124,10 @@ pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
|
|||||||
{
|
{
|
||||||
if (id.GetPathElementCount() == 4) {
|
if (id.GetPathElementCount() == 4) {
|
||||||
const auto &inst = light_instances_.find(id.GetParentPath())->second;
|
const auto &inst = light_instances_.find(id.GetParentPath())->second;
|
||||||
std::string name = id.GetName();
|
return inst.transforms[light_prim_id_index(id)];
|
||||||
int index;
|
|
||||||
sscanf_s(name.c_str(), "L_%x", &index);
|
|
||||||
return inst.transforms[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mesh instance transform must be identity */
|
||||||
return pxr::GfMatrix4d(1.0);
|
return pxr::GfMatrix4d(1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,15 +310,13 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
|||||||
auto &render_index = scene_delegate_->GetRenderIndex();
|
auto &render_index = scene_delegate_->GetRenderIndex();
|
||||||
LightData &l_data = *inst.data;
|
LightData &l_data = *inst.data;
|
||||||
|
|
||||||
char name[16];
|
|
||||||
int i;
|
int i;
|
||||||
pxr::SdfPath p;
|
pxr::SdfPath p;
|
||||||
|
|
||||||
/* Remove old light instances */
|
/* Remove old light instances */
|
||||||
while (inst.count > inst.transforms.size()) {
|
while (inst.count > inst.transforms.size()) {
|
||||||
--inst.count;
|
--inst.count;
|
||||||
snprintf(name, 16, "L_%08x", inst.count);
|
p = light_prim_id(inst, inst.count);
|
||||||
p = l_data.prim_id.AppendElementString(name);
|
|
||||||
render_index.RemoveSprim(l_data.prim_type_, p);
|
render_index.RemoveSprim(l_data.prim_type_, p);
|
||||||
ID_LOG(2, "Remove %s", p.GetText());
|
ID_LOG(2, "Remove %s", p.GetText());
|
||||||
}
|
}
|
||||||
@ -323,15 +325,13 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
|||||||
if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) {
|
if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) {
|
||||||
/* Recreate instances when prim_type was changed */
|
/* Recreate instances when prim_type was changed */
|
||||||
for (i = 0; i < inst.count; ++i) {
|
for (i = 0; i < inst.count; ++i) {
|
||||||
snprintf(name, 16, "L_%08x", i);
|
p = light_prim_id(inst, i);
|
||||||
p = l_data.prim_id.AppendElementString(name);
|
|
||||||
render_index.RemoveSprim(l_data.prim_type_, p);
|
render_index.RemoveSprim(l_data.prim_type_, p);
|
||||||
ID_LOG(2, "Remove %s", p.GetText());
|
ID_LOG(2, "Remove %s", p.GetText());
|
||||||
}
|
}
|
||||||
inst.data->init();
|
inst.data->init();
|
||||||
for (i = 0; i < inst.count; ++i) {
|
for (i = 0; i < inst.count; ++i) {
|
||||||
snprintf(name, 16, "L_%08x", i);
|
p = light_prim_id(inst, i);
|
||||||
p = l_data.prim_id.AppendElementString(name);
|
|
||||||
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
||||||
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
||||||
}
|
}
|
||||||
@ -344,8 +344,7 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
|||||||
bits = pxr::HdLight::AllDirty;
|
bits = pxr::HdLight::AllDirty;
|
||||||
}
|
}
|
||||||
for (i = 0; i < inst.count; ++i) {
|
for (i = 0; i < inst.count; ++i) {
|
||||||
snprintf(name, 16, "L_%08x", i);
|
p = light_prim_id(inst, i);
|
||||||
p = l_data.prim_id.AppendElementString(name);
|
|
||||||
render_index.GetChangeTracker().MarkSprimDirty(p, bits);
|
render_index.GetChangeTracker().MarkSprimDirty(p, bits);
|
||||||
ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name);
|
ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name);
|
||||||
}
|
}
|
||||||
@ -353,12 +352,25 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
|||||||
|
|
||||||
/* Add new light instances */
|
/* Add new light instances */
|
||||||
while (inst.count < inst.transforms.size()) {
|
while (inst.count < inst.transforms.size()) {
|
||||||
snprintf(name, 16, "L_%08x", inst.count);
|
p = light_prim_id(inst, inst.count);
|
||||||
p = inst.data->prim_id.AppendElementString(name);
|
|
||||||
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
||||||
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
||||||
++inst.count;
|
++inst.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pxr::SdfPath InstancerData::light_prim_id(LightInstance const &inst, int index) const
|
||||||
|
{
|
||||||
|
char name[16];
|
||||||
|
snprintf(name, 16, "L_%08x", index);
|
||||||
|
return inst.data->prim_id.AppendElementString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
sscanf_s(id.GetName().c_str(), "L_%x", &index);
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -52,6 +52,8 @@ 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();
|
||||||
void update_light_instance(LightInstance &inst);
|
void update_light_instance(LightInstance &inst);
|
||||||
|
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
|
||||||
|
int light_prim_id_index(pxr::SdfPath const &id) const;
|
||||||
|
|
||||||
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
|
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
|
||||||
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;
|
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;
|
||||||
|
Loading…
Reference in New Issue
Block a user