Move model_, data_, and spec_ into private accessors.
This is in preparation for an upcoming change. PiperOrigin-RevId: 865332731 Change-Id: I74041b3caf5de841f583f76682e1ced049557202
This commit is contained in:
committed by
Copybara-Service
parent
0add985a15
commit
c2ede20d08
@@ -229,8 +229,7 @@ void App::LoadModelFromBuffer(std::span<const std::byte> buffer,
|
||||
resource.name = (char*)filename.data();
|
||||
spec = mju_decodeResource(&resource, content_type.data(), &vfs);
|
||||
} else {
|
||||
SetLoadError(
|
||||
"Unknown content type; expected text/xml or application/mjb");
|
||||
SetLoadError("Unknown content type; expected text/xml or application/mjb");
|
||||
return;
|
||||
}
|
||||
if (err[0]) {
|
||||
@@ -327,20 +326,20 @@ void App::SetLoadError(std::string error) {
|
||||
}
|
||||
|
||||
void App::ResetPhysics() {
|
||||
mj_resetData(model_, data_);
|
||||
mj_forward(model_, data_);
|
||||
mj_resetData(model(), data());
|
||||
mj_forward(model(), data());
|
||||
step_error_ = "";
|
||||
}
|
||||
|
||||
void App::UpdatePhysics() {
|
||||
if (model_ == nullptr) {
|
||||
if (!has_model()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool stepped = false;
|
||||
platform::ForEachModelPlugin([&](platform::ModelPlugin* plugin) {
|
||||
if (plugin->do_update) {
|
||||
if (plugin->do_update(plugin, model_, data_)) {
|
||||
if (plugin->do_update(plugin, model(), data())) {
|
||||
stepped = true;
|
||||
}
|
||||
}
|
||||
@@ -348,21 +347,22 @@ void App::UpdatePhysics() {
|
||||
|
||||
if (!stepped) {
|
||||
if (!step_control_.IsPaused()) {
|
||||
mju_zero(data_->xfrc_applied, 6 * model_->nbody);
|
||||
mjv_applyPerturbPose(model_, data_, &perturb_, 0);
|
||||
mjv_applyPerturbForce(model_, data_, &perturb_);
|
||||
mju_zero(data()->xfrc_applied, 6 * model()->nbody);
|
||||
mjv_applyPerturbPose(model(), data(), &perturb_, 0);
|
||||
mjv_applyPerturbForce(model(), data(), &perturb_);
|
||||
} else {
|
||||
mjv_applyPerturbPose(model_, data_, &perturb_, 1);
|
||||
mjv_applyPerturbPose(model(), data(), &perturb_, 1);
|
||||
}
|
||||
|
||||
if (data_) {
|
||||
if (has_data()) {
|
||||
for (int i = 0; i < mjNTIMER; i++) {
|
||||
data_->timer[i].duration = 0;
|
||||
data_->timer[i].number = 0;
|
||||
data()->timer[i].duration = 0;
|
||||
data()->timer[i].number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
platform::StepControl::Status status = step_control_.Advance(model_, data_);
|
||||
platform::StepControl::Status status =
|
||||
step_control_.Advance(model(), data());
|
||||
if (status == platform::StepControl::Status::kPaused) {
|
||||
// do nothing
|
||||
} else if (status == platform::StepControl::Status::kOk) {
|
||||
@@ -374,18 +374,18 @@ void App::UpdatePhysics() {
|
||||
} else if (status == platform::StepControl::Status::kDiverged) {
|
||||
stepped = true;
|
||||
for (mjtWarning w : platform::StepControl::kDivergedWarnings) {
|
||||
if (data_->warning[w].number > 0) {
|
||||
step_error_ = mju_warningText(w, data_->warning[w].lastinfo);
|
||||
if (data()->warning[w].number > 0) {
|
||||
step_error_ = mju_warningText(w, data()->warning[w].lastinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stepped) {
|
||||
profiler_.Update(model_, data_);
|
||||
profiler_.Update(model(), data());
|
||||
std::span<mjtNum> state = history_.AddToHistory();
|
||||
if (!state.empty()) {
|
||||
mj_getState(model_, data_, state.data(), mjSTATE_INTEGRATION);
|
||||
mj_getState(model(), data(), state.data(), mjSTATE_INTEGRATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,8 +397,8 @@ void App::LoadHistory(int offset) {
|
||||
step_control_.Pause();
|
||||
|
||||
// Load the state into the data buffer.
|
||||
mj_setState(model_, data_, state.data(), mjSTATE_INTEGRATION);
|
||||
mj_forward(model_, data_);
|
||||
mj_setState(model(), data(), state.data(), mjSTATE_INTEGRATION);
|
||||
mj_forward(model(), data());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,16 +430,16 @@ void App::Render() {
|
||||
} else {
|
||||
pixels_.clear();
|
||||
}
|
||||
renderer_->Render(model_, data_, &perturb_, &camera_, &vis_options_,
|
||||
renderer_->Render(model(), data(), &perturb_, &camera_, &vis_options_,
|
||||
width * scale, height * scale, pixels_);
|
||||
|
||||
window_->EndFrame();
|
||||
window_->Present(pixels_);
|
||||
|
||||
if (data_) {
|
||||
if (has_data()) {
|
||||
for (int i = 0; i < mjNTIMER; i++) {
|
||||
data_->timer[i].duration = 0;
|
||||
data_->timer[i].number = 0;
|
||||
data()->timer[i].duration = 0;
|
||||
data()->timer[i].number = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,7 +487,7 @@ void App::HandleMouseEvents() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!model_ || !data_) {
|
||||
if (!has_model() || !has_data()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -522,9 +522,9 @@ void App::HandleMouseEvents() {
|
||||
const mjtPertBit active =
|
||||
action == mjMOUSE_MOVE_V ? mjPERT_TRANSLATE : mjPERT_ROTATE;
|
||||
if (active != perturb_.active) {
|
||||
platform::InitPerturb(model_, data_, &camera_, &perturb_, active);
|
||||
platform::InitPerturb(model(), data(), &camera_, &perturb_, active);
|
||||
}
|
||||
platform::MovePerturb(model_, data_, &camera_, &perturb_, action,
|
||||
platform::MovePerturb(model(), data(), &camera_, &perturb_, action,
|
||||
mouse_dx, mouse_dy);
|
||||
}
|
||||
}
|
||||
@@ -559,7 +559,7 @@ void App::HandleMouseEvents() {
|
||||
// Left double click.
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
platform::PickResult picked =
|
||||
platform::Pick(model_, data_, &camera_, mouse_x, mouse_y,
|
||||
platform::Pick(model(), data(), &camera_, mouse_x, mouse_y,
|
||||
window_->GetAspectRatio(), &vis_options_);
|
||||
if (picked.body >= 0) {
|
||||
perturb_.select = picked.body;
|
||||
@@ -568,8 +568,8 @@ void App::HandleMouseEvents() {
|
||||
|
||||
// Compute the local position of the selected object in the world.
|
||||
mjtNum tmp[3];
|
||||
mju_sub3(tmp, picked.point, data_->xpos + 3 * picked.body);
|
||||
mju_mulMatTVec(perturb_.localpos, data_->xmat + 9 * picked.body, tmp, 3,
|
||||
mju_sub3(tmp, picked.point, data()->xpos + 3 * picked.body);
|
||||
mju_mulMatTVec(perturb_.localpos, data()->xmat + 9 * picked.body, tmp, 3,
|
||||
3);
|
||||
} else {
|
||||
perturb_.select = 0;
|
||||
@@ -581,7 +581,7 @@ void App::HandleMouseEvents() {
|
||||
// Right double click.
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right)) {
|
||||
platform::PickResult picked =
|
||||
platform::Pick(model_, data_, &camera_, mouse_x, mouse_y,
|
||||
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) {
|
||||
@@ -618,14 +618,14 @@ void App::HandleKeyboardEvents() {
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_P | ImGuiMod_Ctrl)) {
|
||||
tmp_.file_dialog = UiTempState::FileDialog_SaveScreenshot;
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_C | ImGuiMod_Ctrl)) {
|
||||
std::string keyframe = platform::KeyframeToString(model_, data_, false);
|
||||
std::string keyframe = platform::KeyframeToString(model(), data(), false);
|
||||
platform::MaybeSaveToClipboard(keyframe);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_L | ImGuiMod_Ctrl)) {
|
||||
RequestModelReload();
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_Q | ImGuiMod_Ctrl)) {
|
||||
tmp_.should_exit = true;
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_A | ImGuiMod_Ctrl)) {
|
||||
mjv_defaultFreeCamera(model_, &camera_);
|
||||
mjv_defaultFreeCamera(model(), &camera_);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_Tab | ImGuiMod_Shift)) {
|
||||
tmp_.inspector_panel = !tmp_.inspector_panel;
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_Tab)) {
|
||||
@@ -651,7 +651,7 @@ void App::HandleKeyboardEvents() {
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_Backspace)) {
|
||||
ResetPhysics();
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_PageUp)) {
|
||||
SelectParentPerturb(model_, perturb_);
|
||||
SelectParentPerturb(model(), perturb_);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_F1)) {
|
||||
ToggleWindow(tmp_.help);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_F2)) {
|
||||
@@ -740,16 +740,16 @@ void App::HandleKeyboardEvents() {
|
||||
ToggleFlag(vis_options_.geomgroup[4]);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_5)) {
|
||||
ToggleFlag(vis_options_.geomgroup[5]);
|
||||
} else if (model_) {
|
||||
} else if (has_model()) {
|
||||
if (ImGui_IsChordJustPressed(ImGuiKey_Escape)) {
|
||||
ui_.camera_idx =
|
||||
platform::SetCamera(model_, &camera_, platform::kTumbleCameraIdx);
|
||||
platform::SetCamera(model(), &camera_, platform::kTumbleCameraIdx);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_LeftBracket)) {
|
||||
ui_.camera_idx =
|
||||
platform::SetCamera(model_, &camera_, ui_.camera_idx - 1);
|
||||
platform::SetCamera(model(), &camera_, ui_.camera_idx - 1);
|
||||
} else if (ImGui_IsChordJustPressed(ImGuiKey_RightBracket)) {
|
||||
ui_.camera_idx =
|
||||
platform::SetCamera(model_, &camera_, ui_.camera_idx + 1);
|
||||
platform::SetCamera(model(), &camera_, ui_.camera_idx + 1);
|
||||
}
|
||||
|
||||
// WASD camera controls for free camera.
|
||||
@@ -843,7 +843,7 @@ void App::SetSpeedIndex(int idx) {
|
||||
|
||||
void App::MoveCamera(platform::CameraMotion motion, mjtNum reldx,
|
||||
mjtNum reldy) {
|
||||
platform::MoveCamera(model_, data_, &camera_, motion, reldx, reldy);
|
||||
platform::MoveCamera(model(), data(), &camera_, motion, reldx, reldy);
|
||||
}
|
||||
|
||||
void App::BuildGui() {
|
||||
@@ -919,15 +919,15 @@ void App::BuildGui() {
|
||||
ImGui::SetNextWindowPos(chart_pos, ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowSize(chart_size, ImGuiCond_FirstUseEver);
|
||||
if (ImGui::Begin("Solver", &tmp_.chart_solver)) {
|
||||
platform::CountsGui(model_, data_);
|
||||
platform::ConvergenceGui(model_, data_);
|
||||
platform::CountsGui(model(), data());
|
||||
platform::ConvergenceGui(model(), data());
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (tmp_.picture_in_picture) {
|
||||
if (ImGui::Begin("Picture-in-Picture", &tmp_.picture_in_picture)) {
|
||||
PipGui(model_, data_, window_.get(), renderer_.get(), &tmp_.pips);
|
||||
PipGui(model(), data(), window_.get(), renderer_.get(), &tmp_.pips);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -949,7 +949,7 @@ void App::BuildGui() {
|
||||
style.Var(ImGuiStyleVar_Alpha, 0.6f);
|
||||
if (ImGui::Begin("Stats", &tmp_.stats)) {
|
||||
const float fps = renderer_->GetFps();
|
||||
platform::StatsGui(model_, data_, step_control_.IsPaused(), fps);
|
||||
platform::StatsGui(model(), data(), step_control_.IsPaused(), fps);
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -1042,14 +1042,14 @@ void App::ModelOptionsGui() {
|
||||
|
||||
ImGui::BeginChild("PhysicsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Physics Settings", node_flags)) {
|
||||
platform::PhysicsGui(model_, min_width);
|
||||
platform::PhysicsGui(model(), min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("RenderingGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Rendering Settings", node_flags)) {
|
||||
platform::RenderingGui(model_, &vis_options_, renderer_->GetRenderFlags(),
|
||||
platform::RenderingGui(model(), &vis_options_, renderer_->GetRenderFlags(),
|
||||
min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@@ -1057,21 +1057,21 @@ void App::ModelOptionsGui() {
|
||||
|
||||
ImGui::BeginChild("GroupsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Visibility Groups", node_flags)) {
|
||||
platform::GroupsGui(model_, &vis_options_, min_width);
|
||||
platform::GroupsGui(model(), &vis_options_, min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("VisualizationGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Visualization", node_flags)) {
|
||||
platform::VisualizationGui(model_, &vis_options_, &camera_, min_width);
|
||||
platform::VisualizationGui(model(), &vis_options_, &camera_, min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void App::DataInspectorGui() {
|
||||
if (data_ == nullptr) {
|
||||
if (!has_data()) {
|
||||
ImGui::Text("No mjData loaded.");
|
||||
return;
|
||||
}
|
||||
@@ -1087,7 +1087,7 @@ void App::DataInspectorGui() {
|
||||
float noise_scale = 0;
|
||||
float noise_rate = 0;
|
||||
step_control_.GetNoiseParameters(noise_scale, noise_rate);
|
||||
platform::NoiseGui(model_, data_, noise_scale, noise_rate);
|
||||
platform::NoiseGui(model(), data(), noise_scale, noise_rate);
|
||||
step_control_.SetNoiseParameters(noise_scale, noise_rate);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@@ -1095,36 +1095,36 @@ void App::DataInspectorGui() {
|
||||
|
||||
ImGui::BeginChild("JointsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Joints", node_flags)) {
|
||||
platform::JointsGui(model_, data_, &vis_options_);
|
||||
platform::JointsGui(model(), data(), &vis_options_);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("ControlsGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Controls", node_flags)) {
|
||||
platform::ControlsGui(model_, data_, &vis_options_);
|
||||
platform::ControlsGui(model(), data(), &vis_options_);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("SensorGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Sensor", node_flags)) {
|
||||
platform::SensorGui(model_, data_);
|
||||
platform::SensorGui(model(), data());
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("WatchGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("Watch", node_flags)) {
|
||||
platform::WatchGui(model_, data_, ui_.watch_field, sizeof(ui_.watch_field),
|
||||
ui_.watch_index);
|
||||
platform::WatchGui(model(), data(), ui_.watch_field,
|
||||
sizeof(ui_.watch_field), ui_.watch_index);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::BeginChild("StateGui", {0, 0}, child_flags);
|
||||
if (ImGui::TreeNodeEx("State", node_flags)) {
|
||||
platform::StateGui(model_, data_, tmp_.state, tmp_.state_sig, min_width);
|
||||
platform::StateGui(model(), data(), tmp_.state, tmp_.state_sig, min_width);
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
@@ -1140,7 +1140,7 @@ void DisplayElementTree(mjsElement* element) {
|
||||
}
|
||||
|
||||
void App::SpecExplorerGui() {
|
||||
if (spec_ == nullptr) {
|
||||
if (!has_spec()) {
|
||||
ImGui::Text("No mjSpec loaded.");
|
||||
return;
|
||||
}
|
||||
@@ -1149,7 +1149,7 @@ void App::SpecExplorerGui() {
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_Framed;
|
||||
|
||||
auto display_group = [this](mjtObj type, const std::string& prefix) {
|
||||
mjsElement* element = mjs_firstElement(spec_, type);
|
||||
mjsElement* element = mjs_firstElement(spec(), type);
|
||||
while (element) {
|
||||
const int id = mjs_getId(element);
|
||||
|
||||
@@ -1164,14 +1164,14 @@ void App::SpecExplorerGui() {
|
||||
tmp_.element_id = id;
|
||||
}
|
||||
|
||||
element = mjs_nextElement(spec_, element);
|
||||
element = mjs_nextElement(spec(), element);
|
||||
}
|
||||
};
|
||||
|
||||
if (ImGui::TreeNodeEx("Bodies", flags)) {
|
||||
// We don't use `display_group` here because we do additional selection
|
||||
// logic tied to the `perturb_` field.
|
||||
mjsElement* element = mjs_firstElement(spec_, mjOBJ_BODY);
|
||||
mjsElement* element = mjs_firstElement(spec(), mjOBJ_BODY);
|
||||
while (element) {
|
||||
const int id = mjs_getId(element);
|
||||
|
||||
@@ -1191,7 +1191,7 @@ void App::SpecExplorerGui() {
|
||||
perturb_.select = id;
|
||||
}
|
||||
|
||||
element = mjs_nextElement(spec_, element);
|
||||
element = mjs_nextElement(spec(), element);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@@ -1217,18 +1217,20 @@ void App::PropertiesGui() {
|
||||
case mjOBJ_BODY:
|
||||
ImGui::Text("Body");
|
||||
ImGui::Separator();
|
||||
platform::BodyPropertiesGui(model_, data_, tmp_.element, tmp_.element_id);
|
||||
platform::BodyPropertiesGui(model(), data(), tmp_.element,
|
||||
tmp_.element_id);
|
||||
break;
|
||||
case mjOBJ_JOINT:
|
||||
ImGui::Text("Joint");
|
||||
ImGui::Separator();
|
||||
platform::JointPropertiesGui(model_, data_, tmp_.element,
|
||||
platform::JointPropertiesGui(model(), data(), tmp_.element,
|
||||
tmp_.element_id);
|
||||
break;
|
||||
case mjOBJ_SITE:
|
||||
ImGui::Text("Site");
|
||||
ImGui::Separator();
|
||||
platform::SitePropertiesGui(model_, data_, tmp_.element, tmp_.element_id);
|
||||
platform::SitePropertiesGui(model(), data(), tmp_.element,
|
||||
tmp_.element_id);
|
||||
break;
|
||||
default:
|
||||
// ignore other types
|
||||
@@ -1431,8 +1433,8 @@ void App::ToolBarGui() {
|
||||
if (ImGui::BeginCombo("##Camera", cameras[camera_idx], combo_flags)) {
|
||||
for (int n = 0; n < cameras.size(); n++) {
|
||||
if (ImGui::Selectable(cameras[n], (camera_idx == n))) {
|
||||
ui_.camera_idx = platform::SetCamera(
|
||||
model_, &camera_, n + platform::kTumbleCameraIdx);
|
||||
ui_.camera_idx = platform::SetCamera(model(), &camera_,
|
||||
n + platform::kTumbleCameraIdx);
|
||||
}
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
@@ -1440,7 +1442,7 @@ void App::ToolBarGui() {
|
||||
ImGui::SetItemTooltip("%s", "Camera");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(ICON_COPY_CAMERA)) {
|
||||
std::string camera_string = platform::CameraToString(data_, &camera_);
|
||||
std::string camera_string = platform::CameraToString(data(), &camera_);
|
||||
platform::MaybeSaveToClipboard(camera_string);
|
||||
}
|
||||
ImGui::SetItemTooltip("%s", "Copy Camera");
|
||||
@@ -1524,7 +1526,7 @@ void App::StatusBarGui() {
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (model_ == nullptr) {
|
||||
if (!has_model()) {
|
||||
ImGui::Text("No model loaded");
|
||||
} else if (step_control_.IsPaused()) {
|
||||
ImGui::Text("Paused");
|
||||
@@ -1645,16 +1647,16 @@ void App::MainMenuGui() {
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu("Keyframes")) {
|
||||
ImGui::SetNextItemWidth(200);
|
||||
ImGui::SliderInt("##Key", &ui_.key_idx, 0, model_->nkey);
|
||||
ImGui::SliderInt("##Key", &ui_.key_idx, 0, model()->nkey);
|
||||
if (ImGui::MenuItem("Load")) {
|
||||
mj_resetDataKeyframe(model_, data_, ui_.key_idx);
|
||||
mj_forward(model_, data_);
|
||||
mj_resetDataKeyframe(model(), data(), ui_.key_idx);
|
||||
mj_forward(model(), data());
|
||||
}
|
||||
if (ImGui::MenuItem("Save")) {
|
||||
mj_setKeyframe(model_, data_, ui_.key_idx);
|
||||
mj_setKeyframe(model(), data(), ui_.key_idx);
|
||||
}
|
||||
if (ImGui::MenuItem("Copy")) {
|
||||
std::string str = platform::KeyframeToString(model_, data_, false);
|
||||
std::string str = platform::KeyframeToString(model(), data(), false);
|
||||
platform::MaybeSaveToClipboard(str);
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
@@ -1748,25 +1750,25 @@ void App::FileDialogGui() {
|
||||
RequestModelLoad(res.path);
|
||||
break;
|
||||
case UiTempState::FileDialog_SaveXml:
|
||||
mj_saveLastXML(res.path.c_str(), model_, nullptr, 0);
|
||||
mj_saveLastXML(res.path.c_str(), model(), nullptr, 0);
|
||||
break;
|
||||
case UiTempState::FileDialog_SaveMjb:
|
||||
mj_saveModel(model_, res.path.c_str(), nullptr, 0);
|
||||
mj_saveModel(model(), res.path.c_str(), nullptr, 0);
|
||||
break;
|
||||
case UiTempState::FileDialog_SaveScreenshot: {
|
||||
const int width = window_->GetWidth();
|
||||
const int height = window_->GetHeight();
|
||||
std::vector<std::byte> buffer(width * height * 3);
|
||||
renderer_->RenderToTexture(model_, data_, &camera_, width, height,
|
||||
renderer_->RenderToTexture(model(), data(), &camera_, width, height,
|
||||
buffer.data());
|
||||
platform::SaveToWebp(width, height, buffer.data(), res.path);
|
||||
break;
|
||||
}
|
||||
case UiTempState::FileDialog_PrintModel:
|
||||
mj_printModel(model_, res.path.c_str());
|
||||
mj_printModel(model(), res.path.c_str());
|
||||
break;
|
||||
case UiTempState::FileDialog_PrintData:
|
||||
mj_printData(model_, data_, res.path.c_str());
|
||||
mj_printData(model(), data(), res.path.c_str());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1818,14 +1820,14 @@ float App::GetExpectedLabelWidth() {
|
||||
|
||||
std::vector<const char*> App::GetCameraNames() {
|
||||
if (tmp_.camera_names.empty()) {
|
||||
tmp_.camera_names.reserve(model_->ncam + 3);
|
||||
tmp_.camera_names.reserve(model()->ncam + 3);
|
||||
|
||||
tmp_.camera_names.push_back("Free: tumble");
|
||||
tmp_.camera_names.push_back("Free: wasd");
|
||||
tmp_.camera_names.push_back("Tracking (-1)");
|
||||
for (int i = 0; i < model_->ncam; i++) {
|
||||
if (model_->names[model_->name_camadr[i]]) {
|
||||
tmp_.camera_names.push_back(model_->names + model_->name_camadr[i]);
|
||||
for (int i = 0; i < model()->ncam; i++) {
|
||||
if (model()->names[model()->name_camadr[i]]) {
|
||||
tmp_.camera_names.push_back(model()->names + model()->name_camadr[i]);
|
||||
} else {
|
||||
tmp_.camera_names.push_back("Unnamed");
|
||||
}
|
||||
|
||||
@@ -207,6 +207,13 @@ class App {
|
||||
float GetExpectedLabelWidth();
|
||||
std::vector<const char*> GetCameraNames();
|
||||
|
||||
mjSpec* spec() { return spec_; }
|
||||
mjModel* model() { return model_; }
|
||||
mjData* data() { return data_; }
|
||||
bool has_spec() const { return spec_ != nullptr; }
|
||||
bool has_model() const { return model_ != nullptr; }
|
||||
bool has_data() const { return data_ != nullptr; }
|
||||
|
||||
std::string ini_path_;
|
||||
std::string model_name_; // Used if model_kind_ is kModelFromBuffer.
|
||||
std::string model_path_;
|
||||
|
||||
Reference in New Issue
Block a user