ofxPiMapper fixed for C++17 & oF 12.0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

524 lines
15 KiB

#include "SettingsLoader.h"
namespace ofx {
namespace piMapper {
SettingsLoader * SettingsLoader::_instance = 0;
SettingsLoader * SettingsLoader::instance(){
if(_instance == 0){
_instance = new ofx::piMapper::SettingsLoader();
}
return _instance;
}
SettingsLoader::SettingsLoader(){
_lastLoadedFilename = "surfaces.xml";
}
bool SettingsLoader::load(
SurfaceManager & surfaceManager,
MediaServer & mediaServer,
string fileName){
ofxXmlSettings * xmlSettings = new ofxXmlSettings();
string sourceType = "";
string sourceName = "";
BaseSource * source = 0;
if(!xmlSettings->loadFile(fileName)){
ofLogWarning("SettingsLoader::load()") << "Could not load XML settings";
return false;
}
if(!xmlSettings->tagExists("surfaces")){
xmlSettings->addTag("surfaces");
}
// Count <surfaces> tags.
unsigned int numPresets = xmlSettings->getNumTags("surfaces");
cout << "numPresets: " << numPresets << endl;
// Clear previous presets and surfaces first.
surfaceManager.clearPresets();
// Loop through <surfaces> tags in the XML.
for(unsigned int i = 0; i < numPresets; ++i){
xmlSettings->pushTag("surfaces", i);
SurfaceStack * surfaces = surfaceManager.createPreset();
int numSurfaces = xmlSettings->getNumTags("surface");
for(int i = 0; i < numSurfaces; i++){
if(xmlSettings->tagExists("surface", i)){
SurfaceType type = SurfaceType::NONE;
if(xmlSettings->attributeExists("surface", "type")){
type = static_cast<SurfaceType>(
xmlSettings->getAttribute("surface", "type", 0, i));
}
xmlSettings->pushTag("surface", i);
// attempt to load surface source
if(xmlSettings->tagExists("source", 0)){
xmlSettings->pushTag("source");
sourceType = xmlSettings->getValue("source-type", "");
sourceName = xmlSettings->getValue("source-name", "");
if(sourceName != "" && sourceName != "none" && sourceType != ""){
// Load source depending on type
SourceType typeEnum = SourceTypeHelper::GetSourceTypeHelperEnum(sourceType);
if(typeEnum == SourceType::SOURCE_TYPE_FBO){
// Load FBO source using sourceName
source = mediaServer.loadMedia(sourceName, typeEnum);
}else{
// Construct full path
string dir = mediaServer.getDefaultMediaDir(typeEnum);
stringstream pathss;
pathss << ofToDataPath(dir, true) << sourceName;
string sourcePath = pathss.str();
// Load media by using full path
source = mediaServer.loadMedia(sourcePath, typeEnum);
}
}
xmlSettings->popTag(); // source
}
int vertexCount = 0;
if(xmlSettings->tagExists("vertices", 0)){
xmlSettings->pushTag("vertices");
vertexCount = xmlSettings->getNumTags("vertex");
xmlSettings->popTag(); // vertices
}
if(type == SurfaceType::NONE){
if(vertexCount == 3){
type = SurfaceType::TRIANGLE_SURFACE;
}else if(vertexCount == 4){
type = SurfaceType::QUAD_SURFACE;
}else if(vertexCount > 4){
type = SurfaceType::GRID_WARP_SURFACE;
}
}
if(type == SurfaceType::TRIANGLE_SURFACE){
BaseSurface * triangleSurface = getTriangleSurface(xmlSettings);
if(sourceName != "none" && source != 0){
triangleSurface->setSource(source);
}
surfaces->push_back(triangleSurface);
}else if(type == SurfaceType::QUAD_SURFACE){
BaseSurface * quadSurface = getQuadSurface(xmlSettings);
if(sourceName != "none" && source != 0){
quadSurface->setSource(source);
}
surfaces->push_back(quadSurface);
}else if(type == SurfaceType::CIRCLE_SURFACE){
QuadSurface * base = (QuadSurface*)getQuadSurface(xmlSettings);
CircleSurface * circleSurface = new CircleSurface(*base);
if(sourceName != "none" && source != 0){
circleSurface->setSource(source);
}
surfaces->push_back(circleSurface);
}else if(type == SurfaceType::GRID_WARP_SURFACE){
BaseSurface * gridWarpSurface = getGridWarpSurface(xmlSettings);
if(sourceName != "none" && source != 0){
gridWarpSurface->setSource(source);
}
surfaces->push_back(gridWarpSurface);
}else if(type == SurfaceType::HEXAGON_SURFACE){
BaseSurface * hexagonSurface = getHexagonSurface(xmlSettings);
if(sourceName != "none" && source != 0){
hexagonSurface->setSource(source);
}
surfaces->push_back(hexagonSurface);
}
xmlSettings->popTag(); // surface
}
}
xmlSettings->popTag(); // surfaces
} // for
_lastLoadedFilename = fileName;
return true;
}
// TODO: Save all presets, not just the active one.
bool SettingsLoader::save(SurfaceManager & surfaceManager, string fileName){
ofxXmlSettings * xmlSettings = new ofxXmlSettings();
unsigned int numPresets = surfaceManager.getNumPresets();
for(unsigned int i = 0; i < numPresets; ++i){
SurfaceStack * surfaces = surfaceManager.getPresetAt(i);
// Save surfaces
xmlSettings->addTag("surfaces");
xmlSettings->pushTag("surfaces", i);
for(int i = 0; i < surfaces->size(); i++){
BaseSurface * surface = surfaces->at(i);
xmlSettings->addTag("surface");
xmlSettings->addAttribute("surface", "type", surface->getType(), i);
xmlSettings->pushTag("surface", i);
xmlSettings->addTag("vertices");
xmlSettings->pushTag("vertices");
vector <ofVec3f> * vertices = &surface->getVertices();
for(int j = 0; j < vertices->size(); j++){
xmlSettings->addTag("vertex");
xmlSettings->pushTag("vertex", j);
ofVec3f * vertex = &(*vertices)[j];
xmlSettings->addValue("x", vertex->x);
xmlSettings->addValue("y", vertex->y);
// we don't need z as it will be 0 anyways
xmlSettings->popTag(); // vertex
}
xmlSettings->popTag(); // vertices
xmlSettings->addTag("texCoords");
xmlSettings->pushTag("texCoords");
vector <Vec2> * texCoords = &surface->getTexCoords();
for(int j = 0; j < texCoords->size(); j++){
xmlSettings->addTag("texCoord");
xmlSettings->pushTag("texCoord", j);
Vec2 * texCoord = &(*texCoords)[j];
xmlSettings->addValue("x", texCoord->x);
xmlSettings->addValue("y", texCoord->y);
xmlSettings->popTag(); // texCoord
}
xmlSettings->popTag(); // texCoords
xmlSettings->addTag("source");
xmlSettings->pushTag("source");
string sourceTypeName = SourceTypeHelper::GetSourceTypeHelperName(surface->getSource()->getType());
xmlSettings->addValue("source-type", sourceTypeName);
string sourceName = surface->getSource()->getName();
xmlSettings->addValue("source-name", (sourceName == "") ? "none" : sourceName);
xmlSettings->popTag(); // source
// Save surface options
// For now only if quad surface
if (surface->getType() == SurfaceType::QUAD_SURFACE ||
surface->getType() == SurfaceType::CIRCLE_SURFACE) {
QuadSurface * qs = (QuadSurface *)surface;
if(!xmlSettings->tagExists("properties")){
xmlSettings->addTag("properties");
}
xmlSettings->pushTag("properties");
xmlSettings->addValue("perspectiveWarping", qs->getPerspectiveWarping());
xmlSettings->popTag(); // properties
}else if(surface->getType() == SurfaceType::GRID_WARP_SURFACE){
GridWarpSurface * gws = (GridWarpSurface *)surface;
if(!xmlSettings->tagExists("properties")){
xmlSettings->addTag("properties");
}
xmlSettings->pushTag("properties");
xmlSettings->addValue("gridCols", gws->getGridCols());
xmlSettings->addValue("gridRows", gws->getGridRows());
xmlSettings->popTag();
}
xmlSettings->popTag(); // surface
}
xmlSettings->popTag(); // surfaces
} // for
xmlSettings->save(fileName);
}
bool SettingsLoader::create(string fileName){
ofxXmlSettings xml;
xml.addTag("surfaces");
return xml.save(fileName);
}
BaseSurface * SettingsLoader::getTriangleSurface(ofxXmlSettings * xmlSettings){
vector <Vec2> vertices;
if(xmlSettings->tagExists("vertices")){
xmlSettings->pushTag("vertices");
if(xmlSettings->tagExists("vertex", 0)){
xmlSettings->pushTag("vertex", 0);
vertices.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("vertex", 1)){
xmlSettings->pushTag("vertex", 1);
vertices.push_back(Vec2(xmlSettings->getValue("x", 100.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("vertex", 2)){
xmlSettings->pushTag("vertex", 2);
vertices.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 100.0f)));
xmlSettings->popTag();
}
xmlSettings->popTag(); // vertices
}
vector <Vec2> texCoords;
if(xmlSettings->tagExists("texCoords")){
xmlSettings->pushTag("texCoords");
if(xmlSettings->tagExists("texCoord", 0)){
xmlSettings->pushTag("texCoord", 0);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("texCoord", 1)){
xmlSettings->pushTag("texCoord", 1);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 1.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("texCoord", 2)){
xmlSettings->pushTag("texCoord", 2);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 1.0f)));
xmlSettings->popTag();
}
xmlSettings->popTag(); // texCoords
}
// Create and add a triangle surface
BaseSurface * triangleSurface =
SurfaceFactory::instance()->createSurface(
SurfaceType::TRIANGLE_SURFACE);
triangleSurface->setVertices(vertices);
triangleSurface->setTexCoords(texCoords);
return triangleSurface;
}
BaseSurface * SettingsLoader::getQuadSurface(ofxXmlSettings * xmlSettings){
vector <Vec2> vertices;
if(xmlSettings->tagExists("vertices")){
xmlSettings->pushTag("vertices");
if(xmlSettings->tagExists("vertex", 0)){
xmlSettings->pushTag("vertex", 0);
vertices.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("vertex", 1)){
xmlSettings->pushTag("vertex", 1);
vertices.push_back(Vec2(xmlSettings->getValue("x", 100.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("vertex", 2)){
xmlSettings->pushTag("vertex", 2);
vertices.push_back(Vec2(xmlSettings->getValue("x", 100.0f),
xmlSettings->getValue("y", 100.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("vertex", 3)){
xmlSettings->pushTag("vertex", 3);
vertices.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 100.0f)));
xmlSettings->popTag();
}
xmlSettings->popTag(); // vertices
}
vector <Vec2> texCoords;
if(xmlSettings->tagExists("texCoords")){
xmlSettings->pushTag("texCoords");
if(xmlSettings->tagExists("texCoord", 0)){
xmlSettings->pushTag("texCoord", 0);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("texCoord", 1)){
xmlSettings->pushTag("texCoord", 1);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 1.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("texCoord", 2)){
xmlSettings->pushTag("texCoord", 2);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 1.0f),
xmlSettings->getValue("y", 1.0f)));
xmlSettings->popTag();
}
if(xmlSettings->tagExists("texCoord", 3)){
xmlSettings->pushTag("texCoord", 3);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 1.0f)));
xmlSettings->popTag();
}
xmlSettings->popTag(); // texCoords
}
// Create and add quad surface
BaseSurface * quadSurface =
SurfaceFactory::instance()->createSurface(
SurfaceType::QUAD_SURFACE);
quadSurface->setVertices(vertices);
quadSurface->setTexCoords(texCoords);
// Read properties
// Only perspective warping for now
bool perspectiveWarping = false;
if(xmlSettings->tagExists("properties")){
xmlSettings->pushTag("properties");
perspectiveWarping = xmlSettings->getValue("perspectiveWarping", false);
xmlSettings->popTag(); // properties
}
QuadSurface * qs = (QuadSurface *)quadSurface;
qs->setPerspectiveWarping(perspectiveWarping);
return quadSurface;
}
BaseSurface * SettingsLoader::getGridWarpSurface(ofxXmlSettings * xmlSettings){
vector <Vec2> vertices;
if(xmlSettings->tagExists("vertices")){
xmlSettings->pushTag("vertices");
int iv = 0;
while(xmlSettings->tagExists("vertex", iv)){
xmlSettings->pushTag("vertex", iv);
vertices.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
++iv;
}
xmlSettings->popTag(); // vertices
}
vector <Vec2> texCoords;
if(xmlSettings->tagExists("texCoords")){
xmlSettings->pushTag("texCoords");
int it = 0;
while(xmlSettings->tagExists("texCoord", it)){
xmlSettings->pushTag("texCoord", it);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag();
++it;
}
xmlSettings->popTag(); // texCoords
}
// Read properties
// Only perspective warping for now
int gridCols = 0;
int gridRows = 0;
if(xmlSettings->tagExists("properties")){
xmlSettings->pushTag("properties");
gridCols = xmlSettings->getValue("gridCols", 0);
gridRows = xmlSettings->getValue("gridRows", 0);
xmlSettings->popTag(); // properties
}
// Create and add quad surface
BaseSurface * gridWarpSurface =
SurfaceFactory::instance()->createSurface(
SurfaceType::GRID_WARP_SURFACE);
((GridWarpSurface *)gridWarpSurface)->setGridCols(gridCols);
((GridWarpSurface *)gridWarpSurface)->setGridRows(gridRows);
((GridWarpSurface *)gridWarpSurface)->createGridMesh();
gridWarpSurface->setVertices(vertices);
gridWarpSurface->setTexCoords(texCoords);
return gridWarpSurface;
}
BaseSurface * SettingsLoader::getHexagonSurface(ofxXmlSettings * xmlSettings){
vector <Vec2> vertices;
if(xmlSettings->tagExists("vertices")){
xmlSettings->pushTag("vertices");
unsigned int v = 0;
while(xmlSettings->tagExists("vertex", v)){
xmlSettings->pushTag("vertex", v);
vertices.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag(); // vertex
v += 1;
}
xmlSettings->popTag(); // vertices
}
vector <Vec2> texCoords;
if(xmlSettings->tagExists("texCoords")){
xmlSettings->pushTag("texCoords");
unsigned int t = 0;
while(xmlSettings->tagExists("texCoord", t)){
xmlSettings->pushTag("texCoord", t);
texCoords.push_back(Vec2(xmlSettings->getValue("x", 0.0f),
xmlSettings->getValue("y", 0.0f)));
xmlSettings->popTag(); // texCoord
t += 1;
}
xmlSettings->popTag(); // texCoords
}
// Create and add a triangle surface
BaseSurface * hexagonSurface =
SurfaceFactory::instance()->createSurface(
SurfaceType::HEXAGON_SURFACE);
hexagonSurface->setVertices(vertices);
hexagonSurface->setTexCoords(texCoords);
return hexagonSurface;
}
} // namespace piMapper
} // namespace ofx