in src/utils/viewer/viewer.cpp [1997:2224]
void Viewer::keyPressEvent(KeyEvent& event) {
const auto key = event.key();
switch (key) {
case KeyEvent::Key::R: {
const auto recorder = simulator_->getGfxReplayManager()->getRecorder();
if (recorder) {
recorder->writeSavedKeyframesToFile(gfxReplayRecordFilepath_);
}
} break;
case KeyEvent::Key::Esc:
/* Using Application::exit(), which exits at the next iteration of the
event loop (same as the window close button would do). Using
std::exit() would exit immediately, but without calling any scoped
destructors, which could hide potential destruction order issues or
crashes at exit. We don't want that. */
exit(0);
break;
case KeyEvent::Key::Tab:
if (event.modifiers() & MouseEvent::Modifier::Alt) {
setSceneInstanceFromListAndShow(curSceneInstanceIDX_);
} else {
ESP_DEBUG() << "Cycling to"
<< ((event.modifiers() & MouseEvent::Modifier::Shift)
? "previous"
: "next")
<< "SceneInstance";
setSceneInstanceFromListAndShow(getNextSceneInstanceIDX(
(event.modifiers() & MouseEvent::Modifier::Shift) ? -1 : 1));
}
break;
case KeyEvent::Key::Space:
simulating_ = !simulating_;
ESP_DEBUG() << "Physics Simulation cycling from" << !simulating_ << "to"
<< simulating_;
break;
case KeyEvent::Key::Period:
// also `>` key
simulateSingleStep_ = true;
break;
case KeyEvent::Key::Comma:
debugBullet_ = !debugBullet_;
break;
// ==== Miscellaneous ====
case KeyEvent::Key::One:
// toggle agent location recording for trajectory
setAgentLocationRecord(!agentLocRecordOn_);
break;
case KeyEvent::Key::Two:
// agent motion trajectory mesh synthesis with random color
buildTrajectoryVis();
break;
case KeyEvent::Key::Three:
// toggle between single color and multi-color trajectories
singleColorTrajectory_ = !singleColorTrajectory_;
ESP_DEBUG() << (singleColorTrajectory_
? "Building trajectory with multiple random colors "
"changed to single random color."
: "Building trajectory with single random color "
"changed to multiple random colors.");
break;
case KeyEvent::Key::Four:
// switch between camera types (Camera, Fisheye, Equirectangular)
sensorMode_ = static_cast<VisualSensorMode>(
(uint8_t(sensorMode_) + 1) %
uint8_t(VisualSensorMode::VisualSensorModeCount));
setSensorVisID();
break;
case KeyEvent::Key::Five:
// switch camera between ortho and perspective
switchCameraType();
break;
case KeyEvent::Key::Six:
// reset camera zoom
getAgentCamera().resetZoom();
break;
case KeyEvent::Key::Seven:
visualizeMode_ = static_cast<VisualizeMode>(
(uint8_t(visualizeMode_) + 1) %
uint8_t(VisualizeMode::VisualizeModeCount));
setSensorVisID();
bindRenderTarget();
break;
case KeyEvent::Key::Eight:
addPrimitiveObject();
break;
case KeyEvent::Key::Nine:
if (simulator_->getPathFinder()->isLoaded()) {
const esp::vec3f position =
simulator_->getPathFinder()->getRandomNavigablePoint();
agentBodyNode_->setTranslation(Mn::Vector3(position));
}
break;
case KeyEvent::Key::LeftBracket:
saveAgentAndSensorTransformToFile();
break;
case KeyEvent::Key::RightBracket:
loadAgentAndSensorTransformFromFile();
break;
case KeyEvent::Key::Equal: {
// increase trajectory tube diameter
ESP_DEBUG() << "Bigger";
modTrajRad(true);
break;
}
case KeyEvent::Key::Minus: {
// decrease trajectory tube diameter
ESP_DEBUG() << "Smaller";
modTrajRad(false);
break;
}
case KeyEvent::Key::B: {
// toggle bounding box on objects
drawObjectBBs = !drawObjectBBs;
for (auto id : simulator_->getExistingObjectIDs()) {
simulator_->setObjectBBDraw(drawObjectBBs, id);
}
} break;
case KeyEvent::Key::C:
showFPS_ = !showFPS_;
showFPS_ ? profiler_.enable() : profiler_.disable();
break;
case KeyEvent::Key::E:
simulator_->setFrustumCullingEnabled(
!simulator_->isFrustumCullingEnabled());
break;
case KeyEvent::Key::H:
printHelpText();
break;
case KeyEvent::Key::I:
screenshot();
break;
case KeyEvent::Key::M: {
// toggle the mouse interaction mode
mouseInteractionMode = MouseInteractionMode(
(int(mouseInteractionMode) + 1) % int(NUM_MODES));
} break;
case KeyEvent::Key::N:
// toggle navmesh visualization
simulator_->setNavMeshVisualization(
!simulator_->isNavMeshVisualizationActive());
break;
case KeyEvent::Key::O:
addTemplateObject();
break;
case KeyEvent::Key::P:
// save current sim state
simulator_->saveCurrentSceneInstance();
break;
case KeyEvent::Key::Slash:
// display current scene's metadata information
dispMetadataInfo();
break;
case KeyEvent::Key::Q:
// query the agent state
showAgentStateMsg(true, true);
break;
case KeyEvent::Key::T: {
//+ALT for fixedBase
bool fixedBase = bool(event.modifiers() & MouseEvent::Modifier::Alt);
// add an ArticulatedObject from provided filepath
std::string urdfFilepath;
if (event.modifiers() & MouseEvent::Modifier::Shift &&
!cachedURDF_.empty()) {
// quick-reload the most recently loaded URDF
ESP_DEBUG() << "URDF quick-reload: " << cachedURDF_;
urdfFilepath = cachedURDF_;
} else {
ESP_DEBUG() << "Load URDF: provide a URDF filepath.";
std::cin >> urdfFilepath;
}
if (urdfFilepath.empty()) {
ESP_DEBUG() << "... no input provided. Aborting.";
} else if (!Cr::Utility::String::endsWith(urdfFilepath, ".urdf") &&
!Cr::Utility::String::endsWith(urdfFilepath, ".URDF")) {
ESP_DEBUG() << "... input is not a URDF. Aborting.";
} else if (Cr::Utility::Directory::exists(urdfFilepath)) {
// cache the file for quick-reload with SHIFT-T
cachedURDF_ = urdfFilepath;
auto aom = simulator_->getArticulatedObjectManager();
auto ao = aom->addArticulatedObjectFromURDF(urdfFilepath, fixedBase,
1.0, 1.0, true);
ao->setTranslation(
defaultAgent_->node().transformation().transformPoint(
{0, 1.0, -1.5}));
} else {
ESP_DEBUG() << "... input file not found. Aborting.";
}
} break;
case KeyEvent::Key::L: {
// override the default light setup with the config in this directory
auto& lightLayoutMgr = simulator_->getLightLayoutAttributesManager();
auto loadedLayout = lightLayoutMgr->createObjectFromJSONFile(
"src/utils/viewer/default_light_override.lighting_config.json");
lightLayoutMgr->registerObject(loadedLayout, "default_override");
simulator_->setLightSetup(
lightLayoutMgr->createLightSetupFromAttributes("default_override"));
} break;
case KeyEvent::Key::U:
removeLastObject();
break;
case KeyEvent::Key::V:
invertGravity();
break;
#ifdef ESP_BUILD_WITH_VHACD
case KeyEvent::Key::K: {
iterateAndDisplaySignedDistanceField();
// Increase the distance visualized for next time (Pressing L
// repeatedly will visualize different distances)
voxelDistance++;
break;
}
case KeyEvent::Key::G: {
displayStageDistanceGradientField();
break;
}
#endif
default:
break;
}
// Update map of moving/looking keys which are currently pressed
if (keysPressed.count(key) > 0) {
keysPressed[key] = true;
}
redraw();
}