bool ResourceManager::loadStage()

in src/esp/assets/ResourceManager.cpp [287:448]


bool ResourceManager::loadStage(
    const StageAttributes::ptr& stageAttributes,
    const SceneObjectInstanceAttributes::cptr& stageInstanceAttributes,
    const std::shared_ptr<physics::PhysicsManager>& _physicsManager,
    esp::scene::SceneManager* sceneManagerPtr,
    std::vector<int>& activeSceneIDs) {
  // If the semantic mesh should be created, based on SimulatorConfiguration
  const bool createSemanticMesh =
      metadataMediator_->getSimulatorConfiguration().loadSemanticMesh;

  // Force creation of a separate semantic scene graph, even when no semantic
  // mesh is loaded for the stage.  This is required to support playback of any
  // replay that includes a semantic-only render asset instance.
  const bool forceSeparateSemanticSceneGraph =
      metadataMediator_->getSimulatorConfiguration()
          .forceSeparateSemanticSceneGraph;

  // create AssetInfos here for each potential mesh file for the scene, if they
  // are unique.
  bool buildCollisionMesh =
      ((_physicsManager != nullptr) &&
       (_physicsManager->getInitializationAttributes()->getSimulator() !=
        "none"));
  const std::string renderLightSetupKey(stageAttributes->getLightSetupKey());
  std::map<std::string, AssetInfo> assetInfoMap =
      createStageAssetInfosFromAttributes(stageAttributes, buildCollisionMesh,
                                          createSemanticMesh);

  // set equal to current Simulator::activeSemanticSceneID_ value
  int activeSemanticSceneID = activeSceneIDs[0];
  // if semantic scene load is requested and possible
  if (assetInfoMap.count("semantic") != 0u) {
    // check if file names exist
    AssetInfo semanticInfo = assetInfoMap.at("semantic");
    auto semanticStageFilename = semanticInfo.filepath;
    if (Cr::Utility::Directory::exists(semanticStageFilename)) {
      ESP_DEBUG() << "Loading Semantic Stage mesh :" << semanticStageFilename;
      activeSemanticSceneID = sceneManagerPtr->initSceneGraph();

      auto& semanticSceneGraph =
          sceneManagerPtr->getSceneGraph(activeSemanticSceneID);
      auto& semanticRootNode = semanticSceneGraph.getRootNode();
      auto& semanticDrawables = semanticSceneGraph.getDrawables();

      RenderAssetInstanceCreationInfo::Flags flags;
      flags |= RenderAssetInstanceCreationInfo::Flag::IsSemantic;
      if (stageAttributes->getFrustumCulling()) {
        // only treat as static if doing culling
        flags |= RenderAssetInstanceCreationInfo::Flag::IsStatic;
      }
      RenderAssetInstanceCreationInfo creation(
          semanticStageFilename, Cr::Containers::NullOpt, flags, NO_LIGHT_KEY);

      bool semanticStageSuccess =
          loadStageInternal(semanticInfo,  // AssetInfo
                            &creation,
                            &semanticRootNode,    // parent scene node
                            &semanticDrawables);  // drawable group

      // regardless of load failure, original code still changed
      // activeSemanticSceneID_
      if (!semanticStageSuccess) {
        ESP_ERROR() << "Semantic Stage mesh load failed.";
        return false;
      }
      ESP_DEBUG() << "Semantic Stage mesh :" << semanticStageFilename
                  << "loaded.";

    } else if (semanticStageFilename !=
               "") {  // semantic file name does not exist but house does
      ESP_ERROR() << "Not loading semantic mesh with File Name :"
                  << semanticStageFilename << "does not exist.";
    }
  } else {  // not wanting to create semantic mesh
    ESP_DEBUG() << "Not loading semantic mesh";
  }

  if (forceSeparateSemanticSceneGraph &&
      activeSemanticSceneID == activeSceneIDs[0]) {
    // Create a separate semantic scene graph if it wasn't already created
    // above.
    activeSemanticSceneID = sceneManagerPtr->initSceneGraph();
  }

  // save active semantic scene ID so that simulator can consume
  activeSceneIDs[1] = activeSemanticSceneID;
  const bool isSeparateSemanticScene = activeSceneIDs[1] != activeSceneIDs[0];

  auto& sceneGraph = sceneManagerPtr->getSceneGraph(activeSceneIDs[0]);
  auto& rootNode = sceneGraph.getRootNode();
  auto& drawables = sceneGraph.getDrawables();

  AssetInfo renderInfo = assetInfoMap.at("render");

  RenderAssetInstanceCreationInfo::Flags flags;
  flags |= RenderAssetInstanceCreationInfo::Flag::IsStatic;
  flags |= RenderAssetInstanceCreationInfo::Flag::IsRGBD;
  if (!isSeparateSemanticScene) {
    flags |= RenderAssetInstanceCreationInfo::Flag::IsSemantic;
  }
  RenderAssetInstanceCreationInfo renderCreation(
      renderInfo.filepath, Cr::Containers::NullOpt, flags, renderLightSetupKey);
  ESP_DEBUG() << "Start load render asset" << renderInfo.filepath << ".";

  bool renderMeshSuccess = loadStageInternal(renderInfo,  // AssetInfo
                                             &renderCreation,
                                             &rootNode,    // parent scene node
                                             &drawables);  //  drawable group
  if (!renderMeshSuccess) {
    ESP_ERROR()
        << "Stage render mesh load failed, Aborting stage initialization.";
    return false;
  }
  // declare mesh group variable
  std::vector<CollisionMeshData> meshGroup;
  AssetInfo& infoToUse = renderInfo;
  if (assetInfoMap.count("collision") != 0u) {
    AssetInfo colInfo = assetInfoMap.at("collision");
    if (resourceDict_.count(colInfo.filepath) == 0) {
      ESP_DEBUG() << "Start load collision asset" << colInfo.filepath << ".";
      // will not reload if already present
      bool collisionMeshSuccess =
          loadStageInternal(colInfo,   // AssetInfo
                            nullptr,   // creation
                            nullptr,   // parent scene node
                            nullptr);  // drawable group

      if (!collisionMeshSuccess) {
        ESP_ERROR() << "Stage collision mesh load failed.  Aborting stage "
                       "initialization.";
        return false;
      }
    }
    // if we have a collision mesh, and it does not exist already as a
    // collision object, add it
    if (colInfo.filepath != EMPTY_SCENE) {
      infoToUse = colInfo;
    }  // if not colInfo.filepath.compare(EMPTY_SCENE)
  }    // if collision mesh desired
  // build the appropriate mesh groups, either for the collision mesh, or, if
  // the collision mesh is empty scene

  if ((_physicsManager != nullptr) && (infoToUse.filepath != EMPTY_SCENE)) {
    bool success = buildMeshGroups(infoToUse, meshGroup);
    if (!success) {
      return false;
    }
    //! Add to physics manager - will only be null for certain tests
    // Either add with pre-built meshGroup if collision assets are loaded
    // or empty vector for mesh group - this should only be the case if
    // we are using None-type physicsManager.
    bool sceneSuccess = _physicsManager->addStage(
        stageAttributes, stageInstanceAttributes, meshGroup);
    if (!sceneSuccess) {
      ESP_ERROR() << "Adding Stage" << stageAttributes->getHandle()
                  << "to PhysicsManager failed. Aborting stage initialization.";
      return false;
    }
  }

  return true;
}  // ResourceManager::loadScene