First-pass of a plugin system for GUI elements.
Refactor filament's debug drawing to be one such plugin. PiperOrigin-RevId: 859002002 Change-Id: Ibe9000dec19fce648eef6d57170ce435b9a8c6ff
This commit is contained in:
committed by
Copybara-Service
parent
bf05bb1885
commit
e2180ff744
@@ -47,6 +47,8 @@ target_sources(${MUJOCO_PLATFORM_TARGET_NAME}
|
||||
interaction.h
|
||||
picture_gui.h
|
||||
picture_gui.cc
|
||||
plugin.cc
|
||||
plugin.h
|
||||
renderer.cc
|
||||
renderer.h
|
||||
sim_history.cc
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
// Copyright 2026 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "experimental/platform/plugin.h"
|
||||
#include "engine/engine_global_table.h"
|
||||
|
||||
namespace mujoco::platform {
|
||||
|
||||
void RegisterGuiPlugin(const GuiPlugin* plugin) {
|
||||
if (plugin->name == nullptr || plugin->name[0] == '\0') {
|
||||
mju_error("Plugin name must not be empty or null.");
|
||||
}
|
||||
GlobalTable<GuiPlugin>::GetSingleton().AppendIfUnique(*plugin);
|
||||
}
|
||||
|
||||
void ForEachGuiPlugin(const std::function<void(GuiPlugin*)>& fn) {
|
||||
auto& table = GlobalTable<GuiPlugin>::GetSingleton();
|
||||
for (int i = 0; i < table.count(); ++i) {
|
||||
const GuiPlugin* plugin = table.GetAtSlot(i);
|
||||
fn(const_cast<GuiPlugin*>(plugin));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mujoco::platform
|
||||
|
||||
using mujoco::GlobalTable;
|
||||
using GuiPlugin = mujoco::platform::GuiPlugin;
|
||||
|
||||
template <>
|
||||
const char* GlobalTable<GuiPlugin>::HumanReadableTypeName() {
|
||||
return "gui plugin";
|
||||
}
|
||||
|
||||
template <>
|
||||
std::string_view GlobalTable<GuiPlugin>::ObjectKey(const GuiPlugin& plugin) {
|
||||
return std::string_view(plugin.name);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool GlobalTable<GuiPlugin>::ObjectEqual(const GuiPlugin& p1, const GuiPlugin& p2) {
|
||||
return CaseInsensitiveEqual(p1.name, p2.name);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool GlobalTable<GuiPlugin>::CopyObject(GuiPlugin& dst, const GuiPlugin& src, ErrorMessage& err) {
|
||||
dst = src;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// Copyright 2026 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_PLUGIN_H_
|
||||
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_PLUGIN_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace mujoco::platform {
|
||||
|
||||
// Important: Do not inherit from these plugin structs. They are copied by value
|
||||
// and therefore any derived classes will be sliced. We assume plugins are
|
||||
// effectively globals and so any pointers will be valid for the lifetime
|
||||
// of the process.
|
||||
|
||||
// Plugin for processing custom UI windows. The plugin will be listed in the
|
||||
// "Plugins" main menu and, when selected, an ImGui window will be opened with
|
||||
// the name of the plugin as the title. The `update` function can then be used
|
||||
// to process the GUI. All functions will be called by passing `this` as the
|
||||
// first argument.
|
||||
struct GuiPlugin final {
|
||||
using UpdateFn = void (*)(GuiPlugin* self);
|
||||
|
||||
// Whether or not to display the plugin window.
|
||||
bool active = false;
|
||||
|
||||
// The name of the plugin; must be unique.
|
||||
const char* name = "";
|
||||
|
||||
// The function that will update the plugin's window. Plugin GUI updates
|
||||
// happen when the window is `active` and after all other Studio GUI updates.
|
||||
UpdateFn update = nullptr;
|
||||
|
||||
// Optional data pointer.
|
||||
void* data = nullptr;
|
||||
};
|
||||
|
||||
// Registers a plugin with a global registry. The plugin must have a
|
||||
// case-insensitive unique name.
|
||||
void RegisterGuiPlugin(const GuiPlugin* plugin);
|
||||
|
||||
// Executes the given function for each registered plugin.
|
||||
void ForEachGuiPlugin(const std::function<void(GuiPlugin*)>& fn);
|
||||
|
||||
} // namespace mujoco::platform
|
||||
|
||||
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_PLUGIN_H_
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#if defined(USE_FILAMENT_OPENGL) || defined(USE_FILAMENT_VULKAN)
|
||||
#include "experimental/filament/render_context_filament.h"
|
||||
#include "experimental/platform/plugin.h"
|
||||
#elif defined(USE_CLASSIC_OPENGL)
|
||||
#include <imgui.h>
|
||||
#include <backends/imgui_impl_opengl3.h>
|
||||
@@ -136,3 +137,14 @@ int Renderer::UploadImage(int texture_id, const std::byte* pixels, int width,
|
||||
double Renderer::GetFps() { return fps_; }
|
||||
|
||||
} // namespace mujoco::platform
|
||||
|
||||
#if !defined(USE_CLASSIC_OPENGL)
|
||||
mjPLUGIN_LIB_INIT {
|
||||
mujoco::platform::GuiPlugin plugin;
|
||||
plugin.name = "Filament";
|
||||
plugin.update = [](mujoco::platform::GuiPlugin* self) {
|
||||
mjr_updateGui(nullptr);
|
||||
};
|
||||
mujoco::platform::RegisterGuiPlugin(&plugin);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user