forked from blender/blender
Implement instancing for light objects #35
@ -32,43 +32,42 @@ pxr::HdMeshTopology BlenderSceneDelegate::GetMeshTopology(pxr::SdfPath const &id
|
|||||||
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
|
pxr::GfMatrix4d BlenderSceneDelegate::GetTransform(pxr::SdfPath const &id)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||||
|
InstancerData *i_data = instancer_data(id, true);
|
||||||
|
if (i_data) {
|
||||||
|
return i_data->get_transform(id);
|
||||||
|
}
|
||||||
ObjectData *obj_data = object_data(id);
|
ObjectData *obj_data = object_data(id);
|
||||||
if (obj_data) {
|
if (obj_data) {
|
||||||
return obj_data->transform;
|
return obj_data->transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (id == world_prim_id()) {
|
if (id == world_prim_id()) {
|
||||||
return world_data_->transform;
|
return world_data_->transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxr::GfMatrix4d();
|
return pxr::GfMatrix4d();
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
|
pxr::VtValue BlenderSceneDelegate::Get(pxr::SdfPath const &id, pxr::TfToken const &key)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText());
|
||||||
|
|
||||||
ObjectData *obj_data = object_data(id);
|
ObjectData *obj_data = object_data(id);
|
||||||
if (obj_data) {
|
if (obj_data) {
|
||||||
return obj_data->get_data(key);
|
return obj_data->get_data(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialData *mat_data = material_data(id);
|
MaterialData *mat_data = material_data(id);
|
||||||
if (mat_data) {
|
if (mat_data) {
|
||||||
return mat_data->get_data(key);
|
return mat_data->get_data(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstancerData *i_data = instancer_data(id);
|
InstancerData *i_data = instancer_data(id);
|
||||||
if (i_data) {
|
if (i_data) {
|
||||||
return i_data->get_data(key);
|
return i_data->get_data(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxr::VtValue();
|
return pxr::VtValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
pxr::VtValue BlenderSceneDelegate::GetLightParamValue(pxr::SdfPath const &id,
|
||||||
pxr::TfToken const &key)
|
pxr::TfToken const &key)
|
||||||
{
|
{
|
||||||
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %s", id.GetText(), key.GetText());
|
||||||
LightData *l_data = light_data(id);
|
LightData *l_data = light_data(id);
|
||||||
if (l_data) {
|
if (l_data) {
|
||||||
return l_data->get_data(key);
|
return l_data->get_data(key);
|
||||||
@ -83,27 +82,26 @@ pxr::HdPrimvarDescriptorVector BlenderSceneDelegate::GetPrimvarDescriptors(
|
|||||||
pxr::SdfPath const &id, pxr::HdInterpolation interpolation)
|
pxr::SdfPath const &id, pxr::HdInterpolation interpolation)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %d", id.GetText(), interpolation);
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s, %d", id.GetText(), interpolation);
|
||||||
|
|
||||||
MeshData *m_data = mesh_data(id);
|
MeshData *m_data = mesh_data(id);
|
||||||
if (m_data) {
|
if (m_data) {
|
||||||
return m_data->primvar_descriptors(interpolation);
|
return m_data->primvar_descriptors(interpolation);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstancerData *i_data = instancer_data(id);
|
InstancerData *i_data = instancer_data(id);
|
||||||
if (i_data) {
|
if (i_data) {
|
||||||
return i_data->primvar_descriptors(interpolation);
|
return i_data->primvar_descriptors(interpolation);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxr::HdPrimvarDescriptorVector();
|
return pxr::HdPrimvarDescriptorVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
pxr::SdfPath BlenderSceneDelegate::GetMaterialId(pxr::SdfPath const &rprim_id)
|
||||||
{
|
{
|
||||||
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", rprim_id.GetText());
|
||||||
return mesh_data(rprim_id)->material_id();
|
return mesh_data(rprim_id)->material_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
||||||
{
|
{
|
||||||
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||||
MaterialData *mat_data = material_data(id);
|
MaterialData *mat_data = material_data(id);
|
||||||
if (mat_data) {
|
if (mat_data) {
|
||||||
return mat_data->get_material_resource();
|
return mat_data->get_material_resource();
|
||||||
@ -113,10 +111,14 @@ pxr::VtValue BlenderSceneDelegate::GetMaterialResource(pxr::SdfPath const &id)
|
|||||||
|
|
||||||
bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
|
bool BlenderSceneDelegate::GetVisible(pxr::SdfPath const &id)
|
||||||
{
|
{
|
||||||
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 3, "%s", id.GetText());
|
||||||
if (id == world_prim_id()) {
|
if (id == world_prim_id()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
InstancerData *i_data = instancer_data(id, true);
|
||||||
|
if (i_data) {
|
||||||
|
return i_data->visible;
|
||||||
|
}
|
||||||
return object_data(id)->visible;
|
return object_data(id)->visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,11 +177,9 @@ void BlenderSceneDelegate::clear()
|
|||||||
for (auto &it : objects_) {
|
for (auto &it : objects_) {
|
||||||
it.second->remove();
|
it.second->remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &it : instancers_) {
|
for (auto &it : instancers_) {
|
||||||
it.second->remove();
|
it.second->remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &it : materials_) {
|
for (auto &it : materials_) {
|
||||||
it.second->remove();
|
it.second->remove();
|
||||||
}
|
}
|
||||||
@ -223,7 +223,7 @@ ObjectData *BlenderSceneDelegate::object_data(pxr::SdfPath const &id) const
|
|||||||
if (it != objects_.end()) {
|
if (it != objects_.end()) {
|
||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
InstancerData *i_data = instancer_data(id.GetParentPath());
|
InstancerData *i_data = instancer_data(id, true);
|
||||||
if (i_data) {
|
if (i_data) {
|
||||||
return i_data->object_data(id);
|
return i_data->object_data(id);
|
||||||
}
|
}
|
||||||
@ -249,9 +249,23 @@ MaterialData *BlenderSceneDelegate::material_data(pxr::SdfPath const &id) const
|
|||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id) const
|
InstancerData *BlenderSceneDelegate::instancer_data(pxr::SdfPath const &id, bool child_id) const
|
||||||
{
|
{
|
||||||
auto it = instancers_.find(id);
|
pxr::SdfPath p_id;
|
||||||
|
if (child_id) {
|
||||||
|
int n = id.GetPathElementCount();
|
||||||
|
if (n == 3) {
|
||||||
|
p_id = id.GetParentPath();
|
||||||
|
}
|
||||||
|
else if (n == 4) {
|
||||||
|
p_id = id.GetParentPath().GetParentPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p_id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = instancers_.find(p_id);
|
||||||
if (it != instancers_.end()) {
|
if (it != instancers_.end()) {
|
||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
@ -266,6 +280,7 @@ void BlenderSceneDelegate::update_objects(Object *object)
|
|||||||
pxr::SdfPath id = object_prim_id(object);
|
pxr::SdfPath id = object_prim_id(object);
|
||||||
ObjectData *obj_data = object_data(id);
|
ObjectData *obj_data = object_data(id);
|
||||||
if (obj_data) {
|
if (obj_data) {
|
||||||
|
obj_data->update_parent();
|
||||||
obj_data->update();
|
obj_data->update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -274,6 +289,9 @@ void BlenderSceneDelegate::update_objects(Object *object)
|
|||||||
}
|
}
|
||||||
objects_[id] = ObjectData::create(this, object, id);
|
objects_[id] = ObjectData::create(this, object, id);
|
||||||
obj_data = object_data(id);
|
obj_data = object_data(id);
|
||||||
|
obj_data->update_parent();
|
||||||
|
obj_data->init();
|
||||||
|
obj_data->insert();
|
||||||
obj_data->update_visibility();
|
obj_data->update_visibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,8 +320,10 @@ void BlenderSceneDelegate::update_instancers(Object *object)
|
|||||||
if (view3d && !BKE_object_is_visible_in_viewport(view3d, object)) {
|
if (view3d && !BKE_object_is_visible_in_viewport(view3d, object)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instancers_[id] = InstancerData::create(this, object, id);
|
instancers_[id] = std::make_unique<InstancerData>(this, object, id);
|
||||||
i_data = instancer_data(id);
|
i_data = instancer_data(id);
|
||||||
|
i_data->init();
|
||||||
|
i_data->insert();
|
||||||
i_data->update_visibility();
|
i_data->update_visibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +332,9 @@ void BlenderSceneDelegate::update_world()
|
|||||||
World *world = scene->world;
|
World *world = scene->world;
|
||||||
if (!world_data_) {
|
if (!world_data_) {
|
||||||
if (world) {
|
if (world) {
|
||||||
world_data_ = WorldData::create(this, world, world_prim_id());
|
world_data_ = std::make_unique<WorldData>(this, world, world_prim_id());
|
||||||
|
world_data_->init();
|
||||||
|
world_data_->insert();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -21,7 +21,8 @@ namespace blender::render::hydra {
|
|||||||
extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegate */
|
extern struct CLG_LogRef *LOG_RENDER_HYDRA_SCENE; /* BSD - Blender Scene Delegate */
|
||||||
|
|
||||||
class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
||||||
friend MeshData; /* has access to materials and instances */
|
friend ObjectData; /* has access to instances */
|
||||||
|
friend MeshData; /* has access to materials */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW };
|
enum class EngineType { VIEWPORT = 1, FINAL, PREVIEW };
|
||||||
@ -70,7 +71,7 @@ class BlenderSceneDelegate : public pxr::HdSceneDelegate {
|
|||||||
MeshData *mesh_data(pxr::SdfPath const &id) const;
|
MeshData *mesh_data(pxr::SdfPath const &id) const;
|
||||||
LightData *light_data(pxr::SdfPath const &id) const;
|
LightData *light_data(pxr::SdfPath const &id) const;
|
||||||
MaterialData *material_data(pxr::SdfPath const &id) const;
|
MaterialData *material_data(pxr::SdfPath const &id) const;
|
||||||
InstancerData *instancer_data(pxr::SdfPath const &id) const;
|
InstancerData *instancer_data(pxr::SdfPath const &id, bool child_id = false) const;
|
||||||
|
|
||||||
void update_objects(Object *object);
|
void update_objects(Object *object);
|
||||||
void update_instancers(Object *object);
|
void update_instancers(Object *object);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* Copyright 2011-2022 Blender Foundation */
|
* Copyright 2011-2022 Blender Foundation */
|
||||||
|
|
||||||
#include <pxr/base/gf/vec2f.h>
|
#include <pxr/base/gf/vec2f.h>
|
||||||
|
#include <pxr/imaging/hd/light.h>
|
||||||
|
|
||||||
#include "blender_scene_delegate.h"
|
#include "blender_scene_delegate.h"
|
||||||
#include "instancer.h"
|
#include "instancer.h"
|
||||||
@ -15,16 +16,6 @@ InstancerData::InstancerData(BlenderSceneDelegate *scene_delegate,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<InstancerData> InstancerData::create(BlenderSceneDelegate *scene_delegate,
|
|
||||||
Object *object,
|
|
||||||
pxr::SdfPath const &prim_id)
|
|
||||||
{
|
|
||||||
auto data = std::make_unique<InstancerData>(scene_delegate, object, prim_id);
|
|
||||||
data->init();
|
|
||||||
data->insert();
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InstancerData::is_supported(Object *object)
|
bool InstancerData::is_supported(Object *object)
|
||||||
{
|
{
|
||||||
switch (object->type) {
|
switch (object->type) {
|
||||||
@ -33,6 +24,7 @@ bool InstancerData::is_supported(Object *object)
|
|||||||
case OB_FONT:
|
case OB_FONT:
|
||||||
case OB_CURVES_LEGACY:
|
case OB_CURVES_LEGACY:
|
||||||
case OB_MBALL:
|
case OB_MBALL:
|
||||||
|
case OB_LAMP:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -56,29 +48,27 @@ void InstancerData::insert()
|
|||||||
void InstancerData::remove()
|
void InstancerData::remove()
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
CLOG_INFO(LOG_RENDER_HYDRA_SCENE, 2, "%s", prim_id.GetText());
|
||||||
for (auto &it : instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
it.second.obj_data->remove();
|
it.second.data->remove();
|
||||||
}
|
}
|
||||||
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
scene_delegate_->GetRenderIndex().RemoveInstancer(prim_id);
|
||||||
|
|
||||||
|
for (auto &it : light_instances_) {
|
||||||
|
it.second.transforms.clear();
|
||||||
|
update_light_instance(it.second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::update()
|
void InstancerData::update()
|
||||||
{
|
{
|
||||||
ID_LOG(2, "");
|
ID_LOG(2, "");
|
||||||
|
|
||||||
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
|
|
||||||
|
|
||||||
Object *object = (Object *)id;
|
Object *object = (Object *)id;
|
||||||
if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
|
if (id->recalc & ID_RECALC_GEOMETRY || ((ID *)object->data)->recalc & ID_RECALC_GEOMETRY ||
|
||||||
|
id->recalc & ID_RECALC_TRANSFORM) {
|
||||||
set_instances();
|
set_instances();
|
||||||
bits |= pxr::HdChangeTracker::AllDirty;
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
}
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
else if (id->recalc & ID_RECALC_TRANSFORM) {
|
|
||||||
set_instances();
|
|
||||||
bits |= pxr::HdChangeTracker::DirtyTransform;
|
|
||||||
}
|
|
||||||
if (bits != pxr::HdChangeTracker::Clean) {
|
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +77,7 @@ pxr::VtValue InstancerData::get_data(pxr::TfToken const &key) const
|
|||||||
ID_LOG(3, "%s", key.GetText());
|
ID_LOG(3, "%s", key.GetText());
|
||||||
pxr::VtValue ret;
|
pxr::VtValue ret;
|
||||||
if (key == pxr::HdInstancerTokens->instanceTransform) {
|
if (key == pxr::HdInstancerTokens->instanceTransform) {
|
||||||
ret = transforms_;
|
ret = mesh_transforms_;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -96,17 +86,36 @@ 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 : instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
it.second.obj_data->visible = visible;
|
it.second.data->visible = visible;
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkRprimDirty(
|
change_tracker.MarkRprimDirty(it.second.data->prim_id,
|
||||||
it.second.obj_data->prim_id, pxr::HdChangeTracker::DirtyVisibility);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pxr::GfMatrix4d InstancerData::get_transform(pxr::SdfPath const &id) const
|
||||||
|
{
|
||||||
|
if (id.GetPathElementCount() == 4) {
|
||||||
|
const auto &inst = light_instances_.find(id.GetParentPath())->second;
|
||||||
|
return inst.transforms[light_prim_id_index(id)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mesh instance transform must be identity */
|
||||||
|
return pxr::GfMatrix4d(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
|
pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
|
||||||
pxr::HdInterpolation interpolation) const
|
pxr::HdInterpolation interpolation) const
|
||||||
{
|
{
|
||||||
@ -120,18 +129,26 @@ pxr::HdPrimvarDescriptorVector InstancerData::primvar_descriptors(
|
|||||||
|
|
||||||
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
|
pxr::VtIntArray InstancerData::indices(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
return instances_.find(id)->second.indices;
|
return mesh_instances_.find(id)->second.indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
ObjectData *InstancerData::object_data(pxr::SdfPath const &id) const
|
||||||
{
|
{
|
||||||
return instances_.find(id)->second.obj_data.get();
|
auto m_it = mesh_instances_.find(id);
|
||||||
|
if (m_it != mesh_instances_.end()) {
|
||||||
|
return m_it->second.data.get();
|
||||||
|
}
|
||||||
|
auto l_it = light_instances_.find(id.GetParentPath());
|
||||||
|
if (l_it != light_instances_.end()) {
|
||||||
|
return l_it->second.data.get();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pxr::SdfPathVector InstancerData::prototypes() const
|
pxr::SdfPathVector InstancerData::prototypes() const
|
||||||
{
|
{
|
||||||
pxr::SdfPathVector paths;
|
pxr::SdfPathVector paths;
|
||||||
for (auto &it : instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
paths.push_back(it.first);
|
paths.push_back(it.first);
|
||||||
}
|
}
|
||||||
return paths;
|
return paths;
|
||||||
@ -140,34 +157,39 @@ 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 it = instances_.find(path);
|
auto m_it = mesh_instances_.find(path);
|
||||||
if (it == instances_.end()) {
|
if (m_it != mesh_instances_.end()) {
|
||||||
|
m_it->second.data->update();
|
||||||
|
|
||||||
|
if (m_it->second.data->id->recalc & ID_RECALC_TRANSFORM) {
|
||||||
|
set_instances();
|
||||||
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ObjectData *obj_data = it->second.obj_data.get();
|
|
||||||
obj_data->update();
|
|
||||||
obj_data->transform = pxr::GfMatrix4d(1.0);
|
|
||||||
|
|
||||||
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
|
auto l_it = light_instances_.find(path);
|
||||||
if (object->id.recalc & ID_RECALC_TRANSFORM) {
|
if (l_it != light_instances_.end()) {
|
||||||
|
Object *obj = (Object *)l_it->second.data->id;
|
||||||
|
if (obj->id.recalc & (ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY) ||
|
||||||
|
((ID *)obj->data)->recalc & ID_RECALC_GEOMETRY) {
|
||||||
set_instances();
|
set_instances();
|
||||||
bits |= pxr::HdChangeTracker::DirtyTransform;
|
|
||||||
}
|
}
|
||||||
if (bits != pxr::HdChangeTracker::Clean) {
|
return;
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(prim_id, bits);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::check_remove(std::set<std::string> &available_objects)
|
void InstancerData::check_remove(std::set<std::string> &available_objects)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
for (auto it = instances_.begin(); it != instances_.end(); ++it) {
|
for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) {
|
||||||
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
it->second.obj_data->remove();
|
it->second.data->remove();
|
||||||
instances_.erase(it);
|
mesh_instances_.erase(it);
|
||||||
it = instances_.begin();
|
it = mesh_instances_.begin();
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -175,12 +197,23 @@ void InstancerData::check_remove(std::set<std::string> &available_objects)
|
|||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkInstancerDirty(
|
||||||
prim_id, pxr::HdChangeTracker::AllDirty);
|
prim_id, pxr::HdChangeTracker::AllDirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) {
|
||||||
|
if (available_objects.find(it->first.GetName()) != available_objects.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
it->second.transforms.clear();
|
||||||
|
update_light_instance(it->second);
|
||||||
|
|
||||||
|
light_instances_.erase(it);
|
||||||
|
it = light_instances_.begin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
|
void InstancerData::available_materials(std::set<pxr::SdfPath> &paths) const
|
||||||
{
|
{
|
||||||
for (auto &it : instances_) {
|
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()) {
|
if (!mat_id.IsEmpty()) {
|
||||||
paths.insert(mat_id);
|
paths.insert(mat_id);
|
||||||
}
|
}
|
||||||
@ -202,49 +235,144 @@ pxr::SdfPath InstancerData::object_prim_id(Object *object) const
|
|||||||
return prim_id.AppendElementString(str);
|
return prim_id.AppendElementString(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
void InstancerData::set_instances()
|
void InstancerData::set_instances()
|
||||||
{
|
{
|
||||||
transforms_.clear();
|
mesh_transforms_.clear();
|
||||||
for (auto &it : instances_) {
|
for (auto &it : mesh_instances_) {
|
||||||
it.second.indices.clear();
|
it.second.indices.clear();
|
||||||
}
|
}
|
||||||
int index = 0;
|
for (auto &it : light_instances_) {
|
||||||
Instance *inst;
|
it.second.transforms.clear();
|
||||||
pxr::SdfPath p_id;
|
}
|
||||||
|
|
||||||
ListBase *lb = object_duplilist(
|
ListBase *lb = object_duplilist(
|
||||||
scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id);
|
scene_delegate_->depsgraph, scene_delegate_->scene, (Object *)id);
|
||||||
LISTBASE_FOREACH (DupliObject *, dupli, lb) {
|
LISTBASE_FOREACH (DupliObject *, dupli, lb) {
|
||||||
p_id = object_prim_id(dupli->ob);
|
Object *ob = dupli->ob;
|
||||||
auto it = instances_.find(p_id);
|
if (!is_supported(ob)) {
|
||||||
if (it == instances_.end()) {
|
|
||||||
inst = &instances_[p_id];
|
|
||||||
if (!is_supported(dupli->ob)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
inst->obj_data = ObjectData::create(scene_delegate_, dupli->ob, p_id);
|
|
||||||
|
|
||||||
/* Instance's transform should be identity */
|
pxr::SdfPath p_id = object_prim_id(ob);
|
||||||
inst->obj_data->transform = pxr::GfMatrix4d(1.0);
|
if (ob->type == OB_LAMP) {
|
||||||
|
LightInstance *inst;
|
||||||
|
auto it = light_instances_.find(p_id);
|
||||||
|
if (it == light_instances_.end()) {
|
||||||
|
inst = &light_instances_[p_id];
|
||||||
|
inst->data = std::make_unique<LightData>(scene_delegate_, ob, p_id);
|
||||||
|
inst->data->init();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inst = &it->second;
|
inst = &it->second;
|
||||||
}
|
}
|
||||||
transforms_.push_back(gf_matrix_from_transform(dupli->mat));
|
ID_LOG(2, "Light %s %d", inst->data->id->name, inst->transforms.size());
|
||||||
inst->indices.push_back(index);
|
inst->transforms.push_back(gf_matrix_from_transform(dupli->mat));
|
||||||
ID_LOG(2, "%s %d", inst->obj_data->id->name, index);
|
}
|
||||||
++index;
|
else {
|
||||||
|
MeshInstance *inst;
|
||||||
|
auto it = mesh_instances_.find(p_id);
|
||||||
|
if (it == mesh_instances_.end()) {
|
||||||
|
inst = &mesh_instances_[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->data->id->name, mesh_transforms_.size());
|
||||||
|
inst->indices.push_back(mesh_transforms_.size());
|
||||||
|
mesh_transforms_.push_back(gf_matrix_from_transform(dupli->mat));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free_object_duplilist(lb);
|
free_object_duplilist(lb);
|
||||||
|
|
||||||
/* Remove intances without indices */
|
/* Remove mesh intances without indices */
|
||||||
for (auto it = instances_.begin(); it != instances_.end(); ++it) {
|
for (auto it = mesh_instances_.begin(); it != mesh_instances_.end(); ++it) {
|
||||||
if (!it->second.indices.empty()) {
|
if (!it->second.indices.empty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
it->second.obj_data->remove();
|
it->second.data->remove();
|
||||||
instances_.erase(it);
|
mesh_instances_.erase(it);
|
||||||
it = instances_.begin();
|
it = mesh_instances_.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update light intances and remove instances without transforms */
|
||||||
|
for (auto it = light_instances_.begin(); it != light_instances_.end(); ++it) {
|
||||||
|
update_light_instance(it->second);
|
||||||
|
if (it->second.transforms.empty()) {
|
||||||
|
light_instances_.erase(it);
|
||||||
|
it = light_instances_.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstancerData::update_light_instance(LightInstance &inst)
|
||||||
|
{
|
||||||
|
auto &render_index = scene_delegate_->GetRenderIndex();
|
||||||
|
LightData &l_data = *inst.data;
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
inst.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
++inst.count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,22 +5,25 @@
|
|||||||
|
|
||||||
#include "BKE_duplilist.h"
|
#include "BKE_duplilist.h"
|
||||||
|
|
||||||
|
#include "light.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
class InstancerData : public ObjectData {
|
class InstancerData : public ObjectData {
|
||||||
struct Instance {
|
struct MeshInstance {
|
||||||
std::unique_ptr<ObjectData> obj_data;
|
std::unique_ptr<MeshData> data;
|
||||||
pxr::VtIntArray indices;
|
pxr::VtIntArray indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LightInstance {
|
||||||
|
std::unique_ptr<LightData> data;
|
||||||
|
pxr::VtMatrix4dArray transforms;
|
||||||
|
int count = 0;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
InstancerData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||||
|
|
||||||
static std::unique_ptr<InstancerData> create(BlenderSceneDelegate *scene_delegate,
|
|
||||||
Object *object,
|
|
||||||
pxr::SdfPath const &prim_id);
|
|
||||||
static bool is_supported(Object *object);
|
static bool is_supported(Object *object);
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
@ -31,6 +34,7 @@ class InstancerData : public ObjectData {
|
|||||||
pxr::VtValue get_data(pxr::TfToken const &key) const override;
|
pxr::VtValue get_data(pxr::TfToken const &key) const override;
|
||||||
bool update_visibility() override;
|
bool update_visibility() override;
|
||||||
|
|
||||||
|
pxr::GfMatrix4d get_transform(pxr::SdfPath const &id) const;
|
||||||
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
pxr::HdPrimvarDescriptorVector primvar_descriptors(pxr::HdInterpolation interpolation) const;
|
||||||
pxr::VtIntArray indices(pxr::SdfPath const &id) const;
|
pxr::VtIntArray indices(pxr::SdfPath const &id) const;
|
||||||
ObjectData *object_data(pxr::SdfPath const &id) const;
|
ObjectData *object_data(pxr::SdfPath const &id) const;
|
||||||
@ -42,10 +46,14 @@ class InstancerData : public ObjectData {
|
|||||||
|
|
||||||
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;
|
||||||
|
int light_prim_id_index(pxr::SdfPath const &id) const;
|
||||||
void set_instances();
|
void set_instances();
|
||||||
|
void update_light_instance(LightInstance &inst);
|
||||||
|
|
||||||
pxr::TfHashMap<pxr::SdfPath, Instance, pxr::SdfPath::Hash> instances_;
|
pxr::TfHashMap<pxr::SdfPath, MeshInstance, pxr::SdfPath::Hash> mesh_instances_;
|
||||||
pxr::VtMatrix4dArray transforms_;
|
pxr::TfHashMap<pxr::SdfPath, LightInstance, pxr::SdfPath::Hash> light_instances_;
|
||||||
|
pxr::VtMatrix4dArray mesh_transforms_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using InstancerDataMap =
|
using InstancerDataMap =
|
||||||
|
@ -104,7 +104,8 @@ void LightData::update()
|
|||||||
{
|
{
|
||||||
ID_LOG(2, "");
|
ID_LOG(2, "");
|
||||||
|
|
||||||
Light *light = (Light *)((Object *)id)->data;
|
Object *object = (Object *)id;
|
||||||
|
Light *light = (Light *)object->data;
|
||||||
if (prim_type(light) != prim_type_) {
|
if (prim_type(light) != prim_type_) {
|
||||||
remove();
|
remove();
|
||||||
init();
|
init();
|
||||||
@ -113,7 +114,7 @@ void LightData::update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
pxr::HdDirtyBits bits = pxr::HdLight::Clean;
|
pxr::HdDirtyBits bits = pxr::HdLight::Clean;
|
||||||
if (id->recalc & ID_RECALC_GEOMETRY) {
|
if (id->recalc & ID_RECALC_GEOMETRY || light->id.recalc & ID_RECALC_GEOMETRY) {
|
||||||
init();
|
init();
|
||||||
bits = pxr::HdLight::AllDirty;
|
bits = pxr::HdLight::AllDirty;
|
||||||
}
|
}
|
||||||
@ -121,8 +122,10 @@ void LightData::update()
|
|||||||
write_transform();
|
write_transform();
|
||||||
bits = pxr::HdLight::DirtyTransform;
|
bits = pxr::HdLight::DirtyTransform;
|
||||||
}
|
}
|
||||||
|
if (bits != pxr::HdChangeTracker::Clean) {
|
||||||
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits);
|
scene_delegate_->GetRenderIndex().GetChangeTracker().MarkSprimDirty(prim_id, bits);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
|
pxr::VtValue LightData::get_data(pxr::TfToken const &key) const
|
||||||
{
|
{
|
||||||
|
@ -13,7 +13,11 @@
|
|||||||
|
|
||||||
namespace blender::render::hydra {
|
namespace blender::render::hydra {
|
||||||
|
|
||||||
|
class InstancerData;
|
||||||
|
|
||||||
class LightData : public ObjectData {
|
class LightData : public ObjectData {
|
||||||
|
friend InstancerData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LightData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
LightData(BlenderSceneDelegate *scene_delegate, Object *object, pxr::SdfPath const &prim_id);
|
||||||
|
|
||||||
|
@ -27,16 +27,6 @@ MaterialData::MaterialData(BlenderSceneDelegate *scene_delegate,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MaterialData> MaterialData::create(BlenderSceneDelegate *scene_delegate,
|
|
||||||
Material *material,
|
|
||||||
pxr::SdfPath const &prim_id)
|
|
||||||
{
|
|
||||||
auto data = std::make_unique<MaterialData>(scene_delegate, material, prim_id);
|
|
||||||
data->init();
|
|
||||||
data->insert();
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaterialData::init()
|
void MaterialData::init()
|
||||||
{
|
{
|
||||||
ID_LOG(2, "");
|
ID_LOG(2, "");
|
||||||
|
@ -19,10 +19,6 @@ class MaterialData : public IdData {
|
|||||||
Material *material,
|
Material *material,
|
||||||
pxr::SdfPath const &prim_id);
|
pxr::SdfPath const &prim_id);
|
||||||
|
|
||||||
static std::unique_ptr<MaterialData> create(BlenderSceneDelegate *scene_delegate,
|
|
||||||
Material *material,
|
|
||||||
pxr::SdfPath const &prim_id);
|
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
void insert() override;
|
void insert() override;
|
||||||
void remove() override;
|
void remove() override;
|
||||||
|
@ -17,7 +17,7 @@ namespace blender::render::hydra {
|
|||||||
MeshData::MeshData(BlenderSceneDelegate *scene_delegate,
|
MeshData::MeshData(BlenderSceneDelegate *scene_delegate,
|
||||||
Object *object,
|
Object *object,
|
||||||
pxr::SdfPath const &prim_id)
|
pxr::SdfPath const &prim_id)
|
||||||
: ObjectData(scene_delegate, object, prim_id), parent_(object->parent)
|
: ObjectData(scene_delegate, object, prim_id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,20 +66,6 @@ void MeshData::remove()
|
|||||||
void MeshData::update()
|
void MeshData::update()
|
||||||
{
|
{
|
||||||
Object *object = (Object *)id;
|
Object *object = (Object *)id;
|
||||||
if (parent_ != object->parent) {
|
|
||||||
parent_ = object->parent;
|
|
||||||
|
|
||||||
/* Looking for corresponded instancer and update it as parent */
|
|
||||||
for (Object *ob = parent_; ob != nullptr; ob = ob->parent) {
|
|
||||||
pxr::SdfPath i_id = scene_delegate_->instancer_prim_id(ob);
|
|
||||||
InstancerData *i_data = scene_delegate_->instancer_data(i_id);
|
|
||||||
if (i_data) {
|
|
||||||
i_data->update_as_parent();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
|
pxr::HdDirtyBits bits = pxr::HdChangeTracker::Clean;
|
||||||
if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
|
if ((id->recalc & ID_RECALC_GEOMETRY) || (((ID *)object->data)->recalc & ID_RECALC_GEOMETRY)) {
|
||||||
init();
|
init();
|
||||||
@ -126,9 +112,6 @@ pxr::VtValue MeshData::get_data(pxr::TfToken const &key) const
|
|||||||
else if (key == pxr::HdPrimvarRoleTokens->textureCoordinate) {
|
else if (key == pxr::HdPrimvarRoleTokens->textureCoordinate) {
|
||||||
ret = uvs_;
|
ret = uvs_;
|
||||||
}
|
}
|
||||||
else if (key == pxr::HdInstancerTokens->instanceTransform) {
|
|
||||||
ret = instances_;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,8 +218,10 @@ void MeshData::write_material()
|
|||||||
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
|
pxr::SdfPath p_id = scene_delegate_->material_prim_id(mat);
|
||||||
mat_data_ = scene_delegate_->material_data(p_id);
|
mat_data_ = scene_delegate_->material_data(p_id);
|
||||||
if (!mat_data_) {
|
if (!mat_data_) {
|
||||||
scene_delegate_->materials_[p_id] = MaterialData::create(scene_delegate_, mat, p_id);
|
scene_delegate_->materials_[p_id] = std::make_unique<MaterialData>(scene_delegate_, mat, p_id);
|
||||||
mat_data_ = scene_delegate_->material_data(p_id);
|
mat_data_ = scene_delegate_->material_data(p_id);
|
||||||
|
mat_data_->init();
|
||||||
|
mat_data_->insert();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,10 +40,8 @@ class MeshData : public ObjectData {
|
|||||||
pxr::VtVec3fArray vertices_;
|
pxr::VtVec3fArray vertices_;
|
||||||
pxr::VtVec2fArray uvs_;
|
pxr::VtVec2fArray uvs_;
|
||||||
pxr::VtVec3fArray normals_;
|
pxr::VtVec3fArray normals_;
|
||||||
pxr::VtMatrix4dArray instances_;
|
|
||||||
|
|
||||||
MaterialData *mat_data_ = nullptr;
|
MaterialData *mat_data_ = nullptr;
|
||||||
Object *parent_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::render::hydra
|
} // namespace blender::render::hydra
|
||||||
|
@ -13,7 +13,7 @@ namespace blender::render::hydra {
|
|||||||
ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate,
|
ObjectData::ObjectData(BlenderSceneDelegate *scene_delegate,
|
||||||
Object *object,
|
Object *object,
|
||||||
pxr::SdfPath const &prim_id)
|
pxr::SdfPath const &prim_id)
|
||||||
: IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0)), visible(true)
|
: IdData(scene_delegate, (ID *)object, prim_id), transform(pxr::GfMatrix4d(1.0))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,10 +39,6 @@ std::unique_ptr<ObjectData> ObjectData::create(BlenderSceneDelegate *scene_deleg
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (data) {
|
|
||||||
data->init();
|
|
||||||
data->insert();
|
|
||||||
}
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +74,25 @@ bool ObjectData::update_visibility()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectData::update_parent()
|
||||||
|
{
|
||||||
|
Object *object = (Object *)id;
|
||||||
|
if (parent_ != object->parent) {
|
||||||
|
ID_LOG(2, "");
|
||||||
|
parent_ = object->parent;
|
||||||
|
|
||||||
|
/* Looking for corresponded instancer and update it as parent */
|
||||||
|
for (Object *ob = parent_; ob != nullptr; ob = ob->parent) {
|
||||||
|
InstancerData *i_data = scene_delegate_->instancer_data(
|
||||||
|
scene_delegate_->instancer_prim_id(ob));
|
||||||
|
if (i_data) {
|
||||||
|
i_data->update_as_parent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectData::write_transform()
|
void ObjectData::write_transform()
|
||||||
{
|
{
|
||||||
transform = gf_matrix_from_transform(((Object *)id)->object_to_world);
|
transform = gf_matrix_from_transform(((Object *)id)->object_to_world);
|
||||||
|
@ -24,12 +24,15 @@ class ObjectData : public IdData {
|
|||||||
static bool is_supported(Object *object);
|
static bool is_supported(Object *object);
|
||||||
|
|
||||||
virtual bool update_visibility();
|
virtual bool update_visibility();
|
||||||
|
void update_parent();
|
||||||
|
|
||||||
pxr::GfMatrix4d transform;
|
pxr::GfMatrix4d transform;
|
||||||
bool visible;
|
bool visible = true;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void write_transform();
|
void write_transform();
|
||||||
|
|
||||||
|
Object *parent_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
using ObjectDataMap =
|
using ObjectDataMap =
|
||||||
|
@ -34,16 +34,6 @@ WorldData::WorldData(BlenderSceneDelegate *scene_delegate,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WorldData> WorldData::create(BlenderSceneDelegate *scene_delegate,
|
|
||||||
World *world,
|
|
||||||
pxr::SdfPath const &prim_id)
|
|
||||||
{
|
|
||||||
auto data = std::make_unique<WorldData>(scene_delegate, world, prim_id);
|
|
||||||
data->init();
|
|
||||||
data->insert();
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorldData::init()
|
void WorldData::init()
|
||||||
{
|
{
|
||||||
ID_LOG(2, "");
|
ID_LOG(2, "");
|
||||||
|
@ -22,10 +22,6 @@ class WorldData : public IdData {
|
|||||||
public:
|
public:
|
||||||
WorldData(BlenderSceneDelegate *scene_delegate, World *world, pxr::SdfPath const &prim_id);
|
WorldData(BlenderSceneDelegate *scene_delegate, World *world, pxr::SdfPath const &prim_id);
|
||||||
|
|
||||||
static std::unique_ptr<WorldData> create(BlenderSceneDelegate *scene_delegate,
|
|
||||||
World *world,
|
|
||||||
pxr::SdfPath const &prim_id);
|
|
||||||
|
|
||||||
void init() override;
|
void init() override;
|
||||||
void insert() override;
|
void insert() override;
|
||||||
void remove() override;
|
void remove() override;
|
||||||
|
Loading…
Reference in New Issue
Block a user