diff --git a/src/experimental/filament/compat/imgui_bridge.cc b/src/experimental/filament/compat/imgui_bridge.cc index c7b83514..6b303f05 100644 --- a/src/experimental/filament/compat/imgui_bridge.cc +++ b/src/experimental/filament/compat/imgui_bridge.cc @@ -24,20 +24,20 @@ #include #include #include -#include "experimental/filament/filament/material.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/mesh.h" -#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" +#include "experimental/filament/render_context_filament.h" namespace mujoco { using filament::math::float3; using filament::math::mat3f; -ImguiBridge::ImguiBridge(ObjectManager* object_mgr) : object_mgr_(object_mgr) { - scene_view_ = std::make_unique(object_mgr_->GetEngine()); +ImguiBridge::ImguiBridge(FilamentContext* ctx) : ctx_(ctx) { + scene_view_ = std::make_unique(ctx_); scene_view_->DisableShadows(); scene_view_->DisableReflections(); scene_view_->DisablePostProcessing(); @@ -88,7 +88,7 @@ uintptr_t ImguiBridge::UploadImage(uintptr_t tex_id, const uint8_t* pixels, config.target = mjTEXTURE_2D; config.format = bpp == 4 ? mjPIXEL_FORMAT_RGBA8 : mjPIXEL_FORMAT_RGB8; config.color_space = mjCOLORSPACE_LINEAR; - texture = std::make_unique(scene_view_->GetEngine(), config); + texture = std::make_unique(ctx_, config); } // Create a copy of the image to pass it to filament as we don't know the @@ -124,8 +124,7 @@ void ImguiBridge::CreateTexture(ImTextureData* data) { config.color_space = mjCOLORSPACE_LINEAR; const uintptr_t tex_id = next_tex_id_++; - textures_[tex_id] = - std::make_unique(scene_view_->GetEngine(), config); + textures_[tex_id] = std::make_unique(ctx_, config); data->SetTexID((ImTextureID)tex_id); UpdateTexture(data); } @@ -232,7 +231,7 @@ void ImguiBridge::Update() { data.indices = cmds->IdxBuffer.Data; data.index_type = mjINDEX_TYPE_U16; data.primitive_type = mjMESH_PRIMITIVE_TYPE_TRIANGLES; - meshes_.push_back(std::make_unique(scene_view_->GetEngine(), data)); + meshes_.push_back(std::make_unique(ctx_, data)); const Mesh* mesh = meshes_.back().get(); @@ -278,8 +277,8 @@ void ImguiBridge::PrepareRenderables(int count) { mjrRenderableParams params; mjr_defaultRenderableParams(¶ms); params.shading_model = mjSHADING_MODEL_UX; - auto& r = renderables_.emplace_back( - std::make_unique(object_mgr_, params)); + auto& r = + renderables_.emplace_back(std::make_unique(ctx_, params)); r->SetCastShadows(false); r->SetReceiveShadows(false); r->SetBlendOrder(static_cast(renderables_.size())); diff --git a/src/experimental/filament/compat/imgui_bridge.h b/src/experimental/filament/compat/imgui_bridge.h index 953cbd1e..756456fc 100644 --- a/src/experimental/filament/compat/imgui_bridge.h +++ b/src/experimental/filament/compat/imgui_bridge.h @@ -21,18 +21,18 @@ #include #include +#include "experimental/filament/filament/filament_context.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 { // Creates and manages a SceneView using data read from ImGui. class ImguiBridge { public: - explicit ImguiBridge(ObjectManager* object_mgr); + explicit ImguiBridge(FilamentContext* ctx); ~ImguiBridge(); // Prepares the Renderables using data from the current ImGui state. This @@ -59,7 +59,7 @@ class ImguiBridge { void UpdateTexture(ImTextureData* data); void DestroyTexture(ImTextureData* data); - ObjectManager* object_mgr_ = nullptr; + FilamentContext* ctx_ = nullptr; std::unique_ptr scene_view_; std::vector> renderables_; std::vector> meshes_; diff --git a/src/experimental/filament/compat/mjr_filament_renderer.cc b/src/experimental/filament/compat/mjr_filament_renderer.cc index 8953e2a2..c7f74ecf 100644 --- a/src/experimental/filament/compat/mjr_filament_renderer.cc +++ b/src/experimental/filament/compat/mjr_filament_renderer.cc @@ -28,18 +28,17 @@ #include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/model_util.h" #include "experimental/filament/filament/render_target.h" -#include "experimental/filament/filament/texture.h" #include "experimental/filament/render_context_filament.h" namespace mujoco { -MjrFilamentRenderer::MjrFilamentRenderer(const mjrFilamentConfig* config) - : FilamentContext(config) { +MjrFilamentRenderer::MjrFilamentRenderer(const mjrFilamentConfig* config) { + filament_context_ = std::make_unique(config); } void MjrFilamentRenderer::Init(const mjModel* model) { - scene_bridge_ = std::make_unique(GetObjectManager(), model); - imgui_bridge_ = std::make_unique(GetObjectManager()); + scene_bridge_ = std::make_unique(filament_context_.get(), model); + imgui_bridge_ = std::make_unique(filament_context_.get()); mjr_defaultRenderRequest(&render_requests_[0]); mjr_defaultRenderRequest(&render_requests_[1]); @@ -66,12 +65,12 @@ void MjrFilamentRenderer::Init(const mjModel* model) { render_requests_[1].camera.frustum_near = 0.0f; render_requests_[1].camera.frustum_far = 1.0f; - - SetClearColor(ReadElement(model, "filament.clearColor", - filament::math::float4(0, 0, 0, 1))); + filament_context_->SetClearColor(ReadElement( + model, "filament.clearColor", filament::math::float4(0, 0, 0, 1))); } -void MjrFilamentRenderer::Render(const mjrRect& viewport, const mjvScene* scene) { +void MjrFilamentRenderer::Render(const mjrRect& viewport, + const mjvScene* scene) { scene_bridge_->Update(viewport, scene); // Update the UX renderable entity after processing the scene in case there // are any elements in the scene which generate UX draw calls (e.g. labels). @@ -92,7 +91,8 @@ void MjrFilamentRenderer::Render(const mjrRect& viewport, const mjvScene* scene) render_requests_[1].width = viewport.width; render_requests_[1].height = viewport.height; - render_requests_[0].camera = mjv_averageCamera(scene->camera, scene->camera + 1); + render_requests_[0].camera = + mjv_averageCamera(scene->camera, scene->camera + 1); render_requests_[1].camera.frustum_center = viewport.width / 2.0f; render_requests_[1].camera.frustum_width = viewport.width / 2.0f; render_requests_[1].camera.frustum_bottom = viewport.height; @@ -100,7 +100,7 @@ void MjrFilamentRenderer::Render(const mjrRect& viewport, const mjvScene* scene) if (mode_ == FrameBufferMode::Window) { render_requests_[0].target = nullptr; render_requests_[1].target = nullptr; - FilamentContext::Render(render_requests_); + filament_context_->Render(render_requests_); } } @@ -136,7 +136,8 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb, mjr_defaultRenderTargetConfig(&config); config.color_format = mjPIXEL_FORMAT_RGB8; config.depth_format = mjPIXEL_FORMAT_DEPTH32F; - auto target = std::make_unique(GetEngine(), config); + auto target = + std::make_unique(filament_context_.get(), config); target->Prepare(viewport.width, viewport.height); render_requests_[0].target = target.get(); render_requests_[1].target = target.get(); @@ -148,9 +149,9 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb, mjr_defaultReadPixelsRequest(&read_request); read_request.output = rgb; read_request.num_bytes = viewport.width * viewport.height * 3; - const mjrFrameHandle frame = FilamentContext::Render( + const mjrFrameHandle frame = filament_context_->Render( {&render_requests_[0], num_requests}, {&read_request, 1}); - FilamentContext::WaitForFrame(frame); + filament_context_->WaitForFrame(frame); render_requests_[0].target = nullptr; render_requests_[1].target = nullptr; @@ -161,7 +162,8 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb, mjr_defaultRenderTargetConfig(&config); config.color_format = mjPIXEL_FORMAT_R32F; config.depth_format = mjPIXEL_FORMAT_DEPTH32F; - auto target = std::make_unique(GetEngine(), config); + auto target = + std::make_unique(filament_context_.get(), config); target->Prepare(viewport.width, viewport.height); render_requests_[0].target = target.get(); render_requests_[1].target = target.get(); @@ -173,9 +175,9 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb, mjr_defaultReadPixelsRequest(&read_request); read_request.output = reinterpret_cast(depth); read_request.num_bytes = viewport.width * viewport.height * sizeof(float); - const mjrFrameHandle frame = - FilamentContext::Render({&render_requests_[0], 1}, {&read_request, 1}); - FilamentContext::WaitForFrame(frame); + const mjrFrameHandle frame = filament_context_->Render( + {&render_requests_[0], 1}, {&read_request, 1}); + filament_context_->WaitForFrame(frame); render_requests_[0].target = nullptr; render_requests_[1].target = nullptr; @@ -205,8 +207,8 @@ void MjrFilamentRenderer::UploadHeightField(const mjModel* model, int id) { } uintptr_t MjrFilamentRenderer::UploadGuiImage(uintptr_t tex_id, - const uint8_t* pixels, int width, - int height, int bpp) { + const uint8_t* pixels, int width, + int height, int bpp) { return imgui_bridge_->UploadImage(tex_id, pixels, width, height, bpp); } diff --git a/src/experimental/filament/compat/mjr_filament_renderer.h b/src/experimental/filament/compat/mjr_filament_renderer.h index 3d87e624..ab77f2c8 100644 --- a/src/experimental/filament/compat/mjr_filament_renderer.h +++ b/src/experimental/filament/compat/mjr_filament_renderer.h @@ -29,7 +29,7 @@ namespace mujoco { // Subclass of the FilamentContext that implements the legacy mjr API. -class MjrFilamentRenderer : public FilamentContext { +class MjrFilamentRenderer { public: explicit MjrFilamentRenderer(const mjrFilamentConfig* config); ~MjrFilamentRenderer() = default; @@ -65,6 +65,10 @@ class MjrFilamentRenderer : public FilamentContext { // Renders an ImGui window containing Filament-specific editor UI. void UpdateGui(); + double GetFrameRate() const { + return filament_context_->GetFrameRate(); + } + MjrFilamentRenderer(const MjrFilamentRenderer&) = delete; MjrFilamentRenderer& operator=(const MjrFilamentRenderer&) = delete; @@ -75,6 +79,7 @@ class MjrFilamentRenderer : public FilamentContext { OffScreenWithGui, }; + std::unique_ptr filament_context_; FrameBufferMode mode_ = FrameBufferMode::Window; mjrRenderRequest render_requests_[2]; std::unique_ptr scene_bridge_; diff --git a/src/experimental/filament/compat/model_objects.cc b/src/experimental/filament/compat/model_objects.cc index 67e07a08..d87dd4c0 100644 --- a/src/experimental/filament/compat/model_objects.cc +++ b/src/experimental/filament/compat/model_objects.cc @@ -32,6 +32,7 @@ #include #include #include "experimental/filament/filament/builtins.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/model_util.h" @@ -493,21 +494,21 @@ void UpdateSkinFlexmjrMeshData(mjrMeshData* data, const mjModel* model, data->user_data = nullptr; } -ModelObjects::ModelObjects(const mjModel* model, filament::Engine* engine) - : model_(model), engine_(engine) { +ModelObjects::ModelObjects(const mjModel* model, FilamentContext* ctx) + : model_(model), ctx_(ctx) { const int nstack = model->vis.quality.numstacks; const int nslice = model->vis.quality.numslices; const int nquad = model->vis.quality.numquads; - shapes_[kLine] = CreateLine(engine_); - shapes_[kBox] = CreateBox(engine_, nquad); - shapes_[kLineBox] = CreateLineBox(engine_); - shapes_[kCone] = CreateCone(engine_, nstack, nslice); - shapes_[kDisk] = CreateDisk(engine_, nslice); - shapes_[kDome] = CreateDome(engine_, nstack / 2, nslice); - shapes_[kTube] = CreateTube(engine_, nstack, nslice); - shapes_[kPlane] = CreatePlane(engine_, nquad); - shapes_[kSphere] = CreateSphere(engine_, nstack, nslice); - shapes_[kTriangle] = CreateTriangle(engine_); + shapes_[kLine] = CreateLine(ctx_); + shapes_[kBox] = CreateBox(ctx_, nquad); + shapes_[kLineBox] = CreateLineBox(ctx_); + shapes_[kCone] = CreateCone(ctx_, nstack, nslice); + shapes_[kDisk] = CreateDisk(ctx_, nslice); + shapes_[kDome] = CreateDome(ctx_, nstack / 2, nslice); + shapes_[kTube] = CreateTube(ctx_, nstack, nslice); + shapes_[kPlane] = CreatePlane(ctx_, nquad); + shapes_[kSphere] = CreateSphere(ctx_, nstack, nslice); + shapes_[kTriangle] = CreateTriangle(ctx_); for (int i = 0; i < model_->ntex; ++i) { UploadTexture(model_, i); @@ -545,13 +546,13 @@ void ModelObjects::UploadMesh(const mjModel* model, int id) { mjrMeshData data; mjr_defaultMeshData(&data); UpdatemjrMeshData(&data, model, id, MeshType::kNormal); - meshes_[id] = std::make_unique(engine_, data); + meshes_[id] = std::make_unique(ctx_, data); if (model->mesh_graphadr[id] >= 0) { mjrMeshData convex_hull_data; mjr_defaultMeshData(&convex_hull_data); UpdatemjrMeshData(&convex_hull_data, model, id, MeshType::kConvexHull); - convex_hulls_[id] = std::make_unique(engine_, convex_hull_data); + convex_hulls_[id] = std::make_unique(ctx_, convex_hull_data); } } @@ -587,7 +588,6 @@ void ModelObjects::UploadTexture(const mjModel* model, int id) { config.format = mjPIXEL_FORMAT_KTX; } - mjrTextureData payload; mjr_defaultTextureData(&payload); payload.bytes = model->tex_data + model->tex_adr[id]; @@ -597,7 +597,7 @@ void ModelObjects::UploadTexture(const mjModel* model, int id) { payload.user_data = nullptr; payload.release_callback = nullptr; - auto texture = std::make_unique(engine_, config); + auto texture = std::make_unique(ctx_, config); texture->Upload(payload); textures_[id] = std::move(texture); } @@ -615,14 +615,14 @@ void ModelObjects::UploadHeightField(const mjModel* model, int id) { mjrMeshData data; mjr_defaultMeshData(&data); UpdatemjrMeshData(&data, model, id, MeshType::kHeightField); - height_fields_[id] = std::make_unique(engine_, data); + height_fields_[id] = std::make_unique(ctx_, data); } void ModelObjects::CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom) { mjrMeshData data; mjr_defaultMeshData(&data); UpdateSkinFlexmjrMeshData(&data, model_, scene, geom); - dynamic_meshes_[geom.objid] = std::make_unique(engine_, data); + dynamic_meshes_[geom.objid] = std::make_unique(ctx_, data); } const Mesh* ModelObjects::GetMeshBuffer(int data_id) const { diff --git a/src/experimental/filament/compat/model_objects.h b/src/experimental/filament/compat/model_objects.h index 4b7b0afd..2db285f7 100644 --- a/src/experimental/filament/compat/model_objects.h +++ b/src/experimental/filament/compat/model_objects.h @@ -19,9 +19,9 @@ #include #include -#include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/texture.h" @@ -30,7 +30,7 @@ namespace mujoco { // Creates and owns various filament objects based on the mjModel. class ModelObjects { public: - ModelObjects(const mjModel* model, filament::Engine* engine); + ModelObjects(const mjModel* model, FilamentContext* ctx); ~ModelObjects(); enum ShapeType { @@ -75,7 +75,7 @@ class ModelObjects { private: const mjModel* model_ = nullptr; - filament::Engine* engine_ = nullptr; + FilamentContext* ctx_ = nullptr; std::array, kNumShapes> shapes_; std::unordered_map> meshes_; std::unordered_map> convex_hulls_; diff --git a/src/experimental/filament/compat/scene_bridge.cc b/src/experimental/filament/compat/scene_bridge.cc index aebb85ef..85d2b1e0 100644 --- a/src/experimental/filament/compat/scene_bridge.cc +++ b/src/experimental/filament/compat/scene_bridge.cc @@ -19,15 +19,7 @@ #include #include -#include -#include -#include -#include #include -#include -#include -#include -#include #include #include #include @@ -40,6 +32,7 @@ #include "experimental/filament/compat/model_objects.h" #include "experimental/filament/compat/scene_geom_util.h" #include "experimental/filament/filament/color_grading_options.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/light.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/model_util.h" @@ -47,6 +40,7 @@ #include "experimental/filament/filament/renderable.h" #include "experimental/filament/filament/scene_view.h" #include "experimental/filament/filament/texture.h" +#include "experimental/filament/render_context_filament.h" namespace mujoco { @@ -56,12 +50,13 @@ using filament::math::mat3; using filament::math::mat4; static std::unique_ptr CreateFallbackIndirectLightTexture( - ObjectManager* object_mgr, std::string_view filename = "") { + FilamentContext* ctx, std::string_view filename = "") { if (filename.empty()) { filename = ObjectManager::kDefaultEnvironmentLight; } - std::unique_ptr asset = object_mgr->LoadAsset(filename); + std::unique_ptr asset = + ctx->GetObjectManager()->LoadAsset(filename); mjrTextureConfig config; mjr_defaultTextureConfig(&config); @@ -71,7 +66,7 @@ static std::unique_ptr CreateFallbackIndirectLightTexture( config.format = mjPIXEL_FORMAT_KTX; config.color_space = mjCOLORSPACE_AUTO; - auto texture = std::make_unique(object_mgr->GetEngine(), config); + auto texture = std::make_unique(ctx, config); mjrTextureData payload; mjr_defaultTextureData(&payload); @@ -86,11 +81,10 @@ static std::unique_ptr CreateFallbackIndirectLightTexture( return texture; } -SceneBridge::SceneBridge(ObjectManager* object_mgr, const mjModel* model) - : object_mgr_(object_mgr) { - scene_view_ = std::make_unique(object_mgr_->GetEngine()); - model_objects_ = - std::make_unique(model, object_mgr_->GetEngine()); +SceneBridge::SceneBridge(FilamentContext* ctx, const mjModel* model) + : ctx_(ctx) { + scene_view_ = std::make_unique(ctx_); + model_objects_ = std::make_unique(model, ctx_); // Configure options for the normal view. auto cg = scene_view_->GetColorGradingOptions(); @@ -203,15 +197,14 @@ void SceneBridge::SetEnvironmentLight(std::string_view filename, fallback_ibl_.reset(); } - fallback_ibl_texture_ = - CreateFallbackIndirectLightTexture(object_mgr_, filename); + fallback_ibl_texture_ = CreateFallbackIndirectLightTexture(ctx_, filename); mjrLightParams params; mjr_defaultLightParams(¶ms); params.type = mjLIGHT_IMAGE; params.texture = fallback_ibl_texture_.get(); params.intensity = intensity; - fallback_ibl_ = std::make_unique(object_mgr_->GetEngine(), params); + fallback_ibl_ = std::make_unique(ctx_, params); scene_view_->AddToScene(fallback_ibl_.get()); } @@ -224,7 +217,6 @@ std::optional SceneBridge::ClipFromWorld(const float3& pos) const{ } void SceneBridge::PrepareLights() { - filament::Engine* engine = object_mgr_->GetEngine(); const mjModel* model = model_objects_->GetModel(); bool has_image_based_light = false; @@ -238,7 +230,7 @@ void SceneBridge::PrepareLights() { params.type = mjLIGHT_IMAGE; params.texture = model_objects_->GetTexture(model->light_texid[i]); params.intensity = model->light_intensity[i]; - auto light_obj = std::make_unique(engine, params); + auto light_obj = std::make_unique(ctx_, params); scene_view_->AddToScene(light_obj.get()); lights_.emplace_back(std::move(light_obj)); has_image_based_light = true; @@ -259,7 +251,7 @@ void SceneBridge::PrepareLights() { params.spot_cone_angle = model->light_cutoff[i]; } - auto light_obj = std::make_unique(engine, params); + auto light_obj = std::make_unique(ctx_, params); scene_view_->AddToScene(light_obj.get()); lights_.emplace_back(std::move(light_obj)); } @@ -279,7 +271,7 @@ void SceneBridge::PrepareLights() { params.cast_shadows = 0; params.intensity = 0.0f; params.spot_cone_angle = 90.0f; - auto light_obj = std::make_unique(engine, params); + auto light_obj = std::make_unique(ctx_, params); scene_view_->AddToScene(light_obj.get()); lights_.emplace_back(std::move(light_obj)); } @@ -287,12 +279,11 @@ void SceneBridge::PrepareLights() { if (!has_image_based_light && total_light_intensity > 0.0f) { // Create a black indirect light to ensure that the skybox is // oriented to respect mujoco's Z-up convention. - filament::Engine* engine = object_mgr_->GetEngine(); mjrLightParams params; mjr_defaultLightParams(¶ms); params.type = mjLIGHT_IMAGE; params.intensity = 10.0f; - fallback_ibl_ = std::make_unique(engine, params); + fallback_ibl_ = std::make_unique(ctx_, params); scene_view_->AddToScene(fallback_ibl_.get()); } @@ -301,14 +292,14 @@ 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_); + fallback_ibl_texture_ = CreateFallbackIndirectLightTexture(ctx_); mjrLightParams params; mjr_defaultLightParams(¶ms); params.type = mjLIGHT_IMAGE; params.texture = fallback_ibl_texture_.get(); params.intensity = fallback_environment_light_intensity_; - fallback_ibl_ = std::make_unique(engine, params); + fallback_ibl_ = std::make_unique(ctx_, params); scene_view_->AddToScene(fallback_ibl_.get()); // Distribute the fallback scene light intensity among the lights. @@ -325,8 +316,7 @@ void SceneBridge::PrepareLights() { scene_view_->SetSkybox(model_objects_->GetSkyboxTexture()); } -filament::math::mat4 CalculateClipFromWorld(const mjrRect& viewport, - const mjvGLCamera& cam) { +mat4 CalculateClipFromWorld(const mjrRect& viewport, const mjvGLCamera& cam) { const float3 cam_pos(cam.pos[0], cam.pos[1], cam.pos[2]); const float3 cam_fwd(cam.forward[0], cam.forward[1], cam.forward[2]); const float3 cam_up(cam.up[0], cam.up[1], cam.up[2]); @@ -394,7 +384,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { } std::unique_ptr renderable = CreateGeomRenderable( - *geom, scene, object_mgr_, model_objects_.get(), headpos); + *geom, scene, ctx_, model_objects_.get(), headpos); scene_view_->AddToScene(renderable.get()); renderables_.push_back(std::move(renderable)); diff --git a/src/experimental/filament/compat/scene_bridge.h b/src/experimental/filament/compat/scene_bridge.h index 96e8ab31..d2d1dfdb 100644 --- a/src/experimental/filament/compat/scene_bridge.h +++ b/src/experimental/filament/compat/scene_bridge.h @@ -25,8 +25,8 @@ #include #include #include "experimental/filament/compat/model_objects.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/light.h" -#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" @@ -36,7 +36,7 @@ namespace mujoco { // Manages all mjModel data and updates a SceneView using an mjvScene. class SceneBridge { public: - SceneBridge(ObjectManager* object_mgr, const mjModel* model); + SceneBridge(FilamentContext* ctx, const mjModel* model); ~SceneBridge(); // Updates the environment light using the KTX image at the given path. @@ -68,8 +68,8 @@ class SceneBridge { std::optional ClipFromWorld( const filament::math::float3& pos) const; + FilamentContext* ctx_ = nullptr; std::unique_ptr scene_view_; - ObjectManager* object_mgr_ = nullptr; std::unique_ptr model_objects_; std::unique_ptr fallback_ibl_; std::unique_ptr fallback_ibl_texture_; diff --git a/src/experimental/filament/compat/scene_geom_util.cc b/src/experimental/filament/compat/scene_geom_util.cc index ddc85bee..382e6c88 100644 --- a/src/experimental/filament/compat/scene_geom_util.cc +++ b/src/experimental/filament/compat/scene_geom_util.cc @@ -20,9 +20,6 @@ #include #include -#include -#include -#include #include #include #include @@ -30,9 +27,9 @@ #include #include #include "experimental/filament/compat/model_objects.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/mesh.h" -#include "experimental/filament/filament/object_manager.h" #include "experimental/filament/filament/renderable.h" #include "experimental/filament/filament/texture.h" #include "experimental/filament/render_context_filament.h" @@ -343,7 +340,6 @@ static void PrepareGeomMeshes(Renderable& renderable, const mjvGeom& geom, static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom, const mjvScene* scene, ModelObjects* model_objs, - ObjectManager* object_mgr, const float headpos[3]) { const mjModel* model = model_objs->GetModel(); @@ -491,7 +487,7 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom, } std::unique_ptr CreateGeomRenderable( - const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr, + const mjvGeom& geom, const mjvScene* scene, FilamentContext* ctx, ModelObjects* model_objs, const float headpos[3]) { mjrShadingModel shading_model = mjSHADING_MODEL_SCENE_OBJECT; if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) { @@ -503,11 +499,9 @@ std::unique_ptr CreateGeomRenderable( mjrRenderableParams params; mjr_defaultRenderableParams(¶ms); params.shading_model = shading_model; - auto renderable = std::make_unique(object_mgr, params); - + auto renderable = std::make_unique(ctx, params); PrepareGeomMeshes(*renderable, geom, scene, model_objs); - UpdateGeomMaterial(*renderable, geom, scene, model_objs, object_mgr, headpos); - + UpdateGeomMaterial(*renderable, geom, scene, model_objs, headpos); return renderable; } } // namespace mujoco diff --git a/src/experimental/filament/compat/scene_geom_util.h b/src/experimental/filament/compat/scene_geom_util.h index c702f687..2a0ee2f5 100644 --- a/src/experimental/filament/compat/scene_geom_util.h +++ b/src/experimental/filament/compat/scene_geom_util.h @@ -19,14 +19,14 @@ #include #include "experimental/filament/compat/model_objects.h" -#include "experimental/filament/filament/object_manager.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/renderable.h" namespace mujoco { // Creates a Renderable from the given mjvGeom. std::unique_ptr CreateGeomRenderable( - const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr, + const mjvGeom& geom, const mjvScene* scene, FilamentContext* ctx, ModelObjects* model_objs, const float headpos[3]); } // namespace mujoco diff --git a/src/experimental/filament/filament/builtins.cc b/src/experimental/filament/filament/builtins.cc index f438fa39..abde82df 100644 --- a/src/experimental/filament/filament/builtins.cc +++ b/src/experimental/filament/filament/builtins.cc @@ -21,14 +21,13 @@ #include #include -#include -#include -#include #include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/mesh.h" +#include "experimental/filament/render_context_filament.h" namespace mujoco { @@ -59,13 +58,13 @@ static std::size_t NumIndicesPerSide(int num_quads_per_axis) { return kNumIndicesPerQuad * num_quads_per_axis * num_quads_per_axis; } -class BuiltinBuilder : mjrMeshData { +class BuiltinBuilder : public mjrMeshData { public: BuiltinBuilder() { mjr_defaultMeshData(this); } virtual ~BuiltinBuilder() = default; template - static std::unique_ptr Create(filament::Engine* engine, + static std::unique_ptr Create(FilamentContext* ctx, Args&&... args) { auto builder = new T(std::forward(args)...); mjrMeshData* mesh_data = builder->PrepareMeshData(); @@ -73,7 +72,7 @@ class BuiltinBuilder : mjrMeshData { delete static_cast(user_data); }; mesh_data->user_data = builder; - return std::make_unique(engine, *mesh_data); + return std::make_unique(ctx, *mesh_data); } mjrMeshData* PrepareMeshData() { @@ -89,33 +88,29 @@ class BuiltinBuilder : mjrMeshData { indices = indices_.data(); nindices = indices_.size(); - primitive_type = - primitive_type_ == filament::backend::PrimitiveType::TRIANGLES - ? mjMESH_PRIMITIVE_TYPE_TRIANGLES - : mjMESH_PRIMITIVE_TYPE_LINES; index_type = mjINDEX_TYPE_U16; - bounds_min[0] = bounds_.getMin().x; - bounds_min[1] = bounds_.getMin().y; - bounds_min[2] = bounds_.getMin().z; - bounds_max[0] = bounds_.getMax().x; - bounds_max[1] = bounds_.getMax().y; - bounds_max[2] = bounds_.getMax().z; return this; } protected: + void SetBounds(const float3& min, const float3& max) { + bounds_min[0] = min.x; + bounds_min[1] = min.y; + bounds_min[2] = min.z; + bounds_max[0] = max.x; + bounds_max[1] = max.y; + bounds_max[2] = max.z; + } + std::vector positions_; std::vector orientations_; std::vector indices_; - filament::Box bounds_; - filament::RenderableManager::PrimitiveType primitive_type_ = - filament::RenderableManager::PrimitiveType::TRIANGLES; }; class LineBuilder : public BuiltinBuilder { public: LineBuilder() { - primitive_type_ = filament::RenderableManager::PrimitiveType::LINES; + primitive_type = mjMESH_PRIMITIVE_TYPE_LINES; positions_.reserve(2); positions_.emplace_back(0, 0, 0); @@ -127,7 +122,7 @@ class LineBuilder : public BuiltinBuilder { indices_.push_back(0); indices_.push_back(1); - bounds_.set({0, 0, 0}, {0, 0, 1}); + SetBounds({0, 0, 0}, {0, 0, 1}); } }; @@ -161,7 +156,7 @@ class PlaneBuilder : public BuiltinBuilder { } } - bounds_.set({-1, -1, -0.001}, {1, 1, 0.001}); + SetBounds({-1, -1, -0.001}, {1, 1, 0.001}); } }; @@ -180,14 +175,14 @@ class TriangleBuilder : public BuiltinBuilder { indices_.emplace_back(1); indices_.emplace_back(2); - bounds_.set({-1, -1, -0.001}, {1, 1, 0.001}); + SetBounds({-1, -1, -0.001}, {1, 1, 0.001}); } }; class LineBoxBuilder : public BuiltinBuilder { public: explicit LineBoxBuilder() { - primitive_type_ = filament::RenderableManager::PrimitiveType::LINES; + primitive_type = mjMESH_PRIMITIVE_TYPE_LINES; positions_.reserve(8); positions_.emplace_back(-1.0f, -1.0f, -1.0f); @@ -229,7 +224,7 @@ class LineBoxBuilder : public BuiltinBuilder { indices_.push_back(1); indices_.push_back(5); - bounds_.set({-1, -1, -1}, {1, 1, 1}); + SetBounds({-1, -1, -1}, {1, 1, 1}); } }; @@ -277,7 +272,7 @@ class BoxBuilder : public BuiltinBuilder { } } - bounds_.set({-1, -1, -1}, {1, 1, 1}); + SetBounds({-1, -1, -1}, {1, 1, 1}); } private: @@ -334,7 +329,7 @@ class TubeBuilder : public BuiltinBuilder { } } - bounds_.set({-1, -1, -1}, {1, 1, 1}); + SetBounds({-1, -1, -1}, {1, 1, 1}); } }; @@ -398,7 +393,7 @@ class ConeBuilder : public BuiltinBuilder { } } - bounds_.set({-1, -1, 0}, {1, 1, 1}); + SetBounds({-1, -1, 0}, {1, 1, 1}); } private: @@ -440,7 +435,7 @@ class DiskBuilder : public BuiltinBuilder { indices_.push_back(1 + next); } - bounds_.set({-1, -1, -0.001}, {1, 1, 0.001}); + SetBounds({-1, -1, -0.001}, {1, 1, 0.001}); } }; @@ -527,7 +522,7 @@ class SphereBuilder : public BuiltinBuilder { indices_.push_back(row_start + adjacent); } - bounds_.set({-1, -1, -1}, {1, 1, 1}); + SetBounds({-1, -1, -1}, {1, 1, 1}); } private: @@ -611,7 +606,7 @@ class DomeBuilder : public BuiltinBuilder { row_start += num_slices; } - bounds_.set({-1, -1, 0}, {1, 1, 1}); + SetBounds({-1, -1, 0}, {1, 1, 1}); } private: @@ -622,44 +617,44 @@ class DomeBuilder : public BuiltinBuilder { } }; -std::unique_ptr CreateLine(filament::Engine* engine) { - return BuiltinBuilder::Create(engine); +std::unique_ptr CreateLine(FilamentContext* ctx) { + return BuiltinBuilder::Create(ctx); } -std::unique_ptr CreatePlane(filament::Engine* engine, int nquad) { - return BuiltinBuilder::Create(engine, nquad); +std::unique_ptr CreatePlane(FilamentContext* ctx, int nquad) { + return BuiltinBuilder::Create(ctx, nquad); } -std::unique_ptr CreateTriangle(filament::Engine* engine) { - return BuiltinBuilder::Create(engine); +std::unique_ptr CreateTriangle(FilamentContext* ctx) { + return BuiltinBuilder::Create(ctx); } -std::unique_ptr CreateBox(filament::Engine* engine, int nquad) { - return BuiltinBuilder::Create(engine, nquad); +std::unique_ptr CreateBox(FilamentContext* ctx, int nquad) { + return BuiltinBuilder::Create(ctx, nquad); } -std::unique_ptr CreateLineBox(filament::Engine* engine) { - return BuiltinBuilder::Create(engine); +std::unique_ptr CreateLineBox(FilamentContext* ctx) { + return BuiltinBuilder::Create(ctx); } -std::unique_ptr CreateSphere(filament::Engine* engine, int nstack, int nslice) { - return BuiltinBuilder::Create(engine, nstack, nslice); +std::unique_ptr CreateSphere(FilamentContext* ctx, int nstack, int nslice) { + return BuiltinBuilder::Create(ctx, nstack, nslice); } -std::unique_ptr CreateTube(filament::Engine* engine, int nstack, int nslice) { - return BuiltinBuilder::Create(engine, nstack, nslice); +std::unique_ptr CreateTube(FilamentContext* ctx, int nstack, int nslice) { + return BuiltinBuilder::Create(ctx, nstack, nslice); } -std::unique_ptr CreateDisk(filament::Engine* engine, int nslice) { - return BuiltinBuilder::Create(engine, nslice); +std::unique_ptr CreateDisk(FilamentContext* ctx, int nslice) { + return BuiltinBuilder::Create(ctx, nslice); } -std::unique_ptr CreateDome(filament::Engine* engine, int nstack, int nslice) { - return BuiltinBuilder::Create(engine, nstack, nslice); +std::unique_ptr CreateDome(FilamentContext* ctx, int nstack, int nslice) { + return BuiltinBuilder::Create(ctx, nstack, nslice); } -std::unique_ptr CreateCone(filament::Engine* engine, int nstack, int nslice) { - return BuiltinBuilder::Create(engine, nstack, nslice); +std::unique_ptr CreateCone(FilamentContext* ctx, int nstack, int nslice) { + return BuiltinBuilder::Create(ctx, nstack, nslice); } } // namespace mujoco diff --git a/src/experimental/filament/filament/builtins.h b/src/experimental/filament/filament/builtins.h index 5fd5c8a5..1727f378 100644 --- a/src/experimental/filament/filament/builtins.h +++ b/src/experimental/filament/filament/builtins.h @@ -17,22 +17,22 @@ #include -#include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/mesh.h" // Generates buffers for built-in shapes. namespace mujoco { -std::unique_ptr CreateLine(filament::Engine* engine); -std::unique_ptr CreatePlane(filament::Engine* engine, int nquad); -std::unique_ptr CreateTriangle(filament::Engine* engine); -std::unique_ptr CreateBox(filament::Engine* engine, int nquad); -std::unique_ptr CreateLineBox(filament::Engine* engine); -std::unique_ptr CreateSphere(filament::Engine* engine, int nstack, int nslice); -std::unique_ptr CreateTube(filament::Engine* engine, int nstack, int nslice); -std::unique_ptr CreateDisk(filament::Engine* engine, int nslice); -std::unique_ptr CreateDome(filament::Engine* engine, int nstack, int nslice); -std::unique_ptr CreateCone(filament::Engine* engine, int nstack, int nslice); +std::unique_ptr CreateLine(FilamentContext* ctx); +std::unique_ptr CreatePlane(FilamentContext* ctx, int nquad); +std::unique_ptr CreateTriangle(FilamentContext* ctx); +std::unique_ptr CreateBox(FilamentContext* ctx, int nquad); +std::unique_ptr CreateLineBox(FilamentContext* ctx); +std::unique_ptr CreateSphere(FilamentContext* ctx, int nstack, int nslice); +std::unique_ptr CreateTube(FilamentContext* ctx, int nstack, int nslice); +std::unique_ptr CreateDisk(FilamentContext* ctx, int nslice); +std::unique_ptr CreateDome(FilamentContext* ctx, int nstack, int nslice); +std::unique_ptr CreateCone(FilamentContext* ctx, int nstack, int nslice); } // namespace mujoco diff --git a/src/experimental/filament/filament/filament_context.cc b/src/experimental/filament/filament/filament_context.cc index 4149559c..3166bea8 100644 --- a/src/experimental/filament/filament/filament_context.cc +++ b/src/experimental/filament/filament/filament_context.cc @@ -36,12 +36,16 @@ #include #include "experimental/filament/filament/filament_platform_factory.h" #include "experimental/filament/filament/object_manager.h" -#include "experimental/filament/filament/render_target.h" -#include "experimental/filament/filament/scene_view.h" #include "experimental/filament/render_context_filament.h" namespace mujoco { +// Forward declarations of functions defined in scene_view.cc to prevent +// circular dependencies. +void DoRender(filament::Renderer* renderer, const mjrRenderRequest& request); +void DoReadPixels(filament::Renderer* renderer, const mjrRenderRequest& request, + const mjrReadPixelsRequest& read_request); + FilamentContext::FilamentContext(const mjrFilamentConfig* config) : config_(*config) { FilamentPlatformSetup setup = CreateFilamentPlatform(config_); @@ -122,12 +126,7 @@ mjrFrameHandle FilamentContext::Render( break; } if (render_began) { - SceneView::RenderRequest scene_view_request; - scene_view_request.draw_mode = request.draw_mode; - scene_view_request.viewport = {0, 0, request.width, request.height}; - scene_view_request.camera = request.camera; - SceneView* scene_view = SceneView::downcast(request.scene); - scene_view->Render(renderer_, scene_view_request); + DoRender(renderer_, request); } } else { if (read_requests.empty()) { @@ -147,17 +146,8 @@ mjrFrameHandle FilamentContext::Render( break; } if (render_began) { - RenderTarget* render_target = RenderTarget::downcast(request.target); - - SceneView::RenderRequest scene_view_request; - scene_view_request.draw_mode = request.draw_mode; - scene_view_request.viewport = {0, 0, request.width, request.height}; - scene_view_request.camera = request.camera; - scene_view_request.target = render_target; - SceneView* scene_view = SceneView::downcast(request.scene); - scene_view->Render(renderer_, scene_view_request); - render_target->ReadColorPixels(renderer_, (uint8_t*)read_request.output, - read_request.num_bytes); + DoRender(renderer_, request); + DoReadPixels(renderer_, request, read_request); } } } diff --git a/src/experimental/filament/filament/light.cc b/src/experimental/filament/filament/light.cc index 2918f0a0..a4cc0ed1 100644 --- a/src/experimental/filament/filament/light.cc +++ b/src/experimental/filament/filament/light.cc @@ -25,6 +25,7 @@ #include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/texture.h" #include "experimental/filament/render_context_filament.h" @@ -34,8 +35,8 @@ namespace mujoco { using filament::math::float3; using filament::math::mat3f; -Light::Light(filament::Engine* engine, const mjrLightParams& params) - : engine_(engine), params_(params) { +Light::Light(FilamentContext* ctx, const mjrLightParams& params) + : engine_(ctx->GetEngine()), params_(params) { // Filament treats image-based lights (IBLs) as separate objects (i.e. // filament::IndirectLight) and so we need to handle IBLs specially. if (params.type == mjLIGHT_IMAGE) { diff --git a/src/experimental/filament/filament/light.h b/src/experimental/filament/filament/light.h index d0b6a884..cc2a16a6 100644 --- a/src/experimental/filament/filament/light.h +++ b/src/experimental/filament/filament/light.h @@ -20,6 +20,7 @@ #include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/render_context_filament.h" namespace mujoco { @@ -27,7 +28,7 @@ namespace mujoco { // Manages the filament Entities for a single mjvLight. class Light : public mjrLight { public: - Light(filament::Engine* engine, const mjrLightParams& params); + Light(FilamentContext* ctx, const mjrLightParams& params); ~Light() noexcept; Light(const Light&) = delete; diff --git a/src/experimental/filament/filament/mesh.cc b/src/experimental/filament/filament/mesh.cc index 9c06cfc7..c2024f3b 100644 --- a/src/experimental/filament/filament/mesh.cc +++ b/src/experimental/filament/filament/mesh.cc @@ -32,6 +32,7 @@ #include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/render_context_filament.h" @@ -102,8 +103,8 @@ int FillSequence(std::byte* buffer, std::size_t num_bytes) { return num; } -Mesh::Mesh(filament::Engine* engine, const mjrMeshData& data) - : engine_(engine), shared_state_(std::make_shared()) { +Mesh::Mesh(FilamentContext* ctx, const mjrMeshData& data) + : engine_(ctx->GetEngine()), shared_state_(std::make_shared()) { type_ = data.primitive_type == mjMESH_PRIMITIVE_TYPE_TRIANGLES ? filament::RenderableManager::PrimitiveType::TRIANGLES : filament::RenderableManager::PrimitiveType::LINES; diff --git a/src/experimental/filament/filament/mesh.h b/src/experimental/filament/filament/mesh.h index 206aa27d..ba9945da 100644 --- a/src/experimental/filament/filament/mesh.h +++ b/src/experimental/filament/filament/mesh.h @@ -29,6 +29,7 @@ #include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/render_context_filament.h" // Functions for creating filament vertex and index buffers. @@ -38,7 +39,7 @@ namespace mujoco { class Mesh : public mjrMesh { public: // Creates a Mesh from the given MeshData. - Mesh(filament::Engine* engine, const mjrMeshData& data); + Mesh(FilamentContext* ctx, const mjrMeshData& data); ~Mesh(); diff --git a/src/experimental/filament/filament/object_manager.cc b/src/experimental/filament/filament/object_manager.cc index 9beb1490..2db47f0d 100644 --- a/src/experimental/filament/filament/object_manager.cc +++ b/src/experimental/filament/filament/object_manager.cc @@ -27,7 +27,6 @@ #include #include #include -#include "experimental/filament/filament/texture.h" #include "user/user_resource.h" namespace mujoco { diff --git a/src/experimental/filament/filament/render_target.cc b/src/experimental/filament/filament/render_target.cc index 4c083136..8b6afb3e 100644 --- a/src/experimental/filament/filament/render_target.cc +++ b/src/experimental/filament/filament/render_target.cc @@ -26,13 +26,15 @@ #include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/texture.h" +#include "experimental/filament/render_context_filament.h" namespace mujoco { -RenderTarget::RenderTarget(filament::Engine* engine, +RenderTarget::RenderTarget(FilamentContext* ctx, const mjrRenderTargetConfig& config) - : engine_(engine), config_(config) {} + : ctx_(ctx), config_(config) {} RenderTarget::~RenderTarget() noexcept { Destroy(); @@ -56,7 +58,7 @@ void RenderTarget::Prepare(int width, int height) { color_config.color_space = mjCOLORSPACE_LINEAR; color_config.format = mjPIXEL_FORMAT_RGB8; color_flags.color_attachment = true; - color_texture_ = std::make_unique(engine_, color_config, color_flags); + color_texture_ = std::make_unique(ctx_, color_config, color_flags); mjrTextureConfig depth_config; mjr_defaultTextureConfig(&depth_config); @@ -68,14 +70,14 @@ void RenderTarget::Prepare(int width, int height) { depth_config.color_space = mjCOLORSPACE_LINEAR; depth_config.format = mjPIXEL_FORMAT_DEPTH32F; depth_flags.depth_attachment = true; - depth_texture_ = std::make_unique(engine_, depth_config, depth_flags); + depth_texture_ = std::make_unique(ctx_, depth_config, depth_flags); filament::RenderTarget::Builder builder; builder.texture(filament::RenderTarget::AttachmentPoint::COLOR, color_texture_->GetFilamentTexture()); builder.texture(filament::RenderTarget::AttachmentPoint::DEPTH, depth_texture_->GetFilamentTexture()); - render_target_ = builder.build(*engine_); + render_target_ = builder.build(*ctx_->GetEngine()); } void RenderTarget::ReadColorPixels(filament::Renderer* renderer, uint8_t* bytes, @@ -109,7 +111,7 @@ void RenderTarget::ReadColorPixels(filament::Renderer* renderer, uint8_t* bytes, void RenderTarget::Destroy() { if (render_target_) { - engine_->destroy(render_target_); + ctx_->GetEngine()->destroy(render_target_); render_target_ = nullptr; } color_texture_.reset(); diff --git a/src/experimental/filament/filament/render_target.h b/src/experimental/filament/filament/render_target.h index 92e221b3..8e3fa83c 100644 --- a/src/experimental/filament/filament/render_target.h +++ b/src/experimental/filament/filament/render_target.h @@ -21,6 +21,7 @@ #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/texture.h" #include "experimental/filament/render_context_filament.h" @@ -31,7 +32,7 @@ class RenderTarget : public mjrRenderTarget { public: // Defines the types of textures to create for the color and depth // attachments. - RenderTarget(filament::Engine* engine, const mjrRenderTargetConfig& config); + RenderTarget(FilamentContext* ctx, const mjrRenderTargetConfig& config); ~RenderTarget() noexcept; RenderTarget(const RenderTarget&) = delete; @@ -64,7 +65,7 @@ class RenderTarget : public mjrRenderTarget { private: void Destroy(); - filament::Engine* engine_ = nullptr; + FilamentContext* ctx_ = nullptr; mjrRenderTargetConfig config_; filament::RenderTarget* render_target_ = nullptr; std::unique_ptr color_texture_ = nullptr; diff --git a/src/experimental/filament/filament/renderable.cc b/src/experimental/filament/filament/renderable.cc index 47c48849..7d26c12c 100644 --- a/src/experimental/filament/filament/renderable.cc +++ b/src/experimental/filament/filament/renderable.cc @@ -26,6 +26,7 @@ #include #include #include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/material.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/mesh.h" @@ -37,8 +38,8 @@ namespace mujoco { using filament::math::mat4f; -Renderable::Renderable(ObjectManager* object_mgr, const mjrRenderableParams& params) - : object_mgr_(object_mgr), params_(params) { +Renderable::Renderable(FilamentContext* ctx, const mjrRenderableParams& params) + : object_mgr_(ctx->GetObjectManager()), params_(params) { mjr_defaultMaterialParams(&material_params_); mjr_defaultMaterialTextures(&material_textures_); } diff --git a/src/experimental/filament/filament/renderable.h b/src/experimental/filament/filament/renderable.h index 9a740a19..2f6f4d48 100644 --- a/src/experimental/filament/filament/renderable.h +++ b/src/experimental/filament/filament/renderable.h @@ -24,7 +24,7 @@ #include #include #include -#include "experimental/filament/filament/material.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/mesh.h" #include "experimental/filament/filament/object_manager.h" @@ -52,7 +52,7 @@ class Renderable : public mjrRenderable { static constexpr std::uint8_t kDefaultPriority = 4; static constexpr std::uint8_t kDefaultLayerMask = 0x01; - Renderable(ObjectManager* object_mgr, const mjrRenderableParams& params); + Renderable(FilamentContext* ctx, const mjrRenderableParams& params); ~Renderable() noexcept; Renderable(const Renderable&) = delete; diff --git a/src/experimental/filament/filament/scene_view.cc b/src/experimental/filament/filament/scene_view.cc index d361fc53..588e98ec 100644 --- a/src/experimental/filament/filament/scene_view.cc +++ b/src/experimental/filament/filament/scene_view.cc @@ -40,6 +40,7 @@ #include #include #include "experimental/filament/filament/color_grading_options.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/light.h" #include "experimental/filament/filament/math_util.h" #include "experimental/filament/filament/render_target.h" @@ -120,7 +121,8 @@ static void SetupReflectionCamera(const mat4& surface_xform, reflection_camera->setCustomProjection(oblique, near, far); } -SceneView::SceneView(filament::Engine* engine) : engine_(engine) { +SceneView::SceneView(FilamentContext* ctx) : ctx_(ctx) { + filament::Engine* engine = ctx_->GetEngine(); scene_ = engine->createScene(); camera_ = engine->createCamera(utils::EntityManager::get().create()); reflect_camera_ = engine->createCamera(utils::EntityManager::get().create()); @@ -153,9 +155,10 @@ SceneView::SceneView(filament::Engine* engine) : engine_(engine) { } SceneView::~SceneView() { + filament::Engine* engine = ctx_->GetEngine(); if (skybox_) { scene_->setSkybox(nullptr); - engine_->destroy(skybox_); + engine->destroy(skybox_); } for (auto& light : lights_) { light->RemoveFromScene(scene_); @@ -166,15 +169,15 @@ SceneView::~SceneView() { lights_.clear(); renderables_.clear(); reflect_targets_.clear(); - engine_->destroyCameraComponent(reflect_camera_->getEntity()); - engine_->destroy(reflect_view_); - engine_->destroyCameraComponent(camera_->getEntity()); + engine->destroyCameraComponent(reflect_camera_->getEntity()); + engine->destroy(reflect_view_); + engine->destroyCameraComponent(camera_->getEntity()); if (color_grading_) { - engine_->destroy(color_grading_); + engine->destroy(color_grading_); } - engine_->destroy(scene_); + engine->destroy(scene_); for (auto& view : views_) { - engine_->destroy(view); + engine->destroy(view); } } @@ -212,13 +215,13 @@ void SceneView::RemoveFromScene(Renderable* renderable) { void SceneView::SetSkybox(const Texture* skybox_texture) { if (skybox_) { scene_->setSkybox(nullptr); - engine_->destroy(skybox_); + GetEngine()->destroy(skybox_); skybox_ = nullptr; } if (skybox_texture) { filament::Skybox::Builder builder; builder.environment(skybox_texture->GetFilamentTexture()); - skybox_ = builder.build(*engine_); + skybox_ = builder.build(*GetEngine()); scene_->setSkybox(skybox_); } } @@ -292,7 +295,7 @@ void SceneView::AddReflectiveRenderable(Renderable* renderable) { config.color_format = mjPIXEL_FORMAT_RGBA8; config.depth_format = mjPIXEL_FORMAT_DEPTH32F; - reflect_targets_.push_back(std::make_unique(engine_, config)); + reflect_targets_.push_back(std::make_unique(ctx_, config)); } // Prepare a render target for the reflective renderable. @@ -311,10 +314,10 @@ void SceneView::SetColorGradingOptions(const ColorGradingOptions& opts) { auto tone_mapper = CreateToneMapper(opts.tone_mapper); auto color_grading = ToBuilder(color_grading_options_) .toneMapper(tone_mapper.get()) - .build(*engine_); + .build(*GetEngine()); views_[mjDRAW_MODE_COLOR]->setColorGrading(color_grading); if (color_grading_) { - engine_->destroy(color_grading_); + GetEngine()->destroy(color_grading_); } color_grading_ = color_grading; color_grading_options_ = opts; @@ -364,4 +367,29 @@ ColorGradingOptions SceneView::GetColorGradingOptions() const { return color_grading_options_; } +void DoRender(filament::Renderer* renderer, const mjrRenderRequest& request) { + SceneView::RenderRequest scene_view_request; + scene_view_request.draw_mode = request.draw_mode; + scene_view_request.viewport = {0, 0, request.width, request.height}; + scene_view_request.camera = request.camera; + SceneView* scene_view = SceneView::downcast(request.scene); + scene_view->Render(renderer, scene_view_request); +} + +void DoReadPixels(filament::Renderer* renderer, + const mjrRenderRequest& request, + const mjrReadPixelsRequest& read_request) { + RenderTarget* render_target = RenderTarget::downcast(request.target); + + SceneView::RenderRequest scene_view_request; + scene_view_request.draw_mode = request.draw_mode; + scene_view_request.viewport = {0, 0, request.width, request.height}; + scene_view_request.camera = request.camera; + scene_view_request.target = render_target; + SceneView* scene_view = SceneView::downcast(request.scene); + scene_view->Render(renderer, scene_view_request); + render_target->ReadColorPixels(renderer, (uint8_t*)read_request.output, + read_request.num_bytes); +} + } // namespace mujoco diff --git a/src/experimental/filament/filament/scene_view.h b/src/experimental/filament/filament/scene_view.h index d23a6ab2..26f41161 100644 --- a/src/experimental/filament/filament/scene_view.h +++ b/src/experimental/filament/filament/scene_view.h @@ -27,6 +27,7 @@ #include #include #include "experimental/filament/filament/color_grading_options.h" +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/filament/light.h" #include "experimental/filament/filament/renderable.h" #include "experimental/filament/filament/render_target.h" @@ -42,7 +43,7 @@ namespace mujoco { // (e.g. normal, depth, segmentation, etc.) as well as reflective surfaces. class SceneView : public mjrScene { public: - SceneView(filament::Engine* engine); + explicit SceneView(FilamentContext* ctx); ~SceneView(); SceneView(const SceneView&) = delete; @@ -71,7 +72,7 @@ class SceneView : public mjrScene { void Render(filament::Renderer* renderer, const RenderRequest& request); // Returns the filament Engine managing the scene. - filament::Engine* GetEngine() const { return engine_; } + filament::Engine* GetEngine() const { return ctx_->GetEngine(); } // Enables/disables shadows for the default render view. void EnableShadows(); @@ -105,7 +106,7 @@ class SceneView : public mjrScene { // rendered in their own passes to create the reflective texture. void AddReflectiveRenderable(Renderable* renderable); - filament::Engine* engine_ = nullptr; + FilamentContext* ctx_ = nullptr; filament::Scene* scene_ = nullptr; filament::Camera* camera_ = nullptr; filament::ColorGrading* color_grading_ = nullptr; diff --git a/src/experimental/filament/filament/texture.cc b/src/experimental/filament/filament/texture.cc index f27b89a6..af174a6e 100644 --- a/src/experimental/filament/filament/texture.cc +++ b/src/experimental/filament/filament/texture.cc @@ -24,6 +24,8 @@ #include #include #include +#include "experimental/filament/filament/filament_context.h" +#include "experimental/filament/render_context_filament.h" namespace mujoco { @@ -110,9 +112,9 @@ static filament::Texture::InternalFormat GetTextureInternalFormat( } } -Texture::Texture(filament::Engine* engine, const mjrTextureConfig& config, +Texture::Texture(FilamentContext* ctx, const mjrTextureConfig& config, InternalFlags flags) - : engine_(engine), config_(config) { + : engine_(ctx->GetEngine()), config_(config) { if (IsCompressed(config_)) { // We defer creation of compressed textures until Upload() is called. In // the meantime, we don't really know anything about the texture (e.g. diff --git a/src/experimental/filament/filament/texture.h b/src/experimental/filament/filament/texture.h index e5b7f305..c0ec1e0b 100644 --- a/src/experimental/filament/filament/texture.h +++ b/src/experimental/filament/filament/texture.h @@ -18,8 +18,7 @@ #include #include #include -#include -#include +#include "experimental/filament/filament/filament_context.h" #include "experimental/filament/render_context_filament.h" // Functions for creating filament textures. @@ -36,7 +35,7 @@ class Texture : public mjrTexture { }; // Creates a texture with the given data. - Texture(filament::Engine* engine, const mjrTextureConfig& config, + Texture(FilamentContext* ctx, const mjrTextureConfig& config, InternalFlags flags = InternalFlags()); ~Texture();