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