forked from blender/blender
Support instancing for other objects: curves and volumes #74
@ -161,9 +161,11 @@ pxr::HdCullStyle BlenderSceneDelegate::GetCullStyle(pxr::SdfPath const &id)
|
||||
pxr::SdfPath BlenderSceneDelegate::GetInstancerId(pxr::SdfPath const &prim_id)
|
||||
{
|
||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", prim_id.GetText());
|
||||
InstancerData *i_data = instancer_data(prim_id, true);
|
||||
if (i_data) {
|
||||
return i_data->prim_id;
|
||||
if (mesh_data(prim_id)) {
|
||||
InstancerData *i_data = instancer_data(prim_id, true);
|
||||
if (i_data) {
|
||||
return i_data->prim_id;
|
||||
}
|
||||
}
|
||||
return pxr::SdfPath();
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ bool InstancerData::is_instance_supported(Object *object)
|
||||
case OB_CURVES_LEGACY:
|
||||
case OB_MBALL:
|
||||
case OB_LAMP:
|
||||
case OB_CURVES:
|
||||
case OB_VOLUME:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@ -120,7 +122,10 @@ pxr::SdfPathVector InstancerData::prototypes() const
|
||||
void InstancerData::available_materials(Set<pxr::SdfPath> &paths) const
|
||||
{
|
||||
for (auto &m_inst : mesh_instances_.values()) {
|
||||
((MeshData *)m_inst.data.get())->available_materials(paths);
|
||||
m_inst.data->available_materials(paths);
|
||||
}
|
||||
for (auto &l_inst : light_instances_.values()) {
|
||||
l_inst.data->available_materials(paths);
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,12 +161,11 @@ void InstancerData::update_instance(Object *parent_ob, DupliObject *dupli)
|
||||
}
|
||||
|
||||
pxr::SdfPath p_id = object_prim_id(ob);
|
||||
if (ob->type == OB_LAMP) {
|
||||
if (ELEM(ob->type, OB_LAMP, OB_VOLUME, OB_CURVES)) {
|
||||
LightInstance *inst = light_instance(p_id);
|
||||
if (!inst) {
|
||||
inst = &light_instances_.lookup_or_add_default(p_id);
|
||||
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
|
||||
inst->data->init();
|
||||
inst->data = ObjectData::create(scene_delegate_, ob, p_id);
|
||||
}
|
||||
ID_LOG(2, "Light %s %d", inst->data->id->name, (int)inst->transforms.size());
|
||||
inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
|
||||
@ -229,11 +233,11 @@ pxr::SdfPath InstancerData::object_prim_id(Object *object) const
|
||||
return prim_id.AppendElementString(name);
|
||||
}
|
||||
|
||||
pxr::SdfPath InstancerData::light_prim_id(LightInstance const &inst, int index) const
|
||||
pxr::SdfPath InstancerData::light_prim_id(pxr::SdfPath const &prim_id, int index) const
|
||||
{
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "L_%08x", index);
|
||||
return inst.data->prim_id.AppendElementString(name);
|
||||
return prim_id.AppendElementString(name);
|
||||
}
|
||||
|
||||
int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const
|
||||
@ -245,57 +249,46 @@ int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const
|
||||
|
||||
void InstancerData::update_light_instance(LightInstance &inst)
|
||||
{
|
||||
auto &render_index = scene_delegate_->GetRenderIndex();
|
||||
LightData &l_data = *inst.data;
|
||||
|
||||
ObjectData *obj_data = inst.data.get();
|
||||
pxr::SdfPath prev_id = inst.data->prim_id;
|
||||
int i;
|
||||
pxr::SdfPath p;
|
||||
|
||||
/* Remove old light instances */
|
||||
while (inst.count > inst.transforms.size()) {
|
||||
--inst.count;
|
||||
p = light_prim_id(inst, inst.count);
|
||||
render_index.RemoveSprim(l_data.prim_type_, p);
|
||||
ID_LOG(2, "Remove %s", p.GetText());
|
||||
obj_data->prim_id = light_prim_id(prev_id, inst.count);
|
||||
obj_data->remove();
|
||||
}
|
||||
|
||||
/* Update current light instances */
|
||||
if (inst.data->prim_type((Light *)((Object *)l_data.id)->data) != l_data.prim_type_) {
|
||||
/* Recreate instances when prim_type was changed */
|
||||
LightData *l_data = dynamic_cast<LightData *>(obj_data);
|
||||
if (l_data && l_data->prim_type((Light *)((Object *)l_data->id)->data) != l_data->prim_type_) {
|
||||
/* Special case: recreate instances when prim_type was changed */
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
p = light_prim_id(inst, i);
|
||||
render_index.RemoveSprim(l_data.prim_type_, p);
|
||||
ID_LOG(2, "Remove %s", p.GetText());
|
||||
obj_data->prim_id = light_prim_id(prev_id, i);
|
||||
obj_data->remove();
|
||||
}
|
||||
inst.data->init();
|
||||
l_data->init();
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
p = light_prim_id(inst, i);
|
||||
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
||||
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
||||
obj_data->prim_id = light_prim_id(prev_id, i);
|
||||
obj_data->insert();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Update light instances*/
|
||||
pxr::HdDirtyBits bits = pxr::HdLight::DirtyTransform;
|
||||
Object *obj = (Object *)inst.data->id;
|
||||
if (obj->id.recalc & ID_RECALC_GEOMETRY || ((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) {
|
||||
l_data.init();
|
||||
bits = pxr::HdLight::AllDirty;
|
||||
}
|
||||
for (i = 0; i < inst.count; ++i) {
|
||||
p = light_prim_id(inst, i);
|
||||
render_index.GetChangeTracker().MarkSprimDirty(p, bits);
|
||||
ID_LOG(2, "Update %s (%s)", p.GetText(), l_data.id->name);
|
||||
obj_data->prim_id = light_prim_id(prev_id, i);
|
||||
obj_data->update();
|
||||
}
|
||||
}
|
||||
|
||||
/* Add new light instances */
|
||||
while (inst.count < inst.transforms.size()) {
|
||||
p = light_prim_id(inst, inst.count);
|
||||
render_index.InsertSprim(l_data.prim_type_, scene_delegate_, p);
|
||||
ID_LOG(2, "Insert %s (%s)", p.GetText(), l_data.id->name);
|
||||
obj_data->prim_id = light_prim_id(prev_id, inst.count);
|
||||
obj_data->insert();
|
||||
++inst.count;
|
||||
}
|
||||
|
||||
obj_data->prim_id = prev_id;
|
||||
}
|
||||
|
||||
InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const
|
||||
|
@ -19,7 +19,7 @@ class InstancerData : public IdData {
|
||||
};
|
||||
|
||||
struct LightInstance {
|
||||
std::unique_ptr<LightData> data;
|
||||
std::unique_ptr<ObjectData> data;
|
||||
pxr::VtMatrix4dArray transforms;
|
||||
int count = 0;
|
||||
};
|
||||
@ -54,7 +54,7 @@ class InstancerData : public IdData {
|
||||
|
||||
private:
|
||||
pxr::SdfPath object_prim_id(Object *object) const;
|
||||
pxr::SdfPath light_prim_id(LightInstance const &inst, int index) const;
|
||||
pxr::SdfPath light_prim_id(pxr::SdfPath const &prim_id, int index) const;
|
||||
int light_prim_id_index(pxr::SdfPath const &id) const;
|
||||
void update_light_instance(LightInstance &inst);
|
||||
MeshInstance *mesh_instance(pxr::SdfPath const &id) const;
|
||||
|
Loading…
Reference in New Issue
Block a user