Remove dependency on Texture from ObjectManager.
ObjectManger now manages low-level filament Texture and Material objects directly. Moves the IBL Texture to the SceneBridge class. PiperOrigin-RevId: 900626110 Change-Id: Idd39464bfb324188dd54975a500954d4ebb29006
This commit is contained in:
committed by
Copybara-Service
parent
a6b98e5a78
commit
5a0809efaf
@@ -94,10 +94,10 @@ FilamentContext::~FilamentContext() {
|
|||||||
|
|
||||||
void FilamentContext::Init(const mjModel* model) {
|
void FilamentContext::Init(const mjModel* model) {
|
||||||
scene_view_ = std::make_unique<SceneView>(engine_);
|
scene_view_ = std::make_unique<SceneView>(engine_);
|
||||||
scene_bridge_ = std::make_unique<SceneBridge>(object_manager_.get(), model,
|
scene_bridge_ = std::make_unique<SceneBridge>(object_manager_.get(),
|
||||||
scene_view_.get());
|
scene_view_.get(), model);
|
||||||
imgui_bridge_ = std::make_unique<ImguiBridge>(
|
imgui_bridge_ =
|
||||||
scene_view_.get(), object_manager_->GetMaterial(ObjectManager::kUnlitUi));
|
std::make_unique<ImguiBridge>(object_manager_.get(), scene_view_.get());
|
||||||
|
|
||||||
// Set clear options.
|
// Set clear options.
|
||||||
filament::Renderer::ClearOptions opts;
|
filament::Renderer::ClearOptions opts;
|
||||||
|
|||||||
@@ -21,19 +21,19 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <filament/Material.h>
|
|
||||||
#include <math/vec4.h>
|
#include <math/vec4.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "experimental/filament/filament/material.h"
|
#include "experimental/filament/filament/material.h"
|
||||||
#include "experimental/filament/filament/mesh.h"
|
#include "experimental/filament/filament/mesh.h"
|
||||||
#include "experimental/filament/filament/renderable.h"
|
#include "experimental/filament/filament/renderable.h"
|
||||||
|
#include "experimental/filament/filament/object_manager.h"
|
||||||
#include "experimental/filament/filament/scene_view.h"
|
#include "experimental/filament/filament/scene_view.h"
|
||||||
#include "experimental/filament/filament/texture.h"
|
#include "experimental/filament/filament/texture.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
ImguiBridge::ImguiBridge(SceneView* scene_view, filament::Material* ui_material)
|
ImguiBridge::ImguiBridge(ObjectManager* object_mgr, SceneView* scene_view)
|
||||||
: scene_view_(scene_view), material_(ui_material) {}
|
: object_mgr_(object_mgr), scene_view_(scene_view) {}
|
||||||
|
|
||||||
ImguiBridge::~ImguiBridge() { PrepareRenderables(0); }
|
ImguiBridge::~ImguiBridge() { PrepareRenderables(0); }
|
||||||
|
|
||||||
@@ -270,14 +270,14 @@ void ImguiBridge::Update() {
|
|||||||
void ImguiBridge::PrepareRenderables(int count) {
|
void ImguiBridge::PrepareRenderables(int count) {
|
||||||
while (renderables_.size() < count) {
|
while (renderables_.size() < count) {
|
||||||
auto& r = renderables_.emplace_back(
|
auto& r = renderables_.emplace_back(
|
||||||
std::make_unique<Renderable>(scene_view_->GetEngine()));
|
std::make_unique<Renderable>(object_mgr_));
|
||||||
r->SetCastShadows(false);
|
r->SetCastShadows(false);
|
||||||
r->SetReceiveShadows(false);
|
r->SetReceiveShadows(false);
|
||||||
r->SetBlendOrder(static_cast<std::uint16_t>(renderables_.size()));
|
r->SetBlendOrder(static_cast<std::uint16_t>(renderables_.size()));
|
||||||
|
|
||||||
Material& material = r->GetMaterial();
|
Material& material = r->GetMaterial();
|
||||||
Material::DrawMode mode = Material::DrawMode::kNormal;
|
Material::DrawMode mode = Material::DrawMode::kNormal;
|
||||||
material.SetMaterial(mode, material_);
|
material.SetMaterial(mode, object_mgr_->GetMaterial(ObjectManager::kUnlitUi));
|
||||||
r->SetMaterialInstance(material.GetMaterialInstance(mode));
|
r->SetMaterialInstance(material.GetMaterialInstance(mode));
|
||||||
scene_view_->AddToUxScene(r.get());
|
scene_view_->AddToUxScene(r.get());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,18 +21,18 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <filament/Material.h>
|
|
||||||
#include "experimental/filament/filament/mesh.h"
|
#include "experimental/filament/filament/mesh.h"
|
||||||
#include "experimental/filament/filament/renderable.h"
|
#include "experimental/filament/filament/renderable.h"
|
||||||
#include "experimental/filament/filament/scene_view.h"
|
#include "experimental/filament/filament/scene_view.h"
|
||||||
#include "experimental/filament/filament/texture.h"
|
#include "experimental/filament/filament/texture.h"
|
||||||
|
#include "experimental/filament/filament/object_manager.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
// Manages Renderables that will be added a SceneView's UX scene.
|
// Manages Renderables that will be added a SceneView's UX scene.
|
||||||
class ImguiBridge {
|
class ImguiBridge {
|
||||||
public:
|
public:
|
||||||
ImguiBridge(SceneView* scene_view, filament::Material* ui_material);
|
ImguiBridge(ObjectManager* object_mgr, SceneView* scene_view);
|
||||||
~ImguiBridge();
|
~ImguiBridge();
|
||||||
|
|
||||||
// Prepares the Renderables using data from the current ImGui state. This
|
// Prepares the Renderables using data from the current ImGui state. This
|
||||||
@@ -59,8 +59,8 @@ class ImguiBridge {
|
|||||||
void UpdateTexture(ImTextureData* data);
|
void UpdateTexture(ImTextureData* data);
|
||||||
void DestroyTexture(ImTextureData* data);
|
void DestroyTexture(ImTextureData* data);
|
||||||
|
|
||||||
|
ObjectManager* object_mgr_ = nullptr;
|
||||||
SceneView* scene_view_ = nullptr;
|
SceneView* scene_view_ = nullptr;
|
||||||
filament::Material* material_ = nullptr;
|
|
||||||
std::vector<std::unique_ptr<Renderable>> renderables_;
|
std::vector<std::unique_ptr<Renderable>> renderables_;
|
||||||
std::vector<MeshPtr> meshes_;
|
std::vector<MeshPtr> meshes_;
|
||||||
std::unordered_map<uintptr_t, std::unique_ptr<Texture>> textures_;
|
std::unordered_map<uintptr_t, std::unique_ptr<Texture>> textures_;
|
||||||
|
|||||||
@@ -19,18 +19,20 @@
|
|||||||
#include <filament/MaterialInstance.h>
|
#include <filament/MaterialInstance.h>
|
||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
#include <filament/TextureSampler.h>
|
#include <filament/TextureSampler.h>
|
||||||
|
#include <mujoco/mujoco.h>
|
||||||
#include "experimental/filament/filament/texture.h"
|
#include "experimental/filament/filament/texture.h"
|
||||||
|
#include "experimental/filament/filament/object_manager.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
Material::Material(filament::Engine* engine)
|
Material::Material(ObjectManager* object_mgr)
|
||||||
: engine_(engine) {
|
: object_mgr_(object_mgr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Material::~Material() noexcept {
|
Material::~Material() noexcept {
|
||||||
for (int i = 0; i < kNumDrawModes; ++i) {
|
for (int i = 0; i < kNumDrawModes; ++i) {
|
||||||
if (instances_[i]) {
|
if (instances_[i]) {
|
||||||
engine_->destroy(instances_[i]);
|
GetEngine()->destroy(instances_[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,7 +45,7 @@ void Material::SetMaterial(DrawMode mode, filament::Material* material) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
engine_->destroy(instances_[mode]);
|
GetEngine()->destroy(instances_[mode]);
|
||||||
instances_[mode] = nullptr;
|
instances_[mode] = nullptr;
|
||||||
}
|
}
|
||||||
if (material) {
|
if (material) {
|
||||||
@@ -62,10 +64,6 @@ void Material::UpdateTextures(const Textures& textures) {
|
|||||||
UpdateMaterialInstances();
|
UpdateMaterialInstances();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Material::SetFallbackTextures(const Textures* fallback_textures) {
|
|
||||||
fallback_textures_ = fallback_textures;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Material::UpdateMaterialInstances() {
|
void Material::UpdateMaterialInstances() {
|
||||||
filament::MaterialInstance* instance = instances_[DrawMode::kNormal];
|
filament::MaterialInstance* instance = instances_[DrawMode::kNormal];
|
||||||
if (instance == nullptr) {
|
if (instance == nullptr) {
|
||||||
@@ -124,32 +122,24 @@ void Material::UpdateMaterialInstances() {
|
|||||||
filament::TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR);
|
filament::TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR);
|
||||||
|
|
||||||
auto TrySetTexture = [&](const char* name, const Texture* texture,
|
auto TrySetTexture = [&](const char* name, const Texture* texture,
|
||||||
const Texture* fallback) {
|
mjtTextureRole role) {
|
||||||
if (material->hasParameter(name)) {
|
if (material->hasParameter(name)) {
|
||||||
if (texture) {
|
if (texture != nullptr) {
|
||||||
instance->setParameter(name, texture->GetFilamentTexture(), sampler);
|
instance->setParameter(name, texture->GetFilamentTexture(), sampler);
|
||||||
} else if (fallback) {
|
} else {
|
||||||
instance->setParameter(name, fallback->GetFilamentTexture(), sampler);
|
instance->setParameter(name, object_mgr_->GetFallbackTexture(role), sampler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TrySetTexture("BaseColor", textures_.color,
|
TrySetTexture("BaseColor", textures_.color, mjTEXROLE_RGB);
|
||||||
fallback_textures_ ? fallback_textures_->color : nullptr);
|
TrySetTexture("Normal", textures_.normal, mjTEXROLE_NORMAL);
|
||||||
TrySetTexture("Normal", textures_.normal,
|
TrySetTexture("Metallic", textures_.metallic, mjTEXROLE_METALLIC);
|
||||||
fallback_textures_ ? fallback_textures_->normal : nullptr);
|
TrySetTexture("Roughness", textures_.roughness, mjTEXROLE_ROUGHNESS);
|
||||||
TrySetTexture("Metallic", textures_.metallic,
|
TrySetTexture("Occlusion", textures_.occlusion, mjTEXROLE_OCCLUSION);
|
||||||
fallback_textures_ ? fallback_textures_->metallic : nullptr);
|
TrySetTexture("ORM", textures_.orm, mjTEXROLE_ORM);
|
||||||
TrySetTexture("Roughness", textures_.roughness,
|
TrySetTexture("Emissive", textures_.emissive, mjTEXROLE_EMISSIVE);
|
||||||
fallback_textures_ ? fallback_textures_->roughness : nullptr);
|
TrySetTexture("Reflection", textures_.reflection, mjTEXROLE_USER);
|
||||||
TrySetTexture("Occlusion", textures_.occlusion,
|
|
||||||
fallback_textures_ ? fallback_textures_->occlusion : nullptr);
|
|
||||||
TrySetTexture("ORM", textures_.orm,
|
|
||||||
fallback_textures_ ? fallback_textures_->orm : nullptr);
|
|
||||||
TrySetTexture("Emissive", textures_.emissive,
|
|
||||||
fallback_textures_ ? fallback_textures_->emissive : nullptr);
|
|
||||||
TrySetTexture("Reflection", textures_.reflection,
|
|
||||||
fallback_textures_ ? fallback_textures_->reflection : nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include <math/vec3.h>
|
#include <math/vec3.h>
|
||||||
#include <math/vec4.h>
|
#include <math/vec4.h>
|
||||||
#include "experimental/filament/filament/texture.h"
|
#include "experimental/filament/filament/texture.h"
|
||||||
|
#include "experimental/filament/filament/object_manager.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
@@ -66,7 +67,7 @@ class Material {
|
|||||||
bool reflective = false;
|
bool reflective = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Material(filament::Engine* engine);
|
explicit Material(ObjectManager* object_mgr);
|
||||||
~Material() noexcept;
|
~Material() noexcept;
|
||||||
|
|
||||||
Material(const Material&) = delete;
|
Material(const Material&) = delete;
|
||||||
@@ -75,9 +76,6 @@ class Material {
|
|||||||
// Assigns a material to the draw mode.
|
// Assigns a material to the draw mode.
|
||||||
void SetMaterial(DrawMode mode, filament::Material* material);
|
void SetMaterial(DrawMode mode, filament::Material* material);
|
||||||
|
|
||||||
// Sets the fallback textures for the material.
|
|
||||||
void SetFallbackTextures(const Textures* fallback_textures);
|
|
||||||
|
|
||||||
// Updates the parameters for the material.
|
// Updates the parameters for the material.
|
||||||
void UpdateParams(const Params& params);
|
void UpdateParams(const Params& params);
|
||||||
|
|
||||||
@@ -96,16 +94,15 @@ class Material {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the filament Engine managing the material.
|
// Returns the filament Engine managing the material.
|
||||||
filament::Engine* GetEngine() const { return engine_; }
|
filament::Engine* GetEngine() const { return object_mgr_->GetEngine(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Updates the material instances based on the currently set parameters and
|
// Updates the material instances based on the currently set parameters and
|
||||||
// textures.
|
// textures.
|
||||||
void UpdateMaterialInstances();
|
void UpdateMaterialInstances();
|
||||||
|
|
||||||
filament::Engine* engine_ = nullptr;
|
ObjectManager* object_mgr_;
|
||||||
filament::MaterialInstance* instances_[kNumDrawModes] = {nullptr};
|
filament::MaterialInstance* instances_[kNumDrawModes] = {nullptr};
|
||||||
const Textures* fallback_textures_ = nullptr;
|
|
||||||
Params params_;
|
Params params_;
|
||||||
Textures textures_;
|
Textures textures_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
@@ -24,40 +25,33 @@
|
|||||||
#include <filament/IndirectLight.h>
|
#include <filament/IndirectLight.h>
|
||||||
#include <filament/Material.h>
|
#include <filament/Material.h>
|
||||||
#include <filament/Skybox.h>
|
#include <filament/Skybox.h>
|
||||||
#include <math/mat3.h>
|
#include <filament/Texture.h>
|
||||||
#include <math/scalar.h>
|
|
||||||
#include <math/vec3.h>
|
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "experimental/filament/filament/texture.h"
|
#include "experimental/filament/filament/texture.h"
|
||||||
#include "user/user_resource.h"
|
#include "user/user_resource.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
namespace {
|
|
||||||
|
|
||||||
// Loads binary data from a file using mjrFilamentConfig callbacks.
|
static std::string GetAssetPath(std::string_view filename) {
|
||||||
struct Asset {
|
std::string path = "filament:" + std::string(filename);
|
||||||
explicit Asset(std::string_view filename) {
|
return path;
|
||||||
std::string path = "filament:" + std::string(filename);
|
}
|
||||||
|
|
||||||
resource = mju_openResource("", path.c_str(), nullptr, nullptr, 0);
|
ObjectManager::Asset::Asset(std::string_view filename) {
|
||||||
size = mju_readResource(resource, const_cast<const void**>(&payload));
|
std::string path = GetAssetPath(filename);
|
||||||
|
resource = mju_openResource("", path.c_str(), nullptr, nullptr, 0);
|
||||||
|
size = mju_readResource(resource, const_cast<const void**>(&payload));
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectManager::Asset::~Asset() {
|
||||||
|
if (resource) {
|
||||||
|
mju_closeResource(resource);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
~Asset() {
|
std::span<const std::byte> ObjectManager::Asset::GetBytes() const {
|
||||||
if (resource) {
|
return {reinterpret_cast<const std::byte*>(payload), size};
|
||||||
mju_closeResource(resource);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Asset(const Asset&) = delete;
|
|
||||||
Asset& operator=(const Asset&) = delete;
|
|
||||||
|
|
||||||
int size = 0;
|
|
||||||
void* payload = nullptr;
|
|
||||||
mjResource* resource = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
ObjectManager::ObjectManager(filament::Engine* engine)
|
ObjectManager::ObjectManager(filament::Engine* engine)
|
||||||
: engine_(engine) {
|
: engine_(engine) {
|
||||||
@@ -93,24 +87,16 @@ ObjectManager::ObjectManager(filament::Engine* engine)
|
|||||||
static uint8_t normal_data[3] = {128, 128, 255};
|
static uint8_t normal_data[3] = {128, 128, 255};
|
||||||
static uint8_t orm_data[3] = {0, 255, 0};
|
static uint8_t orm_data[3] = {0, 255, 0};
|
||||||
|
|
||||||
TextureConfig config;
|
auto CreateFallbackTexture = [this](uint8_t color[3]) {
|
||||||
DefaultTextureConfig(&config);
|
filament::Texture::Builder builder;
|
||||||
config.width = 1;
|
builder.width(1);
|
||||||
config.height = 1;
|
builder.height(1);
|
||||||
config.target = mjTEXTURE_2D;
|
builder.format(filament::Texture::InternalFormat::RGB8);
|
||||||
config.format = mjPIXEL_FORMAT_RGB8;
|
builder.sampler(filament::Texture::Sampler::SAMPLER_2D);
|
||||||
config.color_space = mjCOLORSPACE_LINEAR;
|
filament::Texture* texture = builder.build(*engine_);
|
||||||
|
const filament::Texture::Type type = filament::Texture::Type::UBYTE;
|
||||||
auto CreateFallbackTexture = [this, &config](uint8_t color[3]) {
|
const filament::Texture::Format format = filament::Texture::Format::RGB;
|
||||||
auto texture = std::make_unique<Texture>(engine_, config);
|
texture->setImage(*engine_, 0, {color, 3, format, type});
|
||||||
|
|
||||||
TextureData payload;
|
|
||||||
DefaultTextureData(&payload);
|
|
||||||
payload.bytes = color;
|
|
||||||
payload.nbytes = 3;
|
|
||||||
payload.release_callback = nullptr;
|
|
||||||
payload.user_data = nullptr;
|
|
||||||
texture->Upload(payload);
|
|
||||||
return texture;
|
return texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -119,19 +105,21 @@ ObjectManager::ObjectManager(filament::Engine* engine)
|
|||||||
fallback_normal_ = CreateFallbackTexture(normal_data);
|
fallback_normal_ = CreateFallbackTexture(normal_data);
|
||||||
fallback_orm_ = CreateFallbackTexture(orm_data);
|
fallback_orm_ = CreateFallbackTexture(orm_data);
|
||||||
|
|
||||||
fallback_textures_[mjTEXROLE_USER] = fallback_black_.get();
|
fallback_textures_[mjTEXROLE_USER] = fallback_black_;
|
||||||
fallback_textures_[mjTEXROLE_RGB] = fallback_white_.get();
|
fallback_textures_[mjTEXROLE_RGB] = fallback_white_;
|
||||||
fallback_textures_[mjTEXROLE_OCCLUSION] = fallback_white_.get();
|
fallback_textures_[mjTEXROLE_OCCLUSION] = fallback_white_;
|
||||||
fallback_textures_[mjTEXROLE_ROUGHNESS] = fallback_white_.get();
|
fallback_textures_[mjTEXROLE_ROUGHNESS] = fallback_white_;
|
||||||
fallback_textures_[mjTEXROLE_METALLIC] = fallback_black_.get();
|
fallback_textures_[mjTEXROLE_METALLIC] = fallback_black_;
|
||||||
fallback_textures_[mjTEXROLE_NORMAL] = fallback_normal_.get();
|
fallback_textures_[mjTEXROLE_NORMAL] = fallback_normal_;
|
||||||
fallback_textures_[mjTEXROLE_EMISSIVE] = fallback_black_.get();
|
fallback_textures_[mjTEXROLE_EMISSIVE] = fallback_black_;
|
||||||
fallback_textures_[mjTEXROLE_ORM] = fallback_orm_.get();
|
fallback_textures_[mjTEXROLE_ORM] = fallback_orm_;
|
||||||
|
|
||||||
LoadFallbackIndirectLight("ibl.ktx");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectManager::~ObjectManager() {
|
ObjectManager::~ObjectManager() {
|
||||||
|
engine_->destroy(fallback_black_);
|
||||||
|
engine_->destroy(fallback_white_);
|
||||||
|
engine_->destroy(fallback_normal_);
|
||||||
|
engine_->destroy(fallback_orm_);
|
||||||
for (auto& iter : materials_) {
|
for (auto& iter : materials_) {
|
||||||
engine_->destroy(iter);
|
engine_->destroy(iter);
|
||||||
}
|
}
|
||||||
@@ -144,7 +132,7 @@ filament::Material* ObjectManager::GetMaterial(MaterialType type) const {
|
|||||||
return materials_[type];
|
return materials_[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Texture* ObjectManager::GetFallbackTexture(
|
const filament::Texture* ObjectManager::GetFallbackTexture(
|
||||||
mjtTextureRole role) const {
|
mjtTextureRole role) const {
|
||||||
if (role < 0 || role >= mjNTEXROLE) {
|
if (role < 0 || role >= mjNTEXROLE) {
|
||||||
mju_error("Invalid texture role: %d", role);
|
mju_error("Invalid texture role: %d", role);
|
||||||
@@ -152,39 +140,8 @@ const Texture* ObjectManager::GetFallbackTexture(
|
|||||||
return fallback_textures_[role];
|
return fallback_textures_[role];
|
||||||
}
|
}
|
||||||
|
|
||||||
const Texture* ObjectManager::GetFallbackIndirectLightTexture() {
|
std::unique_ptr<ObjectManager::Asset> ObjectManager::LoadAsset(
|
||||||
return fallback_indirect_light_texture_.get();
|
std::string_view filename) {
|
||||||
}
|
return std::unique_ptr<Asset>(new Asset(filename));
|
||||||
|
|
||||||
void ObjectManager::LoadFallbackIndirectLight(std::string_view filename) {
|
|
||||||
fallback_indirect_light_texture_.reset();
|
|
||||||
|
|
||||||
Asset* asset = new Asset(filename);
|
|
||||||
auto release_asset = +[](void* user_data) {
|
|
||||||
delete static_cast<Asset*>(user_data);
|
|
||||||
};
|
|
||||||
if (asset->size == 0) {
|
|
||||||
release_asset(asset);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureConfig config;
|
|
||||||
DefaultTextureConfig(&config);
|
|
||||||
config.width = 1;
|
|
||||||
config.height = 1;
|
|
||||||
config.target = mjTEXTURE_CUBE;
|
|
||||||
config.format = mjPIXEL_FORMAT_KTX;
|
|
||||||
config.color_space = mjCOLORSPACE_AUTO;
|
|
||||||
|
|
||||||
fallback_indirect_light_texture_ = std::make_unique<Texture>(engine_, config);
|
|
||||||
|
|
||||||
TextureData payload;
|
|
||||||
DefaultTextureData(&payload);
|
|
||||||
payload.bytes = asset->payload;
|
|
||||||
payload.nbytes = static_cast<size_t>(asset->size);
|
|
||||||
payload.release_callback = release_asset;
|
|
||||||
payload.user_data = asset;
|
|
||||||
|
|
||||||
fallback_indirect_light_texture_->Upload(payload);
|
|
||||||
}
|
}
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
@@ -16,20 +16,39 @@
|
|||||||
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_OBJECT_MANAGER_H_
|
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_OBJECT_MANAGER_H_
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <span>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/IndirectLight.h>
|
#include <filament/IndirectLight.h>
|
||||||
#include <filament/Skybox.h>
|
#include <filament/Skybox.h>
|
||||||
|
#include <filament/Texture.h>
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "experimental/filament/filament/texture.h"
|
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
// Creates and owns various filament objects based on the data in a mjrContext.
|
// Creates and owns various filament objects based on the data in a mjrContext.
|
||||||
class ObjectManager {
|
class ObjectManager {
|
||||||
public:
|
public:
|
||||||
|
class Asset {
|
||||||
|
public:
|
||||||
|
~Asset();
|
||||||
|
|
||||||
|
std::span<const std::byte> GetBytes() const;
|
||||||
|
|
||||||
|
Asset(const Asset&) = delete;
|
||||||
|
Asset& operator=(const Asset&) = delete;
|
||||||
|
private:
|
||||||
|
friend class ObjectManager;
|
||||||
|
explicit Asset(std::string_view filename);
|
||||||
|
|
||||||
|
std::size_t size = 0;
|
||||||
|
void* payload = nullptr;
|
||||||
|
mjResource* resource = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
ObjectManager(filament::Engine* engine);
|
ObjectManager(filament::Engine* engine);
|
||||||
~ObjectManager();
|
~ObjectManager();
|
||||||
|
|
||||||
@@ -63,13 +82,13 @@ class ObjectManager {
|
|||||||
filament::Material* GetMaterial(MaterialType type) const;
|
filament::Material* GetMaterial(MaterialType type) const;
|
||||||
|
|
||||||
// Returns the fallback Texture with the given role.
|
// Returns the fallback Texture with the given role.
|
||||||
const Texture* GetFallbackTexture(mjtTextureRole role) const;
|
const filament::Texture* GetFallbackTexture(mjtTextureRole role) const;
|
||||||
|
|
||||||
// Returns the fallback IndirectLight.
|
// Loads the given asset from the filament resource directory.
|
||||||
const Texture* GetFallbackIndirectLightTexture();
|
std::unique_ptr<Asset> LoadAsset(std::string_view filename);
|
||||||
|
|
||||||
// Loads an indirect light from a file, setting it to the fallback.
|
// The default environment light to use if no environment light is specified.
|
||||||
void LoadFallbackIndirectLight(std::string_view filename);
|
static constexpr const char* kDefaultEnvironmentLight = "ibl.ktx";
|
||||||
|
|
||||||
ObjectManager(const ObjectManager&) = delete;
|
ObjectManager(const ObjectManager&) = delete;
|
||||||
ObjectManager& operator=(const ObjectManager&) = delete;
|
ObjectManager& operator=(const ObjectManager&) = delete;
|
||||||
@@ -77,12 +96,11 @@ class ObjectManager {
|
|||||||
private:
|
private:
|
||||||
filament::Engine* engine_ = nullptr;
|
filament::Engine* engine_ = nullptr;
|
||||||
std::array<filament::Material*, kNumMaterials> materials_;
|
std::array<filament::Material*, kNumMaterials> materials_;
|
||||||
std::array<Texture*, mjNTEXROLE> fallback_textures_;
|
std::array<filament::Texture*, mjNTEXROLE> fallback_textures_;
|
||||||
std::unique_ptr<Texture> fallback_white_ = nullptr;
|
filament::Texture* fallback_white_ = nullptr;
|
||||||
std::unique_ptr<Texture> fallback_black_ = nullptr;
|
filament::Texture* fallback_black_ = nullptr;
|
||||||
std::unique_ptr<Texture> fallback_normal_ = nullptr;
|
filament::Texture* fallback_normal_ = nullptr;
|
||||||
std::unique_ptr<Texture> fallback_orm_ = nullptr;
|
filament::Texture* fallback_orm_ = nullptr;
|
||||||
std::unique_ptr<Texture> fallback_indirect_light_texture_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
@@ -24,10 +24,11 @@
|
|||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
#include "experimental/filament/filament/material.h"
|
#include "experimental/filament/filament/material.h"
|
||||||
#include "experimental/filament/filament/mesh.h"
|
#include "experimental/filament/filament/mesh.h"
|
||||||
|
#include "experimental/filament/filament/object_manager.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
Renderable::Renderable(filament::Engine* engine) : material_(engine) {}
|
Renderable::Renderable(ObjectManager* object_mgr) : material_(object_mgr) {}
|
||||||
|
|
||||||
Renderable::~Renderable() noexcept {
|
Renderable::~Renderable() noexcept {
|
||||||
while (!entities_.empty()) {
|
while (!entities_.empty()) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <utils/Entity.h>
|
#include <utils/Entity.h>
|
||||||
#include "experimental/filament/filament/material.h"
|
#include "experimental/filament/filament/material.h"
|
||||||
#include "experimental/filament/filament/mesh.h"
|
#include "experimental/filament/filament/mesh.h"
|
||||||
|
#include "experimental/filament/filament/object_manager.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ class Renderable {
|
|||||||
static constexpr std::uint8_t kDefaultPriority = 4;
|
static constexpr std::uint8_t kDefaultPriority = 4;
|
||||||
static constexpr std::uint8_t kDefaultLayerMask = 0x01;
|
static constexpr std::uint8_t kDefaultLayerMask = 0x01;
|
||||||
|
|
||||||
Renderable(filament::Engine* engine);
|
explicit Renderable(ObjectManager* object_mgr);
|
||||||
~Renderable() noexcept;
|
~Renderable() noexcept;
|
||||||
|
|
||||||
Renderable(const Renderable&) = delete;
|
Renderable(const Renderable&) = delete;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "experimental/filament/filament/renderable.h"
|
#include "experimental/filament/filament/renderable.h"
|
||||||
#include "experimental/filament/filament/scene_geom_util.h"
|
#include "experimental/filament/filament/scene_geom_util.h"
|
||||||
#include "experimental/filament/filament/scene_view.h"
|
#include "experimental/filament/filament/scene_view.h"
|
||||||
|
#include "experimental/filament/filament/texture.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
@@ -55,8 +56,39 @@ using filament::math::float4;
|
|||||||
using filament::math::mat3;
|
using filament::math::mat3;
|
||||||
using filament::math::mat4;
|
using filament::math::mat4;
|
||||||
|
|
||||||
SceneBridge::SceneBridge(ObjectManager* object_mgr, const mjModel* model,
|
static std::unique_ptr<Texture> CreateFallbackIndirectLightTexture(
|
||||||
SceneView* scene_view)
|
ObjectManager* object_mgr, std::string_view filename = "") {
|
||||||
|
if (filename.empty()) {
|
||||||
|
filename = ObjectManager::kDefaultEnvironmentLight;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ObjectManager::Asset> asset = object_mgr->LoadAsset(filename);
|
||||||
|
|
||||||
|
TextureConfig config;
|
||||||
|
DefaultTextureConfig(&config);
|
||||||
|
config.width = 1;
|
||||||
|
config.height = 1;
|
||||||
|
config.target = mjTEXTURE_CUBE;
|
||||||
|
config.format = mjPIXEL_FORMAT_KTX;
|
||||||
|
config.color_space = mjCOLORSPACE_AUTO;
|
||||||
|
|
||||||
|
auto texture = std::make_unique<Texture>(object_mgr->GetEngine(), config);
|
||||||
|
|
||||||
|
TextureData payload;
|
||||||
|
DefaultTextureData(&payload);
|
||||||
|
payload.bytes = (void*)asset->GetBytes().data();
|
||||||
|
payload.nbytes = asset->GetBytes().size();
|
||||||
|
payload.release_callback = +[](void* user_data) {
|
||||||
|
delete static_cast<ObjectManager::Asset*>(user_data);
|
||||||
|
};
|
||||||
|
payload.user_data = asset.release();
|
||||||
|
|
||||||
|
texture->Upload(payload);
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneBridge::SceneBridge(ObjectManager* object_mgr, SceneView* scene_view,
|
||||||
|
const mjModel* model)
|
||||||
: scene_view_(scene_view), object_mgr_(object_mgr) {
|
: scene_view_(scene_view), object_mgr_(object_mgr) {
|
||||||
model_objects_ =
|
model_objects_ =
|
||||||
std::make_unique<ModelObjects>(model, object_mgr_->GetEngine());
|
std::make_unique<ModelObjects>(model, object_mgr_->GetEngine());
|
||||||
@@ -140,14 +172,6 @@ SceneBridge::SceneBridge(ObjectManager* object_mgr, const mjModel* model,
|
|||||||
ReadElement(model, "filament.fallback.environment_light_intensity",
|
ReadElement(model, "filament.fallback.environment_light_intensity",
|
||||||
fallback_environment_light_intensity_);
|
fallback_environment_light_intensity_);
|
||||||
|
|
||||||
fallback_textures_.color = object_mgr_->GetFallbackTexture(mjTEXROLE_RGB);
|
|
||||||
fallback_textures_.normal = object_mgr_->GetFallbackTexture(mjTEXROLE_NORMAL);
|
|
||||||
fallback_textures_.metallic = object_mgr_->GetFallbackTexture(mjTEXROLE_METALLIC);
|
|
||||||
fallback_textures_.roughness = object_mgr_->GetFallbackTexture(mjTEXROLE_ROUGHNESS);
|
|
||||||
fallback_textures_.occlusion = object_mgr_->GetFallbackTexture(mjTEXROLE_OCCLUSION);
|
|
||||||
fallback_textures_.orm = object_mgr_->GetFallbackTexture(mjTEXROLE_ORM);
|
|
||||||
fallback_textures_.emissive = object_mgr_->GetFallbackTexture(mjTEXROLE_EMISSIVE);
|
|
||||||
fallback_textures_.reflection = object_mgr_->GetFallbackTexture(mjTEXROLE_USER);
|
|
||||||
PrepareLights();
|
PrepareLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +188,7 @@ SceneBridge::~SceneBridge() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SceneBridge::SetEnvironmentLight(std::string_view filename,
|
void SceneBridge::SetEnvironmentLight(std::string_view filename,
|
||||||
float intensity) {
|
float intensity) {
|
||||||
for (auto& light : lights_) {
|
for (auto& light : lights_) {
|
||||||
if (light->GetType() == mjLIGHT_IMAGE) {
|
if (light->GetType() == mjLIGHT_IMAGE) {
|
||||||
scene_view_->RemoveFromScene(light.get());
|
scene_view_->RemoveFromScene(light.get());
|
||||||
@@ -177,11 +201,12 @@ void SceneBridge::SetEnvironmentLight(std::string_view filename,
|
|||||||
fallback_ibl_.reset();
|
fallback_ibl_.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
object_mgr_->LoadFallbackIndirectLight(filename);
|
fallback_ibl_texture_ =
|
||||||
|
CreateFallbackIndirectLightTexture(object_mgr_, filename);
|
||||||
|
|
||||||
Light::Params params;
|
Light::Params params;
|
||||||
params.type = mjLIGHT_IMAGE;
|
params.type = mjLIGHT_IMAGE;
|
||||||
params.texture = object_mgr_->GetFallbackIndirectLightTexture();
|
params.texture = fallback_ibl_texture_.get();
|
||||||
params.intensity = intensity;
|
params.intensity = intensity;
|
||||||
fallback_ibl_ = std::make_unique<Light>(object_mgr_->GetEngine(), params);
|
fallback_ibl_ = std::make_unique<Light>(object_mgr_->GetEngine(), params);
|
||||||
scene_view_->AddToScene(fallback_ibl_.get());
|
scene_view_->AddToScene(fallback_ibl_.get());
|
||||||
@@ -274,9 +299,11 @@ void SceneBridge::PrepareLights() {
|
|||||||
// default environment light and set the light intensity ourselves.
|
// default environment light and set the light intensity ourselves.
|
||||||
if (total_light_intensity == 0.0f) {
|
if (total_light_intensity == 0.0f) {
|
||||||
// Create a fallback environment light.
|
// Create a fallback environment light.
|
||||||
|
fallback_ibl_texture_ = CreateFallbackIndirectLightTexture(object_mgr_);
|
||||||
|
|
||||||
Light::Params params;
|
Light::Params params;
|
||||||
params.type = mjLIGHT_IMAGE;
|
params.type = mjLIGHT_IMAGE;
|
||||||
params.texture = object_mgr_->GetFallbackIndirectLightTexture();
|
params.texture = fallback_ibl_texture_.get();
|
||||||
params.intensity = fallback_environment_light_intensity_;
|
params.intensity = fallback_environment_light_intensity_;
|
||||||
fallback_ibl_ = std::make_unique<Light>(engine, params);
|
fallback_ibl_ = std::make_unique<Light>(engine, params);
|
||||||
scene_view_->AddToScene(fallback_ibl_.get());
|
scene_view_->AddToScene(fallback_ibl_.get());
|
||||||
@@ -354,9 +381,8 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Renderable> renderable =
|
std::unique_ptr<Renderable> renderable = CreateGeomRenderable(
|
||||||
CreateGeomRenderable(*geom, scene, object_mgr_, model_objects_.get(),
|
*geom, scene, object_mgr_, model_objects_.get(), headpos);
|
||||||
headpos, &fallback_textures_);
|
|
||||||
|
|
||||||
scene_view_->AddToScene(renderable.get());
|
scene_view_->AddToScene(renderable.get());
|
||||||
renderables_.push_back(std::move(renderable));
|
renderables_.push_back(std::move(renderable));
|
||||||
|
|||||||
@@ -30,14 +30,15 @@
|
|||||||
#include "experimental/filament/filament/object_manager.h"
|
#include "experimental/filament/filament/object_manager.h"
|
||||||
#include "experimental/filament/filament/renderable.h"
|
#include "experimental/filament/filament/renderable.h"
|
||||||
#include "experimental/filament/filament/scene_view.h"
|
#include "experimental/filament/filament/scene_view.h"
|
||||||
|
#include "experimental/filament/filament/texture.h"
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
// Manages all mjModel data and updates a SceneView using an mjvScene.
|
// Manages all mjModel data and updates a SceneView using an mjvScene.
|
||||||
class SceneBridge {
|
class SceneBridge {
|
||||||
public:
|
public:
|
||||||
SceneBridge(ObjectManager* object_mgr, const mjModel* model,
|
SceneBridge(ObjectManager* object_mgr, SceneView* scene_view,
|
||||||
SceneView* scene_view);
|
const mjModel* model);
|
||||||
~SceneBridge();
|
~SceneBridge();
|
||||||
|
|
||||||
// Updates the environment light using the KTX image at the given path.
|
// Updates the environment light using the KTX image at the given path.
|
||||||
@@ -72,6 +73,7 @@ class SceneBridge {
|
|||||||
ObjectManager* object_mgr_ = nullptr;
|
ObjectManager* object_mgr_ = nullptr;
|
||||||
std::unique_ptr<ModelObjects> model_objects_;
|
std::unique_ptr<ModelObjects> model_objects_;
|
||||||
std::unique_ptr<Light> fallback_ibl_;
|
std::unique_ptr<Light> fallback_ibl_;
|
||||||
|
std::unique_ptr<Texture> fallback_ibl_texture_;
|
||||||
std::vector<std::unique_ptr<Light>> lights_;
|
std::vector<std::unique_ptr<Light>> lights_;
|
||||||
std::vector<std::unique_ptr<Renderable>> renderables_;
|
std::vector<std::unique_ptr<Renderable>> renderables_;
|
||||||
filament::math::mat4 clip_from_world_;
|
filament::math::mat4 clip_from_world_;
|
||||||
@@ -80,7 +82,6 @@ class SceneBridge {
|
|||||||
float fallback_head_light_intensity_ = 0.f;
|
float fallback_head_light_intensity_ = 0.f;
|
||||||
float fallback_scene_light_intensity_ = 80'000.f;
|
float fallback_scene_light_intensity_ = 80'000.f;
|
||||||
float fallback_environment_light_intensity_ = 5'000.f;
|
float fallback_environment_light_intensity_ = 5'000.f;
|
||||||
Material::Textures fallback_textures_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
@@ -546,15 +546,13 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom,
|
|||||||
|
|
||||||
std::unique_ptr<Renderable> CreateGeomRenderable(
|
std::unique_ptr<Renderable> CreateGeomRenderable(
|
||||||
const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr,
|
const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr,
|
||||||
ModelObjects* model_objs, const float headpos[3],
|
ModelObjects* model_objs, const float headpos[3]) {
|
||||||
Material::Textures* fallback_textures) {
|
auto renderable = std::make_unique<Renderable>(object_mgr);
|
||||||
auto renderable = std::make_unique<Renderable>(model_objs->GetEngine());
|
|
||||||
|
|
||||||
// The order of these calls is important. e.g. We need to create the filament
|
// The order of these calls is important. e.g. We need to create the filament
|
||||||
// renderable entities before we can set their transform.
|
// renderable entities before we can set their transform.
|
||||||
PrepareGeomMeshes(*renderable, geom, scene, model_objs);
|
PrepareGeomMeshes(*renderable, geom, scene, model_objs);
|
||||||
SetGeomTransform(*renderable, geom);
|
SetGeomTransform(*renderable, geom);
|
||||||
renderable->GetMaterial().SetFallbackTextures(fallback_textures);
|
|
||||||
UpdateGeomMaterial(*renderable, geom, scene, model_objs, object_mgr, headpos);
|
UpdateGeomMaterial(*renderable, geom, scene, model_objs, object_mgr, headpos);
|
||||||
|
|
||||||
return renderable;
|
return renderable;
|
||||||
|
|||||||
@@ -28,8 +28,7 @@ namespace mujoco {
|
|||||||
// Creates a Renderable from the given mjvGeom.
|
// Creates a Renderable from the given mjvGeom.
|
||||||
std::unique_ptr<Renderable> CreateGeomRenderable(
|
std::unique_ptr<Renderable> CreateGeomRenderable(
|
||||||
const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr,
|
const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr,
|
||||||
ModelObjects* model_objs, const float headpos[3],
|
ModelObjects* model_objs, const float headpos[3]);
|
||||||
Material::Textures* fallback_textures);
|
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user