Rename toolbox to platform.

PiperOrigin-RevId: 838701951
Change-Id: I339eafd35d919710cb47bb04e9a8e29f92739513
This commit is contained in:
Haroon Qureshi
2025-12-01 03:57:37 -08:00
committed by Copybara-Service
parent c6b587b515
commit 139a5b6494
24 changed files with 194 additions and 195 deletions
+1 -1
View File
@@ -234,7 +234,7 @@ if(MUJOCO_BUILD_SIMULATE)
endif()
if(MUJOCO_BUILD_STUDIO)
add_subdirectory(src/experimental/toolbox)
add_subdirectory(src/experimental/platform)
add_subdirectory(src/experimental/studio)
endif()
@@ -14,11 +14,11 @@
cmake_minimum_required(VERSION 3.16)
set(MUJOCO_TOOLBOX_TARGET_NAME mujoco_toolbox)
set(MUJOCO_PLATFORM_TARGET_NAME mujoco_platform)
add_library(${MUJOCO_TOOLBOX_TARGET_NAME} STATIC)
add_library(${MUJOCO_PLATFORM_TARGET_NAME} STATIC)
target_sources(${MUJOCO_TOOLBOX_TARGET_NAME}
target_sources(${MUJOCO_PLATFORM_TARGET_NAME}
PUBLIC
gui.cc
gui.h
@@ -39,7 +39,7 @@ target_sources(${MUJOCO_TOOLBOX_TARGET_NAME}
window.cc
window.h
)
target_include_directories(${MUJOCO_TOOLBOX_TARGET_NAME}
target_include_directories(${MUJOCO_PLATFORM_TARGET_NAME}
PUBLIC
${PROJECT_SOURCE_DIR}/include
${PROJECT_SOURCE_DIR}/src
@@ -50,11 +50,11 @@ include(third_party_deps/implot)
include(third_party_deps/sdl2)
include(third_party_deps/libwebp)
target_link_libraries(${MUJOCO_TOOLBOX_TARGET_NAME}
target_link_libraries(${MUJOCO_PLATFORM_TARGET_NAME}
dear_imgui
implot
webp
SDL2::SDL2-static
)
add_library(mujoco::toolbox ALIAS ${MUJOCO_TOOLBOX_TARGET_NAME})
add_library(mujoco::platform ALIAS ${MUJOCO_PLATFORM_TARGET_NAME})
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/gui.h"
#include "experimental/platform/gui.h"
#include <algorithm>
#include <cmath>
@@ -24,10 +24,10 @@
#include <imgui.h>
#include <implot.h>
#include <mujoco/mujoco.h>
#include "experimental/toolbox/helpers.h"
#include "experimental/toolbox/imgui_widgets.h"
#include "experimental/platform/helpers.h"
#include "experimental/platform/imgui_widgets.h"
namespace mujoco::toolbox {
namespace mujoco::platform {
static ImVec2 GetFlexElementSize(int num_cols) {
const float width = (ImGui::GetContentRegionAvail().x / num_cols) -
@@ -804,4 +804,4 @@ void InfoGui(const mjModel* model, const mjData* data, bool paused, float fps) {
ImGui::Columns();
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_GUI_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_GUI_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_GUI_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_GUI_H_
// A collection of functions for building ImGui panels for common MuJoCo
// visualization and manipulation UX. These functions are primarily used by
@@ -27,7 +27,7 @@
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
// UX for controlling the physics simulation parameters (e.g. integrator,
// solver, etc.) in mjModel.
@@ -83,6 +83,6 @@ void CountsGui(const mjModel* model, mjData* data);
// FPS needs to be tracked by the caller and passed here to be displayed.
void InfoGui(const mjModel* model, const mjData* data, bool paused, float fps);
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_GUI_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_GUI_H_
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/helpers.h"
#include "experimental/platform/helpers.h"
#include <cstddef>
#include <cstdint>
@@ -32,7 +32,7 @@
#include "engine/engine_vis_visualize.h"
#include "xml/xml_api.h"
namespace mujoco::toolbox {
namespace mujoco::platform {
mjModel* LoadMujocoModel(const std::string& model_file, const mjVFS* vfs) {
mjModel* model = nullptr;
@@ -219,4 +219,4 @@ std::string KeyframeToString(const mjModel* model, const mjData* data,
return str;
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -13,8 +13,8 @@
// limitations under the License.
// Standalone functions used by Simulate.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_HELPERS_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_HELPERS_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_HELPERS_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_HELPERS_H_
#include <cstddef>
#include <functional>
@@ -25,7 +25,7 @@
#include <mujoco/mjrender.h>
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
// Function signature for loading assets from a given path.
using LoadAssetFn = std::function<std::vector<std::byte>(std::string_view)>;
@@ -61,6 +61,6 @@ std::string CameraToString(const mjData* data, const mjvCamera* camera);
std::string KeyframeToString(const mjModel* model, const mjData* data,
bool full_precision = false);
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_HELPERS_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_HELPERS_H_
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/imgui_widgets.h"
#include "experimental/platform/imgui_widgets.h"
#include <sstream>
#include <string>
@@ -21,7 +21,7 @@
#include <imgui.h>
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
void AppendIniSection(std::string& ini, const std::string& section,
const KeyValues& key_values) {
@@ -93,4 +93,4 @@ void MaybeSaveToClipboard(const std::string& contents) {
}
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_IMGUI_WIDGETS_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_IMGUI_WIDGETS_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_IMGUI_WIDGETS_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_IMGUI_WIDGETS_H_
#include <optional>
#include <utility>
@@ -25,7 +25,7 @@
#include <imgui_internal.h> // For ButtonEx and PressedOnClick
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
using KeyValues = std::unordered_map<std::string, std::string>;
@@ -223,6 +223,6 @@ inline bool ImGui_IsChordJustPressed(ImGuiKeyChord chord) {
// Saves the given contents to the clipboard if the clipboard is available.
void MaybeSaveToClipboard(const std::string& contents);
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_IMGUI_WIDGETS_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_IMGUI_WIDGETS_H_
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/interaction.h"
#include "experimental/platform/interaction.h"
#include <algorithm>
#include <cmath>
@@ -23,7 +23,7 @@
#include "engine/engine_util_misc.h"
#include "engine/engine_vis_visualize.h"
namespace mujoco::toolbox {
namespace mujoco::platform {
static mjtNum CalculateMovementScale(const mjModel* m, const mjvCamera* cam) {
float zclip[2] = {0, 0}, zver[2] = {0, 0};
@@ -624,4 +624,4 @@ int SetCamera(const mjModel* m, mjvCamera* camera, int request_idx) {
return camera_idx;
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,12 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_INTERACTION_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_INTERACTION_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_INTERACTION_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_INTERACTION_H_
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
// The result of a pick operation.
struct PickResult {
@@ -80,6 +80,6 @@ void MovePerturb(const mjModel* m, const mjData* d, const mjvCamera* cam,
mjvPerturb* pert, mjtMouse action, mjtNum reldx,
mjtNum reldy);
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_INTERACTION_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_INTERACTION_H_
@@ -12,15 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/renderer.h"
#include "experimental/platform/renderer.h"
#include <chrono>
#include <string>
#include "experimental/toolbox/helpers.h"
#include "experimental/platform/helpers.h"
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
Renderer::Renderer(MakeContextFn make_context_fn)
: make_context_fn_(make_context_fn) {
@@ -75,4 +75,4 @@ void Renderer::SaveScreenshot(const std::string& filename, int width,
SaveScreenshotToWebp(width, height, &render_context_, filename);
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_RENDERER_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_RENDERER_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_RENDERER_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_RENDERER_H_
#include <chrono>
#include <cstdint>
@@ -22,7 +22,7 @@
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
// Renders the mujoco simulation and the imgui state into the active window
// using the filament rendering backend.
@@ -76,6 +76,6 @@ class Renderer {
double fps_ = 0;
};
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_RENDERER_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_RENDERER_H_
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/sim_history.h"
#include "experimental/platform/sim_history.h"
#include <algorithm>
#include <climits>
#include <span>
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
void SimHistory::Init(int state_size, int max_history, int max_bytes) {
// History buffer will be smaller of number of states and total memory.
@@ -74,4 +74,4 @@ std::span<mjtNum> SimHistory::SetIndex(int offset) {
return history_[actual_index];
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_SIM_HISTORY_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_SIM_HISTORY_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_HISTORY_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_HISTORY_H_
#include <span>
#include <vector>
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
// A historical buffer of simulation data.
class SimHistory {
@@ -89,6 +89,6 @@ class SimHistory {
int size_ = 0;
};
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_SIM_HISTORY_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_HISTORY_H_
@@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/sim_profiler.h"
#include "experimental/platform/sim_profiler.h"
#include <mujoco/mujoco.h>
#include <imgui.h>
#include <implot.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
SimProfiler::SimProfiler() {
Clear();
@@ -164,4 +164,4 @@ void SimProfiler::DimensionsGraph() {
}
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_SIM_PROFILER_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_SIM_PROFILER_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_PROFILER_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_PROFILER_H_
#include <vector>
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
// Collects and displays profiling data for MuJoCo simulations.
class SimProfiler {
@@ -50,6 +50,6 @@ class SimProfiler {
std::vector<float> dim_iteration_;
};
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_SIM_PROFILER_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_PROFILER_H_
@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/step_control.h"
#include "experimental/platform/step_control.h"
#include <algorithm>
#include <chrono>
#include <cstdlib>
#include <ratio>
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
static mjtNum Timer() {
using Clock = std::chrono::steady_clock;
@@ -206,4 +206,4 @@ void StepControl::InjectNoise(const mjModel* m, mjData* d) {
}
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,15 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_STEP_CONTROL_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_STEP_CONTROL_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_STEP_CONTROL_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_STEP_CONTROL_H_
#include <chrono>
#include <string>
#include <mujoco/mujoco.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
using Seconds = std::chrono::duration<double>;
using Clock = std::chrono::steady_clock;
@@ -117,6 +117,6 @@ class StepControl {
bool pause_update_ = false;
};
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_STEP_CONTROL_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_STEP_CONTROL_H_
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "experimental/toolbox/window.h"
#include "experimental/platform/window.h"
#include <string>
#include <string_view>
@@ -26,7 +26,7 @@
#include <SDL_video.h>
#include <backends/imgui_impl_sdl2.h>
#include <imgui.h>
#include "experimental/toolbox/helpers.h"
#include "experimental/platform/helpers.h"
#include <mujoco/mujoco.h>
// Because X11/Xlib.h defines Status.
@@ -34,7 +34,7 @@
#undef Status
#endif
namespace mujoco::toolbox {
namespace mujoco::platform {
static void InitImGui(SDL_Window* window, const LoadAssetFn& load_asset_fn,
bool build_fonts) {
@@ -185,4 +185,4 @@ void Window::Present() {
}
}
} // namespace mujoco::toolbox
} // namespace mujoco::platform
@@ -12,16 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_WINDOW_H_
#define MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_WINDOW_H_
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_WINDOW_H_
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_WINDOW_H_
#include <string>
#include <string_view>
#include "experimental/toolbox/helpers.h"
#include "experimental/platform/helpers.h"
#include <SDL_video.h>
namespace mujoco::toolbox {
namespace mujoco::platform {
// Platform-independent window abstraction using SDL2.
//
@@ -96,6 +96,6 @@ class Window {
std::string drop_file_;
};
} // namespace mujoco::toolbox
} // namespace mujoco::platform
#endif // MUJOCO_SRC_EXPERIMENTAL_TOOLBOX_WINDOW_H_
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_WINDOW_H_
+1 -1
View File
@@ -72,7 +72,7 @@ target_link_libraries(${MUJOCO_STUDIO_TARGET_NAME}
dear_imgui_SDL2
implot
mujoco::mujoco
mujoco::toolbox
mujoco::platform
)
file(MAKE_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/assets)
+91 -91
View File
@@ -34,13 +34,13 @@
#include <imgui_internal.h>
#include <implot.h>
#include <mujoco/mujoco.h>
#include "experimental/toolbox/gui.h"
#include "experimental/toolbox/helpers.h"
#include "experimental/toolbox/imgui_widgets.h"
#include "experimental/toolbox/interaction.h"
#include "experimental/toolbox/renderer.h"
#include "experimental/toolbox/step_control.h"
#include "experimental/toolbox/window.h"
#include "experimental/platform/gui.h"
#include "experimental/platform/helpers.h"
#include "experimental/platform/imgui_widgets.h"
#include "experimental/platform/interaction.h"
#include "experimental/platform/renderer.h"
#include "experimental/platform/step_control.h"
#include "experimental/platform/window.h"
#if defined(USE_FILAMENT_OPENGL) || defined(USE_FILAMENT_VULKAN)
#include "experimental/filament/render_context_filament.h"
@@ -52,15 +52,15 @@
namespace mujoco::studio {
static constexpr toolbox::Window::Config kWindowConfig = {
static constexpr platform::Window::Config kWindowConfig = {
#ifdef EMSCRIPTEN
.render_config = toolbox::Window::RenderConfig::kFilamentWebGL,
.render_config = platform::Window::RenderConfig::kFilamentWebGL,
#elif defined(USE_FILAMENT_VULKAN)
.render_config = toolbox::Window::RenderConfig::kFilamentVulkan,
.render_config = platform::Window::RenderConfig::kFilamentVulkan,
#elif defined(USE_FILAMENT_OPENGL)
.render_config = toolbox::Window::RenderConfig::kFilamentOpenGL,
.render_config = platform::Window::RenderConfig::kFilamentOpenGL,
#elif defined(USE_CLASSIC_OPENGL)
.render_config = toolbox::Window::RenderConfig::kClassicOpenGL,
.render_config = platform::Window::RenderConfig::kClassicOpenGL,
#endif
.enable_keyboard = true,
};
@@ -145,9 +145,9 @@ static constexpr std::array<const char*, 31> kPercentRealTime = {
// clang-format on
App::App(int width, int height, std::string ini_path,
const toolbox::LoadAssetFn& load_asset_fn)
const platform::LoadAssetFn& load_asset_fn)
: ini_path_(std::move(ini_path)), load_asset_fn_(load_asset_fn) {
window_ = std::make_unique<toolbox::Window>("MuJoCo Studio", width, height,
window_ = std::make_unique<platform::Window>("MuJoCo Studio", width, height,
kWindowConfig, load_asset_fn);
ImPlot::CreateContext();
@@ -169,7 +169,7 @@ App::App(int width, int height, std::string ini_path,
mjr_makeFilamentContext(m, con, &render_config);
#endif
};
renderer_ = std::make_unique<toolbox::Renderer>(make_context_fn);
renderer_ = std::make_unique<platform::Renderer>(make_context_fn);
mjv_defaultPerturb(&perturb_);
mjv_defaultCamera(&camera_);
@@ -204,11 +204,11 @@ void App::ProcessPendingLoad() {
std::string model_file = std::move(pending_load_.value());
pending_load_.reset();
model_ = toolbox::LoadMujocoModel(model_file, nullptr);
model_ = platform::LoadMujocoModel(model_file, nullptr);
if (!model_) {
error_ = "Error loading model!";
step_control_.Pause();
model_ = toolbox::LoadMujocoModel("", nullptr);
model_ = platform::LoadMujocoModel("", nullptr);
}
data_ = mj_makeData(model_);
@@ -282,18 +282,18 @@ void App::UpdatePhysics() {
bool stepped = false;
toolbox::StepControl::Status status = step_control_.Advance(model_, data_);
if (status == toolbox::StepControl::Status::kPaused) {
platform::StepControl::Status status = step_control_.Advance(model_, data_);
if (status == platform::StepControl::Status::kPaused) {
// do nothing
} else if (status == toolbox::StepControl::Status::kOk) {
} else if (status == platform::StepControl::Status::kOk) {
stepped = true;
// If we are adding to the history we didn't have a divergence error
error_ = "";
} else if (status == toolbox::StepControl::Status::kAutoReset) {
} else if (status == platform::StepControl::Status::kAutoReset) {
ResetPhysics();
} else if (status == toolbox::StepControl::Status::kDiverged) {
} else if (status == platform::StepControl::Status::kDiverged) {
stepped = true;
for (mjtWarning w : toolbox::StepControl::kDivergedWarnings) {
for (mjtWarning w : platform::StepControl::kDivergedWarnings) {
if (data_->warning[w].number > 0) {
error_ = mju_warningText(w, data_->warning[w].lastinfo);
}
@@ -322,7 +322,7 @@ void App::LoadHistory(int offset) {
}
bool App::Update() {
const toolbox::Window::Status status = window_->NewFrame();
const platform::Window::Status status = window_->NewFrame();
#ifdef USE_CLASSIC_OPENGL
ImGui_ImplOpenGL3_NewFrame();
@@ -343,7 +343,7 @@ bool App::Update() {
UpdatePhysics();
}
return status == toolbox::Window::Status::kRunning;
return status == platform::Window::Status::kRunning;
}
void App::Render() {
@@ -412,44 +412,44 @@ void App::HandleMouseEvents() {
const mjtPertBit active =
action == mjMOUSE_MOVE_V ? mjPERT_TRANSLATE : mjPERT_ROTATE;
if (active != perturb_.active) {
toolbox::InitPerturb(model_, data_, &camera_, &perturb_, active);
platform::InitPerturb(model_, data_, &camera_, &perturb_, active);
}
toolbox::MovePerturb(model_, data_, &camera_, &perturb_, action,
platform::MovePerturb(model_, data_, &camera_, &perturb_, action,
mouse_dx, mouse_dy);
}
}
// Handle camera movement actions.
else if (is_mouse_dragging) {
if (ui_.camera_idx == toolbox::kFreeCameraIdx) {
if (ui_.camera_idx == platform::kFreeCameraIdx) {
if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
MoveCamera(toolbox::CameraMotion::PAN_TILT, mouse_dx, mouse_dy);
MoveCamera(platform::CameraMotion::PAN_TILT, mouse_dx, mouse_dy);
}
} else {
if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
MoveCamera(toolbox::CameraMotion::ORBIT, mouse_dx, mouse_dy);
MoveCamera(platform::CameraMotion::ORBIT, mouse_dx, mouse_dy);
} else if (ImGui::IsMouseDown(ImGuiMouseButton_Middle)) {
MoveCamera(toolbox::CameraMotion::ZOOM, mouse_dx, mouse_dy);
MoveCamera(platform::CameraMotion::ZOOM, mouse_dx, mouse_dy);
}
}
// Right mouse movement is relative to the horizontal and vertical planes.
if (ImGui::IsMouseDown(ImGuiMouseButton_Right) && io.KeyShift) {
MoveCamera(toolbox::CameraMotion::PLANAR_MOVE_H, mouse_dx, mouse_dy);
MoveCamera(platform::CameraMotion::PLANAR_MOVE_H, mouse_dx, mouse_dy);
} else if (ImGui::IsMouseDown(ImGuiMouseButton_Right)) {
MoveCamera(toolbox::CameraMotion::PLANAR_MOVE_V, mouse_dx, mouse_dy);
MoveCamera(platform::CameraMotion::PLANAR_MOVE_V, mouse_dx, mouse_dy);
}
}
// Mouse scroll zooms the camera towards/away from the lookat point.
// Ignored by user-centered free cameras which don't have a lookat point.
if (mouse_scroll != 0.0f && ui_.camera_idx != toolbox::kFreeCameraIdx) {
MoveCamera(toolbox::CameraMotion::ZOOM, 0, -mouse_scroll);
if (mouse_scroll != 0.0f && ui_.camera_idx != platform::kFreeCameraIdx) {
MoveCamera(platform::CameraMotion::ZOOM, 0, -mouse_scroll);
}
// Left double click.
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
toolbox::PickResult picked =
toolbox::Pick(model_, data_, &camera_, mouse_x, mouse_y,
platform::PickResult picked =
platform::Pick(model_, data_, &camera_, mouse_x, mouse_y,
window_->GetAspectRatio(), &vis_options_);
if (picked.body >= 0) {
perturb_.select = picked.body;
@@ -470,8 +470,8 @@ void App::HandleMouseEvents() {
// Right double click.
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right)) {
toolbox::PickResult picked =
toolbox::Pick(model_, data_, &camera_, mouse_x, mouse_y,
platform::PickResult picked =
platform::Pick(model_, data_, &camera_, mouse_x, mouse_y,
window_->GetAspectRatio(), &vis_options_);
mju_copy3(camera_.lookat, picked.point);
if (picked.body > 0 && io.KeyCtrl) {
@@ -479,13 +479,13 @@ void App::HandleMouseEvents() {
camera_.type = mjCAMERA_TRACKING;
camera_.trackbodyid = picked.body;
camera_.fixedcamid = -1;
ui_.camera_idx = toolbox::kTrackingCameraIdx;
ui_.camera_idx = platform::kTrackingCameraIdx;
}
}
}
void App::HandleKeyboardEvents() {
using toolbox::ImGui_IsChordJustPressed;
using platform::ImGui_IsChordJustPressed;
if (ImGui::GetIO().WantCaptureKeyboard) {
return;
}
@@ -506,8 +506,8 @@ void App::HandleKeyboardEvents() {
} else if (ImGui_IsChordJustPressed(ImGuiKey_P | ImGuiMod_Ctrl)) {
ShowPopup(tmp_.save_screenshot_popup);
} else if (ImGui_IsChordJustPressed(ImGuiKey_C | ImGuiMod_Ctrl)) {
std::string keyframe = toolbox::KeyframeToString(model_, data_, false);
toolbox::MaybeSaveToClipboard(keyframe);
std::string keyframe = platform::KeyframeToString(model_, data_, false);
platform::MaybeSaveToClipboard(keyframe);
} else if (ImGui_IsChordJustPressed(ImGuiKey_R | ImGuiMod_Ctrl)) {
LoadModel(model_file_);
} else if (ImGui_IsChordJustPressed(ImGuiKey_Q | ImGuiMod_Ctrl)) {
@@ -628,41 +628,41 @@ void App::HandleKeyboardEvents() {
ToggleFlag(vis_options_.geomgroup[5]);
} else if (model_) {
if (ImGui_IsChordJustPressed(ImGuiKey_Escape)) {
ui_.camera_idx = toolbox::SetCamera(model_, &camera_, toolbox::kTumbleCameraIdx);
ui_.camera_idx = platform::SetCamera(model_, &camera_, platform::kTumbleCameraIdx);
} else if (ImGui_IsChordJustPressed(ImGuiKey_LeftBracket)) {
ui_.camera_idx = toolbox::SetCamera(model_, &camera_, ui_.camera_idx - 1);
ui_.camera_idx = platform::SetCamera(model_, &camera_, ui_.camera_idx - 1);
} else if (ImGui_IsChordJustPressed(ImGuiKey_RightBracket)) {
ui_.camera_idx = toolbox::SetCamera(model_, &camera_, ui_.camera_idx + 1);
ui_.camera_idx = platform::SetCamera(model_, &camera_, ui_.camera_idx + 1);
}
// WASD camera controls for free camera.
if (ui_.camera_idx == toolbox::kFreeCameraIdx) {
if (ui_.camera_idx == platform::kFreeCameraIdx) {
bool moved = false;
// Move (dolly) forward/backward using W and S keys.
if (ImGui::IsKeyDown(ImGuiKey_W)) {
MoveCamera(toolbox::CameraMotion::TRUCK_DOLLY, 0, tmp_.cam_speed);
MoveCamera(platform::CameraMotion::TRUCK_DOLLY, 0, tmp_.cam_speed);
moved = true;
} else if (ImGui::IsKeyDown(ImGuiKey_S)) {
MoveCamera(toolbox::CameraMotion::TRUCK_DOLLY, 0, -tmp_.cam_speed);
MoveCamera(platform::CameraMotion::TRUCK_DOLLY, 0, -tmp_.cam_speed);
moved = true;
}
// Strafe (truck) left/right using A and D keys.
if (ImGui::IsKeyDown(ImGuiKey_A)) {
MoveCamera(toolbox::CameraMotion::TRUCK_DOLLY, -tmp_.cam_speed, 0);
MoveCamera(platform::CameraMotion::TRUCK_DOLLY, -tmp_.cam_speed, 0);
moved = true;
} else if (ImGui::IsKeyDown(ImGuiKey_D)) {
MoveCamera(toolbox::CameraMotion::TRUCK_DOLLY, tmp_.cam_speed, 0);
MoveCamera(platform::CameraMotion::TRUCK_DOLLY, tmp_.cam_speed, 0);
moved = true;
}
// Move (pedestal) up/down using Q and E keys.
if (ImGui::IsKeyDown(ImGuiKey_Q)) {
MoveCamera(toolbox::CameraMotion::TRUCK_PEDESTAL, 0, tmp_.cam_speed);
MoveCamera(platform::CameraMotion::TRUCK_PEDESTAL, 0, tmp_.cam_speed);
moved = true;
} else if (ImGui::IsKeyDown(ImGuiKey_E)) {
MoveCamera(toolbox::CameraMotion::TRUCK_PEDESTAL, 0, -tmp_.cam_speed);
MoveCamera(platform::CameraMotion::TRUCK_PEDESTAL, 0, -tmp_.cam_speed);
moved = true;
}
@@ -682,9 +682,9 @@ void App::HandleKeyboardEvents() {
void App::LoadSettings() {
if (!ini_path_.empty()) {
std::string settings = toolbox::LoadText(ini_path_);
std::string settings = platform::LoadText(ini_path_);
if (!settings.empty()) {
ui_.FromDict(toolbox::ReadIniSection(settings, "[Simulate][Data]"));
ui_.FromDict(platform::ReadIniSection(settings, "[Simulate][Data]"));
ImGui::LoadIniSettingsFromMemory(settings.data(), settings.size());
}
}
@@ -693,8 +693,8 @@ void App::LoadSettings() {
void App::SaveSettings() {
if (!ini_path_.empty()) {
std::string settings = ImGui::SaveIniSettingsToMemory();
toolbox::AppendIniSection(settings, "[Simulate][Data]", ui_.ToDict());
toolbox::SaveText(settings, ini_path_);
platform::AppendIniSection(settings, "[Simulate][Data]", ui_.ToDict());
platform::SaveText(settings, ini_path_);
}
}
@@ -708,8 +708,8 @@ void App::SetSpeedIndex(int idx) {
step_control_.SetSpeed(speed);
}
void App::MoveCamera(toolbox::CameraMotion motion, mjtNum reldx, mjtNum reldy) {
toolbox::MoveCamera(model_, data_, &camera_, motion, reldx, reldy);
void App::MoveCamera(platform::CameraMotion motion, mjtNum reldx, mjtNum reldy) {
platform::MoveCamera(model_, data_, &camera_, motion, reldx, reldy);
}
void App::BuildGui() {
@@ -729,7 +729,7 @@ void App::BuildGui() {
ImGui::End();
{
toolbox::ScopedStyle style;
platform::ScopedStyle style;
style.Var(ImGuiStyleVar_CellPadding, ImVec2(0, 0));
style.Var(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
style.Var(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
@@ -775,14 +775,14 @@ void App::BuildGui() {
ImGui::SetNextWindowPos(chart_pos, ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(chart_size, ImGuiCond_FirstUseEver);
if (ImGui::Begin("Solver", &tmp_.chart_solver)) {
toolbox::CountsGui(model_, data_);
toolbox::ConvergenceGui(model_, data_);
platform::CountsGui(model_, data_);
platform::ConvergenceGui(model_, data_);
}
ImGui::End();
}
if (tmp_.help) {
toolbox::ScopedStyle style;
platform::ScopedStyle style;
style.Var(ImGuiStyleVar_Alpha, 0.6f);
ImGui::SetNextWindowPos(ImVec2(workspace_rect.x, workspace_rect.y),
ImGuiCond_FirstUseEver);
@@ -794,10 +794,10 @@ void App::BuildGui() {
}
if (tmp_.info) {
toolbox::ScopedStyle style;
platform::ScopedStyle style;
style.Var(ImGuiStyleVar_Alpha, 0.6f);
if (ImGui::Begin("Info", &tmp_.info)) {
toolbox::InfoGui(model_, data_, step_control_.IsPaused(),
platform::InfoGui(model_, data_, step_control_.IsPaused(),
renderer_->GetFrameRate());
}
ImGui::End();
@@ -915,7 +915,7 @@ ImVec4 App::ConfigureDockingLayout() {
ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBringToFrontOnFocus |
ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_NoBackground;
toolbox::ScopedStyle style;
platform::ScopedStyle style;
style.Var(ImGuiStyleVar_WindowRounding, 0.0f);
style.Var(ImGuiStyleVar_WindowBorderSize, 0.0f);
style.Var(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
@@ -962,19 +962,19 @@ void App::ModelOptionsGui() {
ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed;
if (ImGui::TreeNodeEx("Physics Settings", flags)) {
toolbox::PhysicsGui(model_, min_width);
platform::PhysicsGui(model_, min_width);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("Rendering Settings", flags)) {
toolbox::RenderingGui(model_, &vis_options_, renderer_->GetRenderFlags(), min_width);
platform::RenderingGui(model_, &vis_options_, renderer_->GetRenderFlags(), min_width);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("Visibility Groups", flags)) {
toolbox::GroupsGui(model_, &vis_options_, min_width);
platform::GroupsGui(model_, &vis_options_, min_width);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("Visualization", flags)) {
toolbox::VisualizationGui(model_, &vis_options_, &camera_, min_width);
platform::VisualizationGui(model_, &vis_options_, &camera_, min_width);
ImGui::TreePop();
}
}
@@ -988,29 +988,29 @@ void App::DataInspectorGui() {
float noise_scale = 0;
float noise_rate = 0;
step_control_.GetNoiseParameters(noise_scale, noise_rate);
toolbox::NoiseGui(model_, data_, noise_scale, noise_rate);
platform::NoiseGui(model_, data_, noise_scale, noise_rate);
step_control_.SetNoiseParameters(noise_scale, noise_rate);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("Joints", flags)) {
toolbox::JointsGui(model_, data_, &vis_options_);
platform::JointsGui(model_, data_, &vis_options_);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("Controls", flags)) {
toolbox::ControlsGui(model_, data_, &vis_options_);
platform::ControlsGui(model_, data_, &vis_options_);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("Sensor", flags)) {
toolbox::SensorGui(model_, data_);
platform::SensorGui(model_, data_);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("Watch", flags)) {
toolbox::WatchGui(model_, data_, ui_.watch_field, sizeof(ui_.watch_field),
platform::WatchGui(model_, data_, ui_.watch_field, sizeof(ui_.watch_field),
ui_.watch_index);
ImGui::TreePop();
}
if (ImGui::TreeNodeEx("State", flags)) {
toolbox::StateGui(model_, data_, tmp_.state, tmp_.state_sig, min_width);
platform::StateGui(model_, data_, tmp_.state, tmp_.state_sig, min_width);
ImGui::TreePop();
}
}
@@ -1159,15 +1159,15 @@ void App::ToolBarGui() {
ImGui::SameLine();
std::vector<const char*> cameras = GetCameraNames();
ImGui::SetNextItemWidth(GetExpectedLabelWidth());
int camera_idx = ui_.camera_idx - toolbox::kTumbleCameraIdx;
int camera_idx = ui_.camera_idx - platform::kTumbleCameraIdx;
if (ImGui::Combo("##Camera", &camera_idx, cameras.data(), cameras.size())) {
ui_.camera_idx = ::mujoco::toolbox::SetCamera(
model_, &camera_, camera_idx + toolbox::kTumbleCameraIdx);
ui_.camera_idx = ::mujoco::platform::SetCamera(
model_, &camera_, camera_idx + platform::kTumbleCameraIdx);
}
ImGui::SameLine();
if (ImGui::Button(ICON_COPY_CAMERA)) {
std::string camera_string = toolbox::CameraToString(data_, &camera_);
toolbox::MaybeSaveToClipboard(camera_string);
std::string camera_string = platform::CameraToString(data_, &camera_);
platform::MaybeSaveToClipboard(camera_string);
}
ImGui::SetItemTooltip("%s", "Copy Camera");
@@ -1265,7 +1265,7 @@ void App::StatusBarGui() {
ImGui::Text("%s", " |");
// Frame scrubber.
toolbox::ScopedStyle style;
platform::ScopedStyle style;
style.Var(ImGuiStyleVar_FrameBorderSize, 0);
style.Color(ImGuiCol_Button, ImGui::GetStyle().Colors[ImGuiCol_WindowBg]);
@@ -1360,8 +1360,8 @@ void App::MainMenuGui() {
mj_setKeyframe(model_, data_, ui_.key_idx);
}
if (ImGui::MenuItem("Copy")) {
std::string str = toolbox::KeyframeToString(model_, data_, false);
toolbox::MaybeSaveToClipboard(str);
std::string str = platform::KeyframeToString(model_, data_, false);
platform::MaybeSaveToClipboard(str);
}
ImGui::EndMenu();
}
@@ -1373,7 +1373,7 @@ void App::MainMenuGui() {
SaveSettings();
}
if (ImGui::MenuItem("Reset Config")) {
toolbox::SaveText("\n\n", ini_path_);
platform::SaveText("\n\n", ini_path_);
LoadSettings();
}
ImGui::Separator();
@@ -1474,7 +1474,7 @@ void App::FileDialogGui() {
if (ImGui::BeginPopupModal("LoadModel", NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
if (toolbox::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
if (platform::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
LoadModel(tmp_.filename);
tmp_.last_load_file = tmp_.filename;
}
@@ -1482,7 +1482,7 @@ void App::FileDialogGui() {
}
if (ImGui::BeginPopupModal("SaveXML", NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
if (toolbox::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
if (platform::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
char err[1000] = "";
mj_saveLastXML(tmp_.filename, model_, err, 1000);
tmp_.last_save_xml_file = tmp_.filename;
@@ -1491,7 +1491,7 @@ void App::FileDialogGui() {
}
if (ImGui::BeginPopupModal("SaveMJB", NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
if (toolbox::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
if (platform::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
mj_saveModel(model_, tmp_.filename, nullptr, 0);
tmp_.last_save_mjb_file = tmp_.filename;
}
@@ -1499,7 +1499,7 @@ void App::FileDialogGui() {
}
if (ImGui::BeginPopupModal("SaveWebp", NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
if (toolbox::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
if (platform::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
renderer_->SaveScreenshot(tmp_.filename, window_->GetWidth(),
window_->GetHeight());
tmp_.last_save_screenshot_file = tmp_.filename;
@@ -1508,7 +1508,7 @@ void App::FileDialogGui() {
}
if (ImGui::BeginPopupModal("PrintModel", NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
if (toolbox::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
if (platform::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
mj_printModel(model_, tmp_.filename);
tmp_.last_print_model_file = tmp_.filename;
}
@@ -1516,7 +1516,7 @@ void App::FileDialogGui() {
}
if (ImGui::BeginPopupModal("PrintData", NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
if (toolbox::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
if (platform::ImGui_FileDialog(tmp_.filename, sizeof(tmp_.filename))) {
mj_printData(model_, data_, tmp_.filename);
tmp_.last_print_data_file = tmp_.filename;
}
+16 -16
View File
@@ -27,13 +27,13 @@
#include <imgui.h>
#include <mujoco/mujoco.h>
#include "experimental/toolbox/helpers.h"
#include "experimental/toolbox/interaction.h"
#include "experimental/toolbox/renderer.h"
#include "experimental/toolbox/sim_history.h"
#include "experimental/toolbox/sim_profiler.h"
#include "experimental/toolbox/step_control.h"
#include "experimental/toolbox/window.h"
#include "experimental/platform/helpers.h"
#include "experimental/platform/interaction.h"
#include "experimental/platform/renderer.h"
#include "experimental/platform/sim_history.h"
#include "experimental/platform/sim_profiler.h"
#include "experimental/platform/step_control.h"
#include "experimental/platform/window.h"
namespace mujoco::studio {
@@ -46,7 +46,7 @@ class App {
using Milliseconds = std::chrono::duration<double, std::milli>;
App(int width, int height, std::string ini_path,
const toolbox::LoadAssetFn& load_asset_fn);
const platform::LoadAssetFn& load_asset_fn);
// Loads a model into the simulation.
void LoadModel(std::string model_file);
@@ -74,7 +74,7 @@ class App {
struct UiState {
char watch_field[1000] = "qpos";
int watch_index = 0;
int camera_idx = toolbox::kTumbleCameraIdx;
int camera_idx = platform::kTumbleCameraIdx;
int key_idx = 0;
Style style = kLight;
@@ -145,7 +145,7 @@ class App {
void HandleMouseEvents();
void HandleKeyboardEvents();
void MoveCamera(toolbox::CameraMotion motion, mjtNum reldx, mjtNum reldy);
void MoveCamera(platform::CameraMotion motion, mjtNum reldx, mjtNum reldy);
void SetupStyle(Style style);
ImVec4 ConfigureDockingLayout();
@@ -166,12 +166,12 @@ class App {
std::string model_file_;
std::optional<std::string> pending_load_;
std::unique_ptr<toolbox::Window> window_;
std::unique_ptr<toolbox::Renderer> renderer_;
toolbox::LoadAssetFn load_asset_fn_;
toolbox::StepControl step_control_;
toolbox::SimProfiler profiler_;
toolbox::SimHistory history_;
std::unique_ptr<platform::Window> window_;
std::unique_ptr<platform::Renderer> renderer_;
platform::LoadAssetFn load_asset_fn_;
platform::StepControl step_control_;
platform::SimProfiler profiler_;
platform::SimHistory history_;
mjModel* model_ = nullptr;
mjData* data_ = nullptr;
+2 -3
View File
@@ -209,6 +209,5 @@ welcome!
We aim to provide an example application that can be easily modified and
embedded into a paper project page (see [this example](https://kzakka.com/robopianist/)).
This could be achieved by extending the Three.js example or by compiling the
MuJoCo toolbox C++ code using the Emscripten toolchain. Community suggestions
and contributions are welcome!
MuJoCo platform C++ code using the Emscripten toolchain. Community
suggestions and contributions are welcome!