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