bool Scene::loadScene(std::string sceneName) { //Get scene file path std::string file = PathReader::getPath("", sceneName.c_str(), "xml"); //Load scene file. tinyxml2::XMLDocument doc; doc.LoadFile(file.c_str()); //Invalid xml. if(doc.ErrorID() != XML_NO_ERROR) { cubeMappingSkybox = nullptr; light = nullptr; errorDescription = "Scene file doesn't exists."; return true; } //Variable used to flag the scene as erroneous. bool errorsInScene = false; //Get scene type. //Assume spectral as default. std::string sceneType = doc.RootElement()->Attribute("type"); sceneType = sceneType == "" ? "Spectral" : sceneType; //Read camera. XMLElement* cameraElement = doc.RootElement()->FirstChildElement("camera"); errorsInScene = errorsInScene || setupCamera(cameraElement); //Light. const XMLElement* lightElement = doc.RootElement()->FirstChildElement("light"); const XMLElement* lightOrigin = lightElement->FirstChildElement("origin"); if(lightElement) { std::string lightType = lightElement->Attribute("type"); if(sceneType == "RGB") { bool rgbLightCreation = setupRGBLight(lightElement, lightOrigin, lightType); errorsInScene = errorsInScene || rgbLightCreation; } else { bool spectralLightCreation = setupSpectralLight(lightElement, lightOrigin, lightType); errorsInScene = errorsInScene || spectralLightCreation; } } else { errorDescription = errorDescription + "The scene doesn't contain any light.\n"; errorsInScene = true; } //Eventually set a cube mapping skybox. setupSkyboxWithCubeMapping(doc); //Objects XMLElement *objectsElement = doc.RootElement()->FirstChildElement("objects"); if(!objectsElement) { errorDescription = errorDescription + "The scene doesn't contain any object.\n"; errorsInScene = true; } //Init geometric objects. for(XMLElement *objectElement = objectsElement->FirstChildElement("object"); objectElement != NULL; objectElement = objectElement->NextSiblingElement("object")) { std::string type = objectElement->Attribute("type"); //Object creation Model* object; bool objectCreation = setupObject(&object, objectElement); errorsInScene = errorsInScene || objectCreation; //Object material creation. const XMLElement* material = objectElement->FirstChildElement("material"); if(sceneType == "RGB") { bool materialRGBCreation = setupRGBObjectMaterial(object, material); errorsInScene = errorsInScene || materialRGBCreation; } else { bool materialBRDFCreation = setupBRDFObjectMaterial(object, material); errorsInScene = errorsInScene || materialBRDFCreation; } //add object. objects.push_back(object); } //Init polygonal mesh. for(XMLElement *objectElement = objectsElement->FirstChildElement("mesh"); objectElement != NULL; objectElement = objectElement->NextSiblingElement("mesh")) { const XMLElement* objFile = objectElement->FirstChildElement("objFile"); bool backFaceCulling = false; if(attributesExist(objFile, {"backFaceCulling"})) { backFaceCulling = objFile->FindAttribute("backFaceCulling")->BoolValue(); } std::string objName = objFile->Attribute("name"); std::string objFilePath = PathReader::getPath("OBJs", objName.c_str(), "obj"); ObjParser objParser; objParser.parseObj(objFilePath.c_str(), backFaceCulling); std::vector<Model *> pList = objParser.getPolygonalShapes(); const XMLElement* material = objectElement->FirstChildElement("material"); for(std::vector<Model *>::size_type i = 0; i != pList.size(); i++) { if(sceneType == "RGB") { bool materialRGBCreation = setupRGBObjectMaterial(pList[i], material); errorsInScene = errorsInScene || materialRGBCreation; } else { bool materialBRDFCreation = setupBRDFObjectMaterial(pList[i], material); errorsInScene = errorsInScene || materialBRDFCreation; } } //Setup AABB. const XMLElement* aabbElement = objectElement->FirstChildElement("aabb"); AxisAlignedBoundingBox aabb; setupAABB(aabb, aabbElement); //Create mesh. Model* mesh = new PolygonalMesh(pList, aabb); //Add mesh. objects.push_back(mesh); } //SCLT specific configuration. errorsInScene = errorsInScene || setupSCLTParameter(doc, sceneType); return errorsInScene; }