diff --git a/src/experimental/filament/compat/scene_bridge.cc b/src/experimental/filament/compat/scene_bridge.cc index dc033610..d1e4bafd 100644 --- a/src/experimental/filament/compat/scene_bridge.cc +++ b/src/experimental/filament/compat/scene_bridge.cc @@ -40,28 +40,25 @@ using filament::math::float4; using filament::math::mat3; using filament::math::mat4; -SceneBridge::SceneBridge(mjrfContext* ctx, const mjModel* model) - : ctx_(ctx) { - mjrfSceneParams params; - mjrf_defaultSceneParams(¶ms); - scene_ = CreateScene(ctx_, params); +SceneBridge::SceneBridge(mjrfContext* ctx, mjrfScene* scene, const mjModel* model) + : ctx_(ctx), scene_(scene) { model_objects_ = std::make_unique(model, ctx_); scene_objects_ = std::make_unique(ctx_); - mjrf_configureSceneFromModel(scene_.get(), model); + mjrf_configureSceneFromModel(scene_, model); auto clear_color = ReadElement(model, "filament.clearColor", filament::math::float4(0, 0, 0, 1)); mjrf_setClearColor(ctx_, &clear_color[0]); light_manager_ = - std::make_unique(ctx_, scene_.get(), model_objects_.get()); + std::make_unique(ctx_, scene_, model_objects_.get()); } SceneBridge::~SceneBridge() { light_manager_.reset(); for (auto& iter : renderables_) { - mjrf_removeRenderableFromScene(scene_.get(), iter.get()); + mjrf_removeRenderableFromScene(scene_, iter.get()); } renderables_.clear(); } @@ -115,7 +112,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { // Remove all drawables from previous render and prepare new ones. for (auto& iter : renderables_) { - mjrf_removeRenderableFromScene(scene_.get(), iter.get()); + mjrf_removeRenderableFromScene(scene_, iter.get()); } renderables_.clear(); for (int i = 0; i < scene->ngeom; ++i) { @@ -154,7 +151,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { mjrf_setRenderableMaterial(vertex.get(), &material); mjrf_setRenderableSize(vertex.get(), size); mjrf_setRenderableTransform(vertex.get(), scene->flexvert + 3*v, rot); - mjrf_addRenderableToScene(scene_.get(), vertex.get()); + mjrf_addRenderableToScene(scene_, vertex.get()); renderables_.push_back(std::move(vertex)); } } @@ -199,7 +196,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { mjrf_setRenderableMaterial(vertex.get(), &material); mjrf_setRenderableSize(vertex.get(), size); mjrf_setRenderableTransform(vertex.get(), pos, rot); - mjrf_addRenderableToScene(scene_.get(), vertex.get()); + mjrf_addRenderableToScene(scene_, vertex.get()); renderables_.push_back(std::move(vertex)); } } @@ -215,7 +212,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { UniquePtr renderable = CreateGeomRenderable( *geom, ctx_, model_objects_.get(), scene_objects_.get()); - mjrf_addRenderableToScene(scene_.get(), renderable.get()); + mjrf_addRenderableToScene(scene_, renderable.get()); renderables_.push_back(std::move(renderable)); } @@ -269,8 +266,6 @@ void SceneBridge::SetDrawTextFunction(DrawTextAtFn fn) { draw_text_callback_ = std::move(fn); } -mjrfScene* SceneBridge::GetScene() const { return scene_.get(); } - mjrCamera SceneBridge::GetCamera() const { return camera_; } } // namespace mujoco diff --git a/src/experimental/filament/compat/scene_bridge.h b/src/experimental/filament/compat/scene_bridge.h index 2b0a0f1e..b05fcc5f 100644 --- a/src/experimental/filament/compat/scene_bridge.h +++ b/src/experimental/filament/compat/scene_bridge.h @@ -35,7 +35,7 @@ namespace mujoco { // Manages all mjModel data and updates a SceneView using an mjvScene. class SceneBridge { public: - SceneBridge(mjrfContext* ctx, const mjModel* model); + SceneBridge(mjrfContext* ctx, mjrfScene* scene, const mjModel* model); ~SceneBridge(); // Updates the Entities in the filament Scene to match the current mjvScene @@ -50,8 +50,7 @@ class SceneBridge { using DrawTextAtFn = std::function; void SetDrawTextFunction(DrawTextAtFn fn); - // Returns the managed scene. - mjrfScene* GetScene() const; + // Returns the camera used for rendering the scene. mjrCamera GetCamera() const; SceneBridge(const SceneBridge&) = delete; @@ -64,12 +63,12 @@ class SceneBridge { const filament::math::float3& pos) const; mjrfContext* ctx_ = nullptr; + mjrfScene* scene_ = nullptr; std::unique_ptr model_objects_; std::unique_ptr scene_objects_; std::unique_ptr light_manager_; mjrCamera camera_; DrawTextAtFn draw_text_callback_; - UniquePtr scene_{nullptr, nullptr}; std::vector> renderables_; filament::math::mat4 clip_from_world_; }; diff --git a/src/experimental/filament/mjr_compat.cc b/src/experimental/filament/mjr_compat.cc index 39c0e6b3..c1da2fd3 100644 --- a/src/experimental/filament/mjr_compat.cc +++ b/src/experimental/filament/mjr_compat.cc @@ -59,7 +59,8 @@ class CompatContext { private: mjrDrawMode draw_mode_ = mjDRAW_MODE_DEFAULT; - UniquePtr context_; + UniquePtr context_{nullptr, nullptr}; + UniquePtr scene_{nullptr, nullptr}; std::unique_ptr scene_bridge_; mjtFramebuffer framebuffer_ = mjFB_WINDOW; UniquePtr color_target_{nullptr, nullptr}; @@ -67,9 +68,11 @@ class CompatContext { }; CompatContext::CompatContext(const mjrfContextConfig* config, - const mjModel* model) - : context_(CreateContext(*config)) { - scene_bridge_ = std::make_unique(context_.get(), model); + const mjModel* model) { + context_ = CreateContext(*config); + scene_ = CreateScene(context_.get(), {}); + scene_bridge_ = + std::make_unique(context_.get(), scene_.get(), model); } void CompatContext::Render(const mjrRect& viewport, const mjvScene* scene) { @@ -92,7 +95,7 @@ void CompatContext::Render(const mjrRect& viewport, const mjvScene* scene) { if (framebuffer_ == mjFB_WINDOW) { mjrfRenderRequest req; mjrf_defaultRenderRequest(&req); - req.scene = scene_bridge_->GetScene(); + req.scene = scene_.get(); req.draw_mode = draw_mode_; req.camera = scene_bridge_->GetCamera(); req.viewport = viewport; @@ -121,7 +124,7 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb, mjrfRenderRequest req; mjrf_defaultRenderRequest(&req); - req.scene = scene_bridge_->GetScene(); + req.scene = scene_.get(); req.draw_mode = draw_mode_; req.camera = scene_bridge_->GetCamera(); req.viewport = viewport; @@ -149,7 +152,7 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb, mjrfRenderRequest req; mjrf_defaultRenderRequest(&req); - req.scene = scene_bridge_->GetScene(); + req.scene = scene_.get(); req.draw_mode = mjDRAW_MODE_DEPTH; req.camera = scene_bridge_->GetCamera(); req.viewport = viewport; diff --git a/src/experimental/platform/hal/renderer.cc b/src/experimental/platform/hal/renderer.cc index e462e9d0..81d983b6 100644 --- a/src/experimental/platform/hal/renderer.cc +++ b/src/experimental/platform/hal/renderer.cc @@ -69,8 +69,8 @@ Renderer::Renderer(void* native_window, GraphicsMode gfx) } g_update_gui_callback = [this]() { - if (scene_bridge_) { - mjrf_DEBUG_drawImguiEditor(scene_bridge_->GetScene()); + if (main_scene_) { + mjrf_DEBUG_drawImguiEditor(main_scene_.get()); } }; } @@ -102,9 +102,12 @@ void Renderer::Init(const mjModel* model) { ? mjGRAPHICS_API_OPENGL : mjGRAPHICS_API_VULKAN; filament_context_ = CreateContext(cfg); - scene_bridge_ = - std::make_unique(filament_context_.get(), model); - imgui_bridge_ = std::make_unique(filament_context_.get()); + main_scene_ = CreateScene(filament_context_.get(), {}); + ux_scene_ = CreateScene(filament_context_.get(), {}); + scene_bridge_ = std::make_unique(filament_context_.get(), + main_scene_.get(), model); + imgui_bridge_ = std::make_unique(filament_context_.get(), + ux_scene_.get()); scene_bridge_->SetDrawTextFunction(DrawTextAt); } @@ -122,6 +125,8 @@ void Renderer::Deinit() { } else { scene_bridge_.reset(); imgui_bridge_.reset(); + ux_scene_.reset(); + main_scene_.reset(); filament_context_.reset(); } initialized_ = false; @@ -242,7 +247,7 @@ void Renderer::DoRender(int width, int height) { mjrfRenderRequest reqs[2]; mjrf_defaultRenderRequest(&reqs[0]); - reqs[0].scene = scene_bridge_->GetScene(); + reqs[0].scene = main_scene_.get(); reqs[0].draw_mode = draw_mode; reqs[0].camera = scene_bridge_->GetCamera(); reqs[0].viewport = viewport; @@ -250,7 +255,7 @@ void Renderer::DoRender(int width, int height) { reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION]; mjrf_defaultRenderRequest(&reqs[1]); - reqs[1].scene = imgui_bridge_->GetScene(); + reqs[1].scene = ux_scene_.get(); reqs[1].draw_mode = mjDRAW_MODE_DEFAULT; reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height); reqs[1].viewport = viewport; @@ -308,7 +313,7 @@ void Renderer::DoReadPixels(int width, int height, unsigned char* rgb) { mjrfRenderRequest reqs[2]; mjrf_defaultRenderRequest(&reqs[0]); - reqs[0].scene = scene_bridge_->GetScene(); + reqs[0].scene = main_scene_.get(); reqs[0].draw_mode = draw_mode; reqs[0].camera = scene_bridge_->GetCamera(); reqs[0].target = target.get(); @@ -317,7 +322,7 @@ void Renderer::DoReadPixels(int width, int height, unsigned char* rgb) { reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION]; mjrf_defaultRenderRequest(&reqs[1]); - reqs[1].scene = imgui_bridge_->GetScene(); + reqs[1].scene = ux_scene_.get(); reqs[1].draw_mode = mjDRAW_MODE_DEFAULT; reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height); reqs[1].target = target.get(); diff --git a/src/experimental/platform/hal/renderer.h b/src/experimental/platform/hal/renderer.h index bc82ea38..f94a7570 100644 --- a/src/experimental/platform/hal/renderer.h +++ b/src/experimental/platform/hal/renderer.h @@ -112,6 +112,8 @@ class Renderer { // State used by the filament renderer. UniquePtr filament_context_{nullptr, nullptr}; + UniquePtr main_scene_{nullptr, nullptr}; + UniquePtr ux_scene_{nullptr, nullptr}; std::unique_ptr scene_bridge_; std::unique_ptr imgui_bridge_; diff --git a/src/experimental/platform/ux/imgui_bridge.cc b/src/experimental/platform/ux/imgui_bridge.cc index 14e8568c..28e3f331 100644 --- a/src/experimental/platform/ux/imgui_bridge.cc +++ b/src/experimental/platform/ux/imgui_bridge.cc @@ -33,10 +33,10 @@ namespace mujoco { using filament::math::float3; using filament::math::mat3f; -ImguiBridge::ImguiBridge(mjrfContext* ctx) : ctx_(ctx) { +ImguiBridge::ImguiBridge(mjrfContext* ctx, mjrfScene* scene) + : ctx_(ctx), scene_(scene) { mjrfSceneParams params; mjrf_defaultSceneParams(¶ms); - scene_ = CreateScene(ctx_, params); } ImguiBridge::~ImguiBridge() { @@ -287,16 +287,14 @@ void ImguiBridge::PrepareRenderables(int count) { params.receive_shadows = false; params.blend_order = static_cast(renderables_.size() + 1); auto& renderable = renderables_.emplace_back(CreateRenderable(ctx_, params)); - mjrf_addRenderableToScene(scene_.get(), renderable.get()); + mjrf_addRenderableToScene(scene_, renderable.get()); } while (renderables_.size() > count) { - mjrf_removeRenderableFromScene(scene_.get(), renderables_.back().get()); + mjrf_removeRenderableFromScene(scene_, renderables_.back().get()); renderables_.pop_back(); } } -mjrfScene* ImguiBridge::GetScene() const { return scene_.get(); } - mjrCamera ImguiBridge::GetCamera(int width, int height) const { mjrCamera camera; camera.orthographic = true; diff --git a/src/experimental/platform/ux/imgui_bridge.h b/src/experimental/platform/ux/imgui_bridge.h index 432e7ec7..beec4a5c 100644 --- a/src/experimental/platform/ux/imgui_bridge.h +++ b/src/experimental/platform/ux/imgui_bridge.h @@ -28,7 +28,7 @@ namespace mujoco { // Creates and manages a SceneView using data read from ImGui. class ImguiBridge { public: - explicit ImguiBridge(mjrfContext* ctx); + explicit ImguiBridge(mjrfContext* ctx, mjrfScene* scene); ~ImguiBridge(); // Prepares the Renderables using data from the current ImGui state. This @@ -36,8 +36,7 @@ class ImguiBridge { // synced. void Update(); - // Returns the managed UX scene. - mjrfScene* GetScene() const; + // Returns the camera used for rendering the UX scene. mjrCamera GetCamera(int width, int height) const; // Uploads texture to be used with ImGui's Image and ImageButton functions. @@ -58,7 +57,7 @@ class ImguiBridge { mjrfTexture* GetTexture(uintptr_t tex_id) const; mjrfContext* ctx_ = nullptr; - UniquePtr scene_{nullptr, nullptr}; + mjrfScene* scene_ = nullptr; std::vector> renderables_; std::vector> meshes_; std::unordered_map> textures_;