void Viewer::keyPressEvent()

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();
}