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