forked from blender/blender
Support multimaterials on one mesh #44
@ -36,7 +36,7 @@ bool InstancerData::is_supported(Object *object)
|
|||||||
void InstancerData::init()
|
void InstancerData::init()
|
||||||
{
|
{
|
||||||
ID_LOG(2, "");
|
ID_LOG(2, "");
|
||||||
set_instances();
|
write_instances();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::insert()
|
void InstancerData::insert()
|
||||||
@ -68,7 +68,7 @@ void InstancerData::update()
|
|||||||
(object->data && ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY) ||
|
(object->data && ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY) ||
|
||||||
id->recalc & ID_RECALC_TRANSFORM)
|
id->recalc & ID_RECALC_TRANSFORM)
|
||||||
{
|
{
|
||||||
set_instances();
|
write_instances();
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
}
|
}
|
||||||
@ -109,9 +109,9 @@ bool InstancerData::update_visibility()
|
|||||||
|
|
||||||
pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
|
pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
auto l_it = light_instances_.find(id.GetParentPath());
|
LightInstance *l_inst = light_instance(id);
|
||||||
if (l_it != light_instances_.end()) {
|
if (l_inst) {
|
||||||
return l_it->second.transforms[light_prim_id_index(id)];
|
return l_inst->transforms[light_prim_id_index(id)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mesh instance transform must be identity */
|
/* Mesh instance transform must be identity */
|
||||||
@ -131,18 +131,18 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
|
|||||||
|
|
||||||
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
|
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
return mesh_instances_.find(id.GetParentPath())->second.indices;
|
return mesh_instance(id)->indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
auto m_it = mesh_instances_.find(id.GetParentPath());
|
MeshInstance *m_inst = mesh_instance(id);
|
||||||
if (m_it != mesh_instances_.end()) {
|
if (m_inst) {
|
||||||
return m_it->second.data.get();
|
return m_inst->data.get();
|
||||||
}
|
}
|
||||||
auto l_it = light_instances_.find(id.GetParentPath());
|
LightInstance *l_inst = light_instance(id);
|
||||||
if (l_it != light_instances_.end()) {
|
if (l_inst) {
|
||||||
return l_it->second.data.get();
|
return l_inst->data.get();
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -161,25 +161,25 @@ pxr::SdfPathVector InstancerData::prototypes() const
|
|||||||
void InstancerData::check_update(Object *object)
|
void InstancerData::check_update(Object *object)
|
||||||
{
|
{
|
||||||
pxr::SdfPath path = object_prim_id(object);
|
pxr::SdfPath path = object_prim_id(object);
|
||||||
auto m_it = mesh_instances_.find(path);
|
MeshInstance *m_inst = mesh_instance(path);
|
||||||
if (m_it != mesh_instances_.end()) {
|
if (m_inst) {
|
||||||
m_it->second.data->update();
|
m_inst->data->update();
|
||||||
|
|
||||||
if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) {
|
if (m_inst->data->id->recalc & ID_RECALC_TRANSFORM) {
|
||||||
set_instances();
|
write_instances();
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto l_it = light_instances_.find(path);
|
LightInstance *l_inst = light_instance(path);
|
||||||
if (l_it != light_instances_.end()) {
|
if (l_inst) {
|
||||||
Object *obj = (Object *)l_it->second.data->id;
|
Object *obj = (Object *)l_inst->data->id;
|
||||||
if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) ||
|
if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) ||
|
||||||
((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY)
|
((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY)
|
||||||
{
|
{
|
||||||
set_instances();
|
write_instances();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
|
|||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
set_instances();
|
write_instances();
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
|
|||||||
|
|
||||||
void InstancerData::update_as_parent()
|
void InstancerData::update_as_parent()
|
||||||
{
|
{
|
||||||
set_instances();
|
write_instances();
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
}
|
}
|
||||||
@ -258,7 +258,7 @@ int InstancerData::light_prim_id_index(pxr::SdfPath const &id) const
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::set_instances()
|
void InstancerData::write_instances()
|
||||||
{
|
{
|
||||||
mesh_transforms_.clear();
|
mesh_transforms_.clear();
|
||||||
for (auto &it : mesh_instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
@ -278,31 +278,23 @@ void InstancerData::set_instances()
|
|||||||
|
|
||||||
pxr::SdfPath p_id = object_prim_id(ob);
|
pxr::SdfPath p_id = object_prim_id(ob);
|
||||||
if (ob->type == OB_LAMP) {
|
if (ob->type == OB_LAMP) {
|
||||||
LightInstance *inst;
|
LightInstance *inst = light_instance(p_id);
|
||||||
auto it = light_instances_.find(p_id);
|
if (!inst) {
|
||||||
if (it == light_instances_.end()) {
|
|
||||||
inst = &light_instances_[p_id];
|
inst = &light_instances_[p_id];
|
||||||
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
|
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
|
||||||
inst->data->init();
|
inst->data->init();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
inst = &it->second;
|
|
||||||
}
|
|
||||||
ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size());
|
ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size());
|
||||||
inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
|
inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MeshInstance *inst;
|
MeshInstance *inst = mesh_instance(p_id);
|
||||||
auto it = mesh_instances_.find(p_id);
|
if (!inst) {
|
||||||
if (it == mesh_instances_.end()) {
|
|
||||||
inst = &mesh_instances_[p_id];
|
inst = &mesh_instances_[p_id];
|
||||||
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
|
inst->data = std::make_unique<MeshData>(scene_delegate_, ob, p_id);
|
||||||
inst->data->init();
|
inst->data->init();
|
||||||
inst->data->insert();
|
inst->data->insert();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
inst = &it->second;
|
|
||||||
}
|
|
||||||
ID_LOG(2, "Mesh %s %d", inst->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));
|
||||||
@ -385,4 +377,22 @@ void InstancerData::update_light_instance(LightInstance &inst)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InstancerData::MeshInstance *InstancerData::mesh_instance(pxr::SdfPath const &id) const
|
||||||
|
{
|
||||||
|
auto it = mesh_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id);
|
||||||
|
if (it == mesh_instances_.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return const_cast<MeshInstance *>(&it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
InstancerData::LightInstance *InstancerData::light_instance(pxr::SdfPath const &id) const
|
||||||
|
{
|
||||||
|
auto it = light_instances_.find(id.GetPathElementCount() == 4 ? id.GetParentPath() : id);
|
||||||
|
if (it == light_instances_.end()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return const_cast<LightInstance *>(&it->second);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -49,8 +49,10 @@ class InstancerData : public ObjectData {
|
|||||||
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(LightInstance const &inst, int index) const;
|
||||||
int light_prim_id_index(pxr::SdfPath const &id) const;
|
int light_prim_id_index(pxr::SdfPath const &id) const;
|
||||||
void set_instances();
|
void write_instances();
|
||||||
void update_light_instance(LightInstance &inst);
|
void update_light_instance(LightInstance &inst);
|
||||||
|
MeshInstance *mesh_instance(pxr::SdfPath const &id) const;
|
||||||
|
LightInstance *light_instance(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