diff --git a/src/Application/Application.cpp b/src/Application/Application.cpp index 072fbe0..88e3048 100644 --- a/src/Application/Application.cpp +++ b/src/Application/Application.cpp @@ -2,94 +2,94 @@ #include "PresentationState.h" namespace ofx { - namespace piMapper { - - Application::Application(ofxPiMapper * opm) { - _ofxPiMapper = opm; - setState(PresentationState::instance()); - ofAddListener(ofEvents().keyPressed, this, &Application::onKeyPressed); - } - - Application::~Application() { - _ofxPiMapper = 0; - setState(0); - ofRemoveListener(ofEvents().keyPressed, this, &Application::onKeyPressed); - } - - ApplicationBaseState * Application::getState() { - return _state; - } - - ofxPiMapper * Application::getOfxPiMapper() { - return _ofxPiMapper; - } - - void Application::draw(){ - _state->draw(this); - } - - // Here we handle application state changes only - void Application::onKeyPressed(ofKeyEventArgs & args) { - - // For now we set the state of the new system and also the old - // before it is completely ported to the state system. - - switch (args.key) { - case '1': - _ofxPiMapper->getCmdManager().exec( - new ofx::piMapper::SetApplicationStateCmd( - this, PresentationState::instance(), - &_ofxPiMapper->getGui(), GuiMode::NONE)); - break; - - case '2': - _ofxPiMapper->getCmdManager().exec( - new ofx::piMapper::SetApplicationStateCmd( - this, TextureMappingState::instance(), - &_ofxPiMapper->getGui(), GuiMode::TEXTURE_MAPPING)); - break; - - case '3': - _ofxPiMapper->getCmdManager().exec( - new ofx::piMapper::SetApplicationStateCmd( - this, ProjectionMappingState::instance(), - &_ofxPiMapper->getGui(), GuiMode::PROJECTION_MAPPING)); - break; - - case '4': - _ofxPiMapper->getCmdManager().exec( - new ofx::piMapper::SetApplicationStateCmd( - this, SourceSelectionState::instance(), - &_ofxPiMapper->getGui(), GuiMode::SOURCE_SELECTION)); - break; - - case 'f': - ofToggleFullscreen(); - break; - - case 'i': - _ofxPiMapper->toggleInfo(); - break; - - case 's': - _ofxPiMapper->getSurfaceManager().saveXmlSettings( - PIMAPPER_USER_SURFACES_XML_FILE); - break; - - case 'z': - _ofxPiMapper->getCmdManager().undo(); - break; - - default: - // All the other keypresses are handled by the application state onKeyPressed - _state->onKeyPressed(this, args); - break; - } - } - - void Application::setState(ApplicationBaseState * st){ - _state = st; - } - - } // namespace piMapper +namespace piMapper { + +Application::Application(ofxPiMapper * opm){ + _ofxPiMapper = opm; + setState(PresentationState::instance()); + ofAddListener(ofEvents().keyPressed, this, &Application::onKeyPressed); +} + +Application::~Application(){ + _ofxPiMapper = 0; + setState(0); + ofRemoveListener(ofEvents().keyPressed, this, &Application::onKeyPressed); +} + +ApplicationBaseState * Application::getState(){ + return _state; +} + +ofxPiMapper * Application::getOfxPiMapper(){ + return _ofxPiMapper; +} + +void Application::draw(){ + _state->draw(this); +} + +// Here we handle application state changes only +void Application::onKeyPressed(ofKeyEventArgs & args){ + + // For now we set the state of the new system and also the old + // before it is completely ported to the state system. + + switch(args.key){ + case '1': + _ofxPiMapper->getCmdManager().exec( + new ofx::piMapper::SetApplicationStateCmd( + this, PresentationState::instance(), + &_ofxPiMapper->getGui(), GuiMode::NONE)); + break; + + case '2': + _ofxPiMapper->getCmdManager().exec( + new ofx::piMapper::SetApplicationStateCmd( + this, TextureMappingState::instance(), + &_ofxPiMapper->getGui(), GuiMode::TEXTURE_MAPPING)); + break; + + case '3': + _ofxPiMapper->getCmdManager().exec( + new ofx::piMapper::SetApplicationStateCmd( + this, ProjectionMappingState::instance(), + &_ofxPiMapper->getGui(), GuiMode::PROJECTION_MAPPING)); + break; + + case '4': + _ofxPiMapper->getCmdManager().exec( + new ofx::piMapper::SetApplicationStateCmd( + this, SourceSelectionState::instance(), + &_ofxPiMapper->getGui(), GuiMode::SOURCE_SELECTION)); + break; + + case 'f': + ofToggleFullscreen(); + break; + + case 'i': + _ofxPiMapper->toggleInfo(); + break; + + case 's': + _ofxPiMapper->getSurfaceManager().saveXmlSettings( + PIMAPPER_USER_SURFACES_XML_FILE); + break; + + case 'z': + _ofxPiMapper->getCmdManager().undo(); + break; + + default: + // All the other keypresses are handled by the application state onKeyPressed + _state->onKeyPressed(this, args); + break; + } +} + +void Application::setState(ApplicationBaseState * st){ + _state = st; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Application/Application.h b/src/Application/Application.h index 820d29f..af40dd3 100644 --- a/src/Application/Application.h +++ b/src/Application/Application.h @@ -19,31 +19,33 @@ class ofxPiMapper; namespace ofx { - namespace piMapper { - - class ApplicationBaseState; - - class Application { - public: - Application(ofxPiMapper * opm); - ~Application(); - - ApplicationBaseState * getState(); - ofxPiMapper * getOfxPiMapper(); // Temporary method. - - void draw(); - void onKeyPressed(ofKeyEventArgs & args); - - protected: - void setState(ApplicationBaseState * st); - - private: - friend class ApplicationBaseState; - friend class SetApplicationStateCmd; - - ApplicationBaseState * _state; - ofxPiMapper * _ofxPiMapper; - }; - - } // namespace piMapper +namespace piMapper { + +class ApplicationBaseState; + +class Application { + + public: + Application(ofxPiMapper * opm); + ~Application(); + + ApplicationBaseState * getState(); + ofxPiMapper * getOfxPiMapper(); // Temporary method. + + void draw(); + void onKeyPressed(ofKeyEventArgs & args); + + protected: + void setState(ApplicationBaseState * st); + + private: + friend class ApplicationBaseState; + friend class SetApplicationStateCmd; + + ApplicationBaseState * _state; + ofxPiMapper * _ofxPiMapper; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Application/ApplicationBaseState.cpp b/src/Application/ApplicationBaseState.cpp index 48f827f..1bc50ef 100644 --- a/src/Application/ApplicationBaseState.cpp +++ b/src/Application/ApplicationBaseState.cpp @@ -2,11 +2,11 @@ #include "PresentationState.h" namespace ofx { - namespace piMapper { - - void ApplicationBaseState::setState(Application * app, ApplicationBaseState * st) { - app->setState(st); - } - - } // namespace piMapper +namespace piMapper { + +void ApplicationBaseState::setState(Application * app, ApplicationBaseState * st){ + app->setState(st); +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Application/ApplicationBaseState.h b/src/Application/ApplicationBaseState.h index fd8a64e..519dc81 100644 --- a/src/Application/ApplicationBaseState.h +++ b/src/Application/ApplicationBaseState.h @@ -4,18 +4,20 @@ #include "ofLog.h" namespace ofx { - namespace piMapper { - - class Application; - - class ApplicationBaseState { - public: - virtual void draw(Application * app){}; - virtual void setState(Application * app, ApplicationBaseState * st); - - // Event handler virtual methods - virtual void onKeyPressed(Application * app, ofKeyEventArgs & args){}; - }; - - } // namespace piMapper +namespace piMapper { + +class Application; + +class ApplicationBaseState { + + public: + virtual void draw(Application * app){} + virtual void setState(Application * app, ApplicationBaseState * st); + + // Event handler virtual methods + virtual void onKeyPressed(Application * app, ofKeyEventArgs & args){} + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Application/PresentationState.cpp b/src/Application/PresentationState.cpp index 5d3f5dd..83979ed 100644 --- a/src/Application/PresentationState.cpp +++ b/src/Application/PresentationState.cpp @@ -1,17 +1,18 @@ #include "PresentationState.h" namespace ofx { - namespace piMapper { - - PresentationState * PresentationState::_instance = 0; - - PresentationState * PresentationState::instance() { - if (_instance == 0) { - _instance = new ofx::piMapper::PresentationState(); - } - return _instance; - } - - void PresentationState::draw(Application * app) {} - } -} \ No newline at end of file +namespace piMapper { + +PresentationState * PresentationState::_instance = 0; + +PresentationState * PresentationState::instance(){ + if(_instance == 0){ + _instance = new ofx::piMapper::PresentationState(); + } + return _instance; +} + +void PresentationState::draw(Application * app){} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Application/PresentationState.h b/src/Application/PresentationState.h index 9f5bd77..22f10de 100644 --- a/src/Application/PresentationState.h +++ b/src/Application/PresentationState.h @@ -6,16 +6,18 @@ #include "ofGraphics.h" namespace ofx { - namespace piMapper { - - class PresentationState : public ApplicationBaseState { - public: - static PresentationState * instance(); - void draw(Application * app); - - private: - static PresentationState * _instance; - }; - - } // namespace piMapper +namespace piMapper { + +class PresentationState : public ApplicationBaseState { + + public: + static PresentationState * instance(); + void draw(Application * app); + + private: + static PresentationState * _instance; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Application/ProjectionMappingState.cpp b/src/Application/ProjectionMappingState.cpp index dfb1dc0..c417878 100644 --- a/src/Application/ProjectionMappingState.cpp +++ b/src/Application/ProjectionMappingState.cpp @@ -1,46 +1,47 @@ #include "ProjectionMappingState.h" namespace ofx { - namespace piMapper { - - ProjectionMappingState * ProjectionMappingState::_instance = 0; - - ProjectionMappingState * ProjectionMappingState::instance() { - if (_instance == 0) { - _instance = new ofx::piMapper::ProjectionMappingState(); - } - return _instance; - } - - void ProjectionMappingState::draw(Application * app) {} - - void ProjectionMappingState::onKeyPressed(Application * app, ofKeyEventArgs & args) { - switch (args.key) { - - case 't': - app->getOfxPiMapper()->getCmdManager().exec( - new AddSurfaceCmd( - app->getOfxPiMapper(), - SurfaceType::TRIANGLE_SURFACE) - ); - break; - - case 'q': - app->getOfxPiMapper()->getCmdManager().exec( - new AddSurfaceCmd( - app->getOfxPiMapper(), - SurfaceType::QUAD_SURFACE) - ); - break; - - case OF_KEY_BACKSPACE: - app->getOfxPiMapper()->getCmdManager().exec( - new RmSurfaceCmd(app->getOfxPiMapper())); - break; - - default: - break; - } - } - } -} \ No newline at end of file +namespace piMapper { + +ProjectionMappingState * ProjectionMappingState::_instance = 0; + +ProjectionMappingState * ProjectionMappingState::instance(){ + if(_instance == 0){ + _instance = new ofx::piMapper::ProjectionMappingState(); + } + return _instance; +} + +void ProjectionMappingState::draw(Application * app){} + +void ProjectionMappingState::onKeyPressed(Application * app, ofKeyEventArgs & args){ + switch(args.key){ + + case 't': + app->getOfxPiMapper()->getCmdManager().exec( + new AddSurfaceCmd( + app->getOfxPiMapper(), + SurfaceType::TRIANGLE_SURFACE) + ); + break; + + case 'q': + app->getOfxPiMapper()->getCmdManager().exec( + new AddSurfaceCmd( + app->getOfxPiMapper(), + SurfaceType::QUAD_SURFACE) + ); + break; + + case OF_KEY_BACKSPACE: + app->getOfxPiMapper()->getCmdManager().exec( + new RmSurfaceCmd(app->getOfxPiMapper())); + break; + + default: + break; + } +} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Application/ProjectionMappingState.h b/src/Application/ProjectionMappingState.h index fd389ad..b406a49 100644 --- a/src/Application/ProjectionMappingState.h +++ b/src/Application/ProjectionMappingState.h @@ -8,17 +8,19 @@ #include "SurfaceType.h" namespace ofx { - namespace piMapper { - - class ProjectionMappingState : public ApplicationBaseState { - public: - static ProjectionMappingState * instance(); - void draw(Application * app); - void onKeyPressed(Application * app, ofKeyEventArgs & args); - - private: - static ProjectionMappingState * _instance; - }; - - } // namespace piMapper +namespace piMapper { + +class ProjectionMappingState : public ApplicationBaseState { + + public: + static ProjectionMappingState * instance(); + void draw(Application * app); + void onKeyPressed(Application * app, ofKeyEventArgs & args); + + private: + static ProjectionMappingState * _instance; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Application/SourceSelectionState.cpp b/src/Application/SourceSelectionState.cpp index e58580d..35ee443 100644 --- a/src/Application/SourceSelectionState.cpp +++ b/src/Application/SourceSelectionState.cpp @@ -1,17 +1,18 @@ #include "SourceSelectionState.h" namespace ofx { - namespace piMapper { - - SourceSelectionState * SourceSelectionState::_instance = 0; - - SourceSelectionState * SourceSelectionState::instance() { - if (_instance == 0) { - _instance = new ofx::piMapper::SourceSelectionState(); - } - return _instance; - } - - void SourceSelectionState::draw(Application * app) {} - } -} \ No newline at end of file +namespace piMapper { + +SourceSelectionState * SourceSelectionState::_instance = 0; + +SourceSelectionState * SourceSelectionState::instance(){ + if(_instance == 0){ + _instance = new ofx::piMapper::SourceSelectionState(); + } + return _instance; +} + +void SourceSelectionState::draw(Application * app){} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Application/SourceSelectionState.h b/src/Application/SourceSelectionState.h index 197280a..e1bfdba 100644 --- a/src/Application/SourceSelectionState.h +++ b/src/Application/SourceSelectionState.h @@ -6,16 +6,18 @@ #include "ofGraphics.h" namespace ofx { - namespace piMapper { - - class SourceSelectionState : public ApplicationBaseState { - public: - static SourceSelectionState * instance(); - void draw(Application * app); - - private: - static SourceSelectionState * _instance; - }; - - } // namespace piMapper +namespace piMapper { + +class SourceSelectionState : public ApplicationBaseState { + + public: + static SourceSelectionState * instance(); + void draw(Application * app); + + private: + static SourceSelectionState * _instance; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Application/TextureMappingState.cpp b/src/Application/TextureMappingState.cpp index a1dc8e8..2b504c1 100644 --- a/src/Application/TextureMappingState.cpp +++ b/src/Application/TextureMappingState.cpp @@ -1,17 +1,18 @@ #include "TextureMappingState.h" namespace ofx { - namespace piMapper { - - TextureMappingState * TextureMappingState::_instance = 0; - - TextureMappingState * TextureMappingState::instance() { - if (_instance == 0) { - _instance = new ofx::piMapper::TextureMappingState(); - } - return _instance; - } - - void TextureMappingState::draw(Application * app) {} - } -} \ No newline at end of file +namespace piMapper { + +TextureMappingState * TextureMappingState::_instance = 0; + +TextureMappingState * TextureMappingState::instance(){ + if(_instance == 0){ + _instance = new ofx::piMapper::TextureMappingState(); + } + return _instance; +} + +void TextureMappingState::draw(Application * app){} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Application/TextureMappingState.h b/src/Application/TextureMappingState.h index 259ad4a..aed5853 100644 --- a/src/Application/TextureMappingState.h +++ b/src/Application/TextureMappingState.h @@ -6,16 +6,18 @@ #include "ofGraphics.h" namespace ofx { - namespace piMapper { - - class TextureMappingState : public ApplicationBaseState { - public: - static TextureMappingState * instance(); - void draw(Application * app); - - private: - static TextureMappingState * _instance; - }; - - } // namespace piMapper +namespace piMapper { + +class TextureMappingState : public ApplicationBaseState { + + public: + static TextureMappingState * instance(); + void draw(Application * app); + + private: + static TextureMappingState * _instance; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/AddSurfaceCmd.cpp b/src/Commands/AddSurfaceCmd.cpp index a806e34..c3eefaf 100644 --- a/src/Commands/AddSurfaceCmd.cpp +++ b/src/Commands/AddSurfaceCmd.cpp @@ -1,61 +1,61 @@ #include "AddSurfaceCmd.h" -namespace ofx{ - namespace piMapper{ - - AddSurfaceCmd::AddSurfaceCmd(ofxPiMapper * app, int surfaceType){ - _app = app; - _surfaceType = surfaceType; - } - - void AddSurfaceCmd::exec(){ - if (_surfaceType == SurfaceType::TRIANGLE_SURFACE) { - addTriangleSurface(); - } else if (_surfaceType == SurfaceType::QUAD_SURFACE) { - addQuadSurface(); - } - } - - void AddSurfaceCmd::undo(){ - ofLogNotice("AddSurfaceCmd", "undo"); - _app->getSurfaceManager().removeSurface(); - } - - void AddSurfaceCmd::addTriangleSurface() { - int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; - - vector vertices; - float margin = 50.0f; - vertices.push_back(ofVec2f((float)ofGetWidth() / 2.0f, margin)); - vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); - vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); - - vector texCoords; - texCoords.push_back(ofVec2f(0.5f, 0.0f)); - texCoords.push_back(ofVec2f(1.0f, 1.0f)); - texCoords.push_back(ofVec2f(0.0f, 1.0f)); - _app->getSurfaceManager().addSurface(surfaceType, vertices, texCoords); - } - - void AddSurfaceCmd::addQuadSurface() { - int surfaceType = ofx::piMapper::SurfaceType::QUAD_SURFACE; - - vector vertices; - float margin = 50.0f; - vertices.push_back(ofVec2f(margin, margin)); - vertices.push_back(ofVec2f((float)ofGetWidth() - margin, margin)); - vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); - vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); - - vector texCoords; - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); - - _app->getSurfaceManager().addSurface(surfaceType, vertices, texCoords); - } - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +AddSurfaceCmd::AddSurfaceCmd(ofxPiMapper * app, int surfaceType){ + _app = app; + _surfaceType = surfaceType; +} + +void AddSurfaceCmd::exec(){ + if(_surfaceType == SurfaceType::TRIANGLE_SURFACE){ + addTriangleSurface(); + }else if(_surfaceType == SurfaceType::QUAD_SURFACE){ + addQuadSurface(); + } +} + +void AddSurfaceCmd::undo(){ + ofLogNotice("AddSurfaceCmd", "undo"); + _app->getSurfaceManager().removeSurface(); +} + +void AddSurfaceCmd::addTriangleSurface(){ + int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; + + vector vertices; + float margin = 50.0f; + vertices.push_back(ofVec2f((float)ofGetWidth() / 2.0f, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); + vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); + + vector texCoords; + texCoords.push_back(ofVec2f(0.5f, 0.0f)); + texCoords.push_back(ofVec2f(1.0f, 1.0f)); + texCoords.push_back(ofVec2f(0.0f, 1.0f)); + _app->getSurfaceManager().addSurface(surfaceType, vertices, texCoords); +} + +void AddSurfaceCmd::addQuadSurface(){ + int surfaceType = ofx::piMapper::SurfaceType::QUAD_SURFACE; + + vector vertices; + float margin = 50.0f; + vertices.push_back(ofVec2f(margin, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); + vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); + + vector texCoords; + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); + + _app->getSurfaceManager().addSurface(surfaceType, vertices, texCoords); +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/AddSurfaceCmd.h b/src/Commands/AddSurfaceCmd.h index 61b27c2..283f654 100644 --- a/src/Commands/AddSurfaceCmd.h +++ b/src/Commands/AddSurfaceCmd.h @@ -7,25 +7,26 @@ class ofxPiMapper; -namespace ofx{ - namespace piMapper{ - - class AddSurfaceCmd : public BaseUndoCmd{ - - public: - AddSurfaceCmd(ofxPiMapper * app, int surfaceType); - void exec(); - void undo(); - - private: - ofxPiMapper * _app; - int _surfaceType; - - // TODO: Should use some kind of factory class here - void addTriangleSurface(); - void addQuadSurface(); - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class AddSurfaceCmd : public BaseUndoCmd { + + public: + AddSurfaceCmd(ofxPiMapper * app, int surfaceType); + void exec(); + void undo(); + + private: + ofxPiMapper * _app; + int _surfaceType; + + // TODO: Should use some kind of factory class here + void addTriangleSurface(); + void addQuadSurface(); + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/BaseCmd.h b/src/Commands/BaseCmd.h index 353b27d..e4aa219 100644 --- a/src/Commands/BaseCmd.h +++ b/src/Commands/BaseCmd.h @@ -9,33 +9,41 @@ #pragma once -namespace ofx{ - namespace piMapper{ - - // Base class for all commands - class BaseCmd{ - public: - virtual ~BaseCmd(){}; - virtual void exec() = 0; - - // By default a command is not undo - virtual bool isUndoable(){return false;} - - protected: - // In order to avoid using this class directly, - // we make the constructor protected. - BaseCmd(){}; - }; - - // Base class for all undoable commands - class BaseUndoCmd : public BaseCmd{ - public: - virtual void undo() = 0; - virtual bool isUndoable(){return true;} - - protected: - BaseUndoCmd(){}; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +// Base class for all commands +class BaseCmd { + + public: + virtual ~BaseCmd(){} + virtual void exec() = 0; + + // By default a command is not undo + virtual bool isUndoable(){ + return false; + } + + protected: + // In order to avoid using this class directly, + // we make the constructor protected. + BaseCmd(){} + +}; + +// Base class for all undoable commands +class BaseUndoCmd : public BaseCmd { + + public: + virtual void undo() = 0; + virtual bool isUndoable(){ + return true; + } + + protected: + BaseUndoCmd(){} + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/CmdManager.cpp b/src/Commands/CmdManager.cpp index 1562b36..67b8c0f 100644 --- a/src/Commands/CmdManager.cpp +++ b/src/Commands/CmdManager.cpp @@ -1,28 +1,28 @@ #include "CmdManager.h" -namespace ofx{ - namespace piMapper{ - - void CmdManager::exec(BaseCmd * cmd){ - cmd->exec(); - if (cmd->isUndoable()){ - cmdStack.push_back(static_cast(cmd)); - } - } - - void CmdManager::undo(){ - ofLogNotice("CmdManager", "undo"); - if (cmdStack.size() > 0){ - BaseUndoCmd * cmd = cmdStack.back(); - cmd->undo(); - - // Delete last command now, change this when implementing redo. - delete cmdStack.back(); - cmdStack.pop_back(); - } else { - ofLogNotice("CmdManager", "Nothing to undo"); - } - } - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +void CmdManager::exec(BaseCmd * cmd){ + cmd->exec(); + if(cmd->isUndoable()){ + cmdStack.push_back(static_cast (cmd)); + } +} + +void CmdManager::undo(){ + ofLogNotice("CmdManager", "undo"); + if(cmdStack.size() > 0){ + BaseUndoCmd * cmd = cmdStack.back(); + cmd->undo(); + + // Delete last command now, change this when implementing redo. + delete cmdStack.back(); + cmdStack.pop_back(); + }else{ + ofLogNotice("CmdManager", "Nothing to undo"); + } +} + +} // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/Commands/CmdManager.h b/src/Commands/CmdManager.h index 6c698a5..8cfcb09 100644 --- a/src/Commands/CmdManager.h +++ b/src/Commands/CmdManager.h @@ -4,17 +4,19 @@ #include "BaseCmd.h" #include "ofLog.h" -namespace ofx{ - namespace piMapper{ - - class CmdManager{ - public: - void exec(BaseCmd * cmd); - void undo(); - - private: - std::vector cmdStack; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class CmdManager { + + public: + void exec(BaseCmd * cmd); + void undo(); + + private: + std::vector cmdStack; + +}; + +} // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/Commands/MvAllTexCoordsCmd.cpp b/src/Commands/MvAllTexCoordsCmd.cpp index 1b29e06..df61672 100644 --- a/src/Commands/MvAllTexCoordsCmd.cpp +++ b/src/Commands/MvAllTexCoordsCmd.cpp @@ -1,27 +1,27 @@ #include "MvAllTexCoordsCmd.h" -namespace ofx{ - namespace piMapper{ - - MvAllTexCoordsCmd::MvAllTexCoordsCmd(BaseSurface * surface, TextureEditor * texEditor){ - _surface = surface; - _texEditor = texEditor; - } +namespace ofx { +namespace piMapper { - void MvAllTexCoordsCmd::exec(){ - ofLogNotice("MvAllTexCoordsCmd", "exec"); - _texCoords = _surface->getTexCoords(); - } - - void MvAllTexCoordsCmd::undo(){ - ofLogNotice("MvAllTexCoordsCmd", "undo"); - ofVec2f dist = _texCoords[0] - _surface->getTexCoords()[0]; - dist.x = _surface->getSource()->getTexture()->getWidth() * dist.x; - dist.y = _surface->getSource()->getTexture()->getHeight() * dist.y; - _texEditor->moveTexCoords(dist); - _surface = 0; - } - - } // namespace piMapper +MvAllTexCoordsCmd::MvAllTexCoordsCmd(BaseSurface * surface, TextureEditor * texEditor){ + _surface = surface; + _texEditor = texEditor; +} + +void MvAllTexCoordsCmd::exec(){ + ofLogNotice("MvAllTexCoordsCmd", "exec"); + _texCoords = _surface->getTexCoords(); +} + +void MvAllTexCoordsCmd::undo(){ + ofLogNotice("MvAllTexCoordsCmd", "undo"); + ofVec2f dist = _texCoords[0] - _surface->getTexCoords()[0]; + dist.x = _surface->getSource()->getTexture()->getWidth() * dist.x; + dist.y = _surface->getSource()->getTexture()->getHeight() * dist.y; + _texEditor->moveTexCoords(dist); + _surface = 0; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/MvAllTexCoordsCmd.h b/src/Commands/MvAllTexCoordsCmd.h index 578c29d..e22d009 100644 --- a/src/Commands/MvAllTexCoordsCmd.h +++ b/src/Commands/MvAllTexCoordsCmd.h @@ -8,22 +8,23 @@ #include "BaseSurface.h" #include "TextureEditor.h" -namespace ofx{ - namespace piMapper{ - - class MvAllTexCoordsCmd : public BaseUndoCmd{ - - public: - MvAllTexCoordsCmd(BaseSurface * surface, TextureEditor * texEditor); - void exec(); - void undo(); - - private: - vector _texCoords; - BaseSurface * _surface; - TextureEditor * _texEditor; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class MvAllTexCoordsCmd : public BaseUndoCmd { + + public: + MvAllTexCoordsCmd(BaseSurface * surface, TextureEditor * texEditor); + void exec(); + void undo(); + + private: + vector _texCoords; + BaseSurface * _surface; + TextureEditor * _texEditor; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/MvSurfaceCmd.cpp b/src/Commands/MvSurfaceCmd.cpp index 366edda..91456fc 100644 --- a/src/Commands/MvSurfaceCmd.cpp +++ b/src/Commands/MvSurfaceCmd.cpp @@ -1,30 +1,29 @@ #include "MvSurfaceCmd.h" -namespace ofx{ - namespace piMapper{ - - MvSurfaceCmd::MvSurfaceCmd( - BaseSurface * surface, - ProjectionEditor * projectionEditor){ - - _surface = surface; - _projectionEditor = projectionEditor; - } +namespace ofx { +namespace piMapper { - void MvSurfaceCmd::exec(){ - ofLogNotice("MvSurfaceCmd", "exec"); - _previousVertices = _surface->getVertices(); - _surface->setMoved(false); - } - - void MvSurfaceCmd::undo(){ - ofLogNotice("MvSurfaceCmd", "undo"); - _surface->moveBy(_previousVertices[0] - _surface->getVertices()[0]); - _projectionEditor->updateJoints(); - _previousVertices.clear(); - _surface = 0; - } - - } // namespace piMapper +MvSurfaceCmd::MvSurfaceCmd(BaseSurface * surface, + ProjectionEditor * projectionEditor){ + + _surface = surface; + _projectionEditor = projectionEditor; +} + +void MvSurfaceCmd::exec(){ + ofLogNotice("MvSurfaceCmd", "exec"); + _previousVertices = _surface->getVertices(); + _surface->setMoved(false); +} + +void MvSurfaceCmd::undo(){ + ofLogNotice("MvSurfaceCmd", "undo"); + _surface->moveBy(_previousVertices[0] - _surface->getVertices()[0]); + _projectionEditor->updateJoints(); + _previousVertices.clear(); + _surface = 0; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/MvSurfaceCmd.h b/src/Commands/MvSurfaceCmd.h index 0c4d72a..c5bb388 100644 --- a/src/Commands/MvSurfaceCmd.h +++ b/src/Commands/MvSurfaceCmd.h @@ -8,24 +8,24 @@ #include "BaseSurface.h" #include "ProjectionEditor.h" -namespace ofx{ - namespace piMapper{ - - class MvSurfaceCmd : public BaseUndoCmd{ - - public: - MvSurfaceCmd( - BaseSurface * surface, - ProjectionEditor * projectionEditor); - void exec(); - void undo(); - - private: - BaseSurface * _surface; - ProjectionEditor * _projectionEditor; - vector _previousVertices; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class MvSurfaceCmd : public BaseUndoCmd { + + public: + MvSurfaceCmd(BaseSurface * surface, + ProjectionEditor * projectionEditor); + void exec(); + void undo(); + + private: + BaseSurface * _surface; + ProjectionEditor * _projectionEditor; + vector _previousVertices; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/MvSurfaceVertCmd.cpp b/src/Commands/MvSurfaceVertCmd.cpp index 74abe6d..5991cce 100644 --- a/src/Commands/MvSurfaceVertCmd.cpp +++ b/src/Commands/MvSurfaceVertCmd.cpp @@ -1,31 +1,30 @@ #include "MvSurfaceVertCmd.h" -namespace ofx{ - namespace piMapper{ - - MvSurfaceVertCmd::MvSurfaceVertCmd( - int vertIndex, - BaseSurface * surface, - ProjectionEditor * projectionEditor){ - - _vertIndex = vertIndex; - _surface = surface; - _projectionEditor = projectionEditor; - } +namespace ofx { +namespace piMapper { - void MvSurfaceVertCmd::exec(){ - ofLogNotice("MvSurfaceVertCommand", "exec"); - _prevVertPos = _surface->getVertices()[_vertIndex]; - } - - void MvSurfaceVertCmd::undo(){ - ofLogNotice("MvSurfaceVertCommand", "undo"); - _surface->setVertex(_vertIndex, _prevVertPos); - _projectionEditor->updateJoints(); - _projectionEditor = 0; - _surface = 0; - } - - } // namespace piMapper +MvSurfaceVertCmd::MvSurfaceVertCmd(int vertIndex, + BaseSurface * surface, + ProjectionEditor * projectionEditor){ + + _vertIndex = vertIndex; + _surface = surface; + _projectionEditor = projectionEditor; +} + +void MvSurfaceVertCmd::exec(){ + ofLogNotice("MvSurfaceVertCommand", "exec"); + _prevVertPos = _surface->getVertices()[_vertIndex]; +} + +void MvSurfaceVertCmd::undo(){ + ofLogNotice("MvSurfaceVertCommand", "undo"); + _surface->setVertex(_vertIndex, _prevVertPos); + _projectionEditor->updateJoints(); + _projectionEditor = 0; + _surface = 0; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/MvSurfaceVertCmd.h b/src/Commands/MvSurfaceVertCmd.h index f2458dd..f517fca 100644 --- a/src/Commands/MvSurfaceVertCmd.h +++ b/src/Commands/MvSurfaceVertCmd.h @@ -9,26 +9,26 @@ #include "ProjectionEditor.h" #include "BaseJoint.h" -namespace ofx{ - namespace piMapper{ - - class MvSurfaceVertCmd : public BaseUndoCmd{ - - public: - MvSurfaceVertCmd( - int vertIndex, - BaseSurface * surface, - ProjectionEditor * projectionEditor); - void exec(); - void undo(); - - private: - int _vertIndex; - ofVec2f _prevVertPos; - BaseSurface * _surface; - ProjectionEditor * _projectionEditor; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class MvSurfaceVertCmd : public BaseUndoCmd { + + public: + MvSurfaceVertCmd(int vertIndex, + BaseSurface * surface, + ProjectionEditor * projectionEditor); + void exec(); + void undo(); + + private: + int _vertIndex; + ofVec2f _prevVertPos; + BaseSurface * _surface; + ProjectionEditor * _projectionEditor; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/MvTexCoordCmd.cpp b/src/Commands/MvTexCoordCmd.cpp index be364a3..aa075b8 100644 --- a/src/Commands/MvTexCoordCmd.cpp +++ b/src/Commands/MvTexCoordCmd.cpp @@ -1,26 +1,26 @@ #include "MvTexCoordCmd.h" -namespace ofx{ - namespace piMapper{ - - MvTexCoordCmd::MvTexCoordCmd(int jointIndex, TextureEditor * texEditor){ - _jointIndex = jointIndex; - _texEditor = texEditor; - } +namespace ofx { +namespace piMapper { - void MvTexCoordCmd::exec(){ - ofLogNotice("MvTexCoordCmd", "exec"); - _jointPosition = _texEditor->getJoints()[_jointIndex]->position; - } - - void MvTexCoordCmd::undo(){ - ofLogNotice("MvTexCoordCmd", "undo"); - _texEditor->unselectAllJoints(); - _texEditor->getJoints()[_jointIndex]->select(); - _texEditor->getJoints()[_jointIndex]->position = _jointPosition; - _texEditor = 0; - } - - } // namespace piMapper +MvTexCoordCmd::MvTexCoordCmd(int jointIndex, TextureEditor * texEditor){ + _jointIndex = jointIndex; + _texEditor = texEditor; +} + +void MvTexCoordCmd::exec(){ + ofLogNotice("MvTexCoordCmd", "exec"); + _jointPosition = _texEditor->getJoints()[_jointIndex]->position; +} + +void MvTexCoordCmd::undo(){ + ofLogNotice("MvTexCoordCmd", "undo"); + _texEditor->unselectAllJoints(); + _texEditor->getJoints()[_jointIndex]->select(); + _texEditor->getJoints()[_jointIndex]->position = _jointPosition; + _texEditor = 0; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/MvTexCoordCmd.h b/src/Commands/MvTexCoordCmd.h index 2b24372..a73e532 100644 --- a/src/Commands/MvTexCoordCmd.h +++ b/src/Commands/MvTexCoordCmd.h @@ -8,22 +8,23 @@ #include "CircleJoint.h" #include "TextureEditor.h" -namespace ofx{ - namespace piMapper{ - - class MvTexCoordCmd : public BaseUndoCmd{ - - public: - MvTexCoordCmd(int jointIndex, TextureEditor * texEditor); - void exec(); - void undo(); - - private: - ofVec2f _jointPosition; - int _jointIndex; - TextureEditor * _texEditor; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class MvTexCoordCmd : public BaseUndoCmd { + + public: + MvTexCoordCmd(int jointIndex, TextureEditor * texEditor); + void exec(); + void undo(); + + private: + ofVec2f _jointPosition; + int _jointIndex; + TextureEditor * _texEditor; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/RmSurfaceCmd.cpp b/src/Commands/RmSurfaceCmd.cpp index 357e618..173f652 100644 --- a/src/Commands/RmSurfaceCmd.cpp +++ b/src/Commands/RmSurfaceCmd.cpp @@ -1,30 +1,30 @@ #include "RmSurfaceCmd.h" -namespace ofx{ - namespace piMapper{ - - RmSurfaceCmd::RmSurfaceCmd(ofxPiMapper * app){ - _app = app; - _surface = 0; - } +namespace ofx { +namespace piMapper { - void RmSurfaceCmd::exec(){ - // Store the surface, this implies that the surfaceManager's - // removeSelectedSurface does not destroy the surface. - _surface = _app->surfaceManager.getSelectedSurface(); - _app->surfaceManager.removeSelectedSurface(); - } - - void RmSurfaceCmd::undo(){ - ofLogNotice("RmSurfaceCmd", "undo"); - if (_surface == 0) { - ofLogError("RmSurfaceCmd", "No surface stored"); - } - _app->surfaceManager.addSurface(_surface); - _app->surfaceManager.selectSurface(_surface); - _surface = 0; - } - - } // namespace piMapper +RmSurfaceCmd::RmSurfaceCmd(ofxPiMapper * app){ + _app = app; + _surface = 0; +} + +void RmSurfaceCmd::exec(){ + // Store the surface, this implies that the surfaceManager's + // removeSelectedSurface does not destroy the surface. + _surface = _app->surfaceManager.getSelectedSurface(); + _app->surfaceManager.removeSelectedSurface(); +} + +void RmSurfaceCmd::undo(){ + ofLogNotice("RmSurfaceCmd", "undo"); + if(_surface == 0){ + ofLogError("RmSurfaceCmd", "No surface stored"); + } + _app->surfaceManager.addSurface(_surface); + _app->surfaceManager.selectSurface(_surface); + _surface = 0; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/RmSurfaceCmd.h b/src/Commands/RmSurfaceCmd.h index 7fd746d..862cb4e 100644 --- a/src/Commands/RmSurfaceCmd.h +++ b/src/Commands/RmSurfaceCmd.h @@ -10,21 +10,22 @@ class ofxPiMapper; -namespace ofx{ - namespace piMapper{ - - class RmSurfaceCmd : public BaseUndoCmd{ - - public: - RmSurfaceCmd(ofxPiMapper * app); - void exec(); - void undo(); - - private: - ofxPiMapper * _app; - BaseSurface * _surface; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class RmSurfaceCmd : public BaseUndoCmd { + + public: + RmSurfaceCmd(ofxPiMapper * app); + void exec(); + void undo(); + + private: + ofxPiMapper * _app; + BaseSurface * _surface; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/SelSurfaceCmd.cpp b/src/Commands/SelSurfaceCmd.cpp index 91d8afc..89f4db2 100644 --- a/src/Commands/SelSurfaceCmd.cpp +++ b/src/Commands/SelSurfaceCmd.cpp @@ -1,34 +1,33 @@ #include "SelSurfaceCmd.h" -namespace ofx{ - namespace piMapper{ - - SelSurfaceCmd::SelSurfaceCmd( - SurfaceManager * surfaceManager, - BaseSurface * surfaceToSelect, - ProjectionEditor * projectionEditor){ - - _surfaceManager = surfaceManager; - _surfaceToSelect = surfaceToSelect; - _projectionEditor = projectionEditor; - } +namespace ofx { +namespace piMapper { - void SelSurfaceCmd::exec(){ - _prevSelectedSurface = _surfaceManager->getSelectedSurface(); - _projectionEditor->clearJoints(); - _surfaceManager->selectSurface(_surfaceToSelect); - _projectionEditor->createJoints(); - } - - void SelSurfaceCmd::undo(){ - ofLogNotice("SelSurfaceCmd", "undo"); - _projectionEditor->clearJoints(); - _surfaceManager->selectSurface(_prevSelectedSurface); - _projectionEditor->createJoints(); - _surfaceToSelect = 0; - _prevSelectedSurface = 0; - } - - } // namespace piMapper +SelSurfaceCmd::SelSurfaceCmd(SurfaceManager * surfaceManager, + BaseSurface * surfaceToSelect, + ProjectionEditor * projectionEditor){ + + _surfaceManager = surfaceManager; + _surfaceToSelect = surfaceToSelect; + _projectionEditor = projectionEditor; +} + +void SelSurfaceCmd::exec(){ + _prevSelectedSurface = _surfaceManager->getSelectedSurface(); + _projectionEditor->clearJoints(); + _surfaceManager->selectSurface(_surfaceToSelect); + _projectionEditor->createJoints(); +} + +void SelSurfaceCmd::undo(){ + ofLogNotice("SelSurfaceCmd", "undo"); + _projectionEditor->clearJoints(); + _surfaceManager->selectSurface(_prevSelectedSurface); + _projectionEditor->createJoints(); + _surfaceToSelect = 0; + _prevSelectedSurface = 0; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/SelSurfaceCmd.h b/src/Commands/SelSurfaceCmd.h index 94f0798..cd8e1a7 100644 --- a/src/Commands/SelSurfaceCmd.h +++ b/src/Commands/SelSurfaceCmd.h @@ -9,26 +9,26 @@ #include "SurfaceManager.h" #include "ProjectionEditor.h" -namespace ofx{ - namespace piMapper{ - - class SelSurfaceCmd : public BaseUndoCmd{ - - public: - SelSurfaceCmd( - SurfaceManager * surfaceManager, - BaseSurface * surfaceToSelect, - ProjectionEditor * projectionEditor); - void exec(); - void undo(); - - private: - BaseSurface * _surfaceToSelect; - SurfaceManager * _surfaceManager; - BaseSurface * _prevSelectedSurface; - ProjectionEditor * _projectionEditor; - }; - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class SelSurfaceCmd : public BaseUndoCmd { + + public: + SelSurfaceCmd(SurfaceManager * surfaceManager, + BaseSurface * surfaceToSelect, + ProjectionEditor * projectionEditor); + void exec(); + void undo(); + + private: + BaseSurface * _surfaceToSelect; + SurfaceManager * _surfaceManager; + BaseSurface * _prevSelectedSurface; + ProjectionEditor * _projectionEditor; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/SetApplicationStateCmd.cpp b/src/Commands/SetApplicationStateCmd.cpp index bb55d0a..e691fec 100644 --- a/src/Commands/SetApplicationStateCmd.cpp +++ b/src/Commands/SetApplicationStateCmd.cpp @@ -1,42 +1,40 @@ #include "SetApplicationStateCmd.h" namespace ofx { - namespace piMapper { - - SetApplicationStateCmd::SetApplicationStateCmd( - Application * app, - ApplicationBaseState * st, - - SurfaceManagerGui * gui, - int mode) { - - _application = app; - _prevApplicationState = 0; - _applicationState = st; - - // TODO: To be removed - _gui = gui; - _prevGuiMode = -1; - _mode = mode; - } - - void SetApplicationStateCmd::exec() { - _prevApplicationState = _application->getState(); - _application->setState(_applicationState); - - // TODO: To be removed. - _prevGuiMode = _gui->getMode(); - _gui->setMode(_mode); - } - - void SetApplicationStateCmd::undo() { - ofLogNotice("SetApplicationStateCmd", "undo"); - _application->setState(_prevApplicationState); - - // TODO: To be removed. - _gui->setMode(_prevGuiMode); - } - - } // namespace piMapper +namespace piMapper { + +SetApplicationStateCmd::SetApplicationStateCmd(Application * app, + ApplicationBaseState * st, + SurfaceManagerGui * gui, + int mode){ + + _application = app; + _prevApplicationState = 0; + _applicationState = st; + + // TODO: To be removed + _gui = gui; + _prevGuiMode = -1; + _mode = mode; +} + +void SetApplicationStateCmd::exec(){ + _prevApplicationState = _application->getState(); + _application->setState(_applicationState); + + // TODO: To be removed. + _prevGuiMode = _gui->getMode(); + _gui->setMode(_mode); +} + +void SetApplicationStateCmd::undo(){ + ofLogNotice("SetApplicationStateCmd", "undo"); + _application->setState(_prevApplicationState); + + // TODO: To be removed. + _gui->setMode(_prevGuiMode); +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/SetApplicationStateCmd.h b/src/Commands/SetApplicationStateCmd.h index 11ca7bb..bd497cf 100644 --- a/src/Commands/SetApplicationStateCmd.h +++ b/src/Commands/SetApplicationStateCmd.h @@ -4,34 +4,34 @@ #include "Application.h" namespace ofx { - namespace piMapper { - - class Application; - class ApplicationBaseState; - - class SetApplicationStateCmd : public BaseUndoCmd { - - public: - SetApplicationStateCmd( - Application * app, - ApplicationBaseState * st, - SurfaceManagerGui * gui, - int mode); - - void exec(); - void undo(); - - private: - Application * _application; - ApplicationBaseState * _prevApplicationState; - ApplicationBaseState * _applicationState; - - // TODO: Remove these after porting to app state system is done - SurfaceManagerGui * _gui; - int _prevGuiMode; - int _mode; - }; - - } // namespace piMapper +namespace piMapper { + +class Application; +class ApplicationBaseState; + +class SetApplicationStateCmd : public BaseUndoCmd { + + public: + SetApplicationStateCmd(Application * app, + ApplicationBaseState * st, + SurfaceManagerGui * gui, + int mode); + + void exec(); + void undo(); + + private: + Application * _application; + ApplicationBaseState * _prevApplicationState; + ApplicationBaseState * _applicationState; + + // TODO: Remove these after porting to app state system is done + SurfaceManagerGui * _gui; + int _prevGuiMode; + int _mode; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/SetSourceCmd.cpp b/src/Commands/SetSourceCmd.cpp index 7694e20..3d02a31 100644 --- a/src/Commands/SetSourceCmd.cpp +++ b/src/Commands/SetSourceCmd.cpp @@ -1,57 +1,57 @@ #include "SetSourceCmd.h" -namespace ofx{ - namespace piMapper{ - - SetSourceCmd::SetSourceCmd(int sourceType, - string sourceId, - BaseSurface * surface, - SourcesEditor * sourcesEditor){ - - _sourceType = sourceType; - _sourceId = sourceId; - _surface = surface; - _sourcesEditor = sourcesEditor; - } - - void SetSourceCmd::exec(){ - ofLogNotice("SetSourceCmd", "exec"); - - _oldSourceType = _surface->getSource()->getType(); - if (_surface->getSource()->isLoadable()) { - _oldSourceId = _surface->getSource()->getPath(); - } else { - _oldSourceId = _surface->getSource()->getName(); - } - - if (_sourceType == SourceType::SOURCE_TYPE_IMAGE) { - _sourcesEditor->setImageSource(_sourceId); - } else if (_sourceType == SourceType::SOURCE_TYPE_VIDEO) { - _sourcesEditor->setVideoSource(_sourceId); - } else if (_sourceType == SourceType::SOURCE_TYPE_FBO) { - _sourcesEditor->setFboSource(_sourceId); - } else if (_sourceType == SourceType::SOURCE_TYPE_NONE) { - _sourcesEditor->clearSource(); - } - } - - void SetSourceCmd::undo(){ - ofLogNotice("SetSourceCmd", "undo"); - - if (_oldSourceType == SourceType::SOURCE_TYPE_IMAGE) { - _sourcesEditor->setImageSource(_oldSourceId); - } else if (_oldSourceType == SourceType::SOURCE_TYPE_VIDEO) { - _sourcesEditor->setVideoSource(_oldSourceId); - } else if (_oldSourceType == SourceType::SOURCE_TYPE_FBO) { - _sourcesEditor->setFboSource(_oldSourceId); - } else if (_oldSourceType == SourceType::SOURCE_TYPE_NONE) { - _sourcesEditor->clearSource(); - } - - _surface = 0; - _sourcesEditor = 0; - } - - } // namespace piMapper +namespace ofx { +namespace piMapper { + +SetSourceCmd::SetSourceCmd(int sourceType, + string sourceId, + BaseSurface * surface, + SourcesEditor * sourcesEditor){ + + _sourceType = sourceType; + _sourceId = sourceId; + _surface = surface; + _sourcesEditor = sourcesEditor; +} + +void SetSourceCmd::exec(){ + ofLogNotice("SetSourceCmd", "exec"); + + _oldSourceType = _surface->getSource()->getType(); + if(_surface->getSource()->isLoadable()){ + _oldSourceId = _surface->getSource()->getPath(); + }else{ + _oldSourceId = _surface->getSource()->getName(); + } + + if(_sourceType == SourceType::SOURCE_TYPE_IMAGE){ + _sourcesEditor->setImageSource(_sourceId); + }else if(_sourceType == SourceType::SOURCE_TYPE_VIDEO){ + _sourcesEditor->setVideoSource(_sourceId); + }else if(_sourceType == SourceType::SOURCE_TYPE_FBO){ + _sourcesEditor->setFboSource(_sourceId); + }else if(_sourceType == SourceType::SOURCE_TYPE_NONE){ + _sourcesEditor->clearSource(); + } +} + +void SetSourceCmd::undo(){ + ofLogNotice("SetSourceCmd", "undo"); + + if(_oldSourceType == SourceType::SOURCE_TYPE_IMAGE){ + _sourcesEditor->setImageSource(_oldSourceId); + }else if(_oldSourceType == SourceType::SOURCE_TYPE_VIDEO){ + _sourcesEditor->setVideoSource(_oldSourceId); + }else if(_oldSourceType == SourceType::SOURCE_TYPE_FBO){ + _sourcesEditor->setFboSource(_oldSourceId); + }else if(_oldSourceType == SourceType::SOURCE_TYPE_NONE){ + _sourcesEditor->clearSource(); + } + + _surface = 0; + _sourcesEditor = 0; +} + +} // namespace piMapper } // namespace ofx diff --git a/src/Commands/SetSourceCmd.h b/src/Commands/SetSourceCmd.h index 303fc22..9e0ca33 100644 --- a/src/Commands/SetSourceCmd.h +++ b/src/Commands/SetSourceCmd.h @@ -8,33 +8,32 @@ #include "BaseSurface.h" #include "SourcesEditor.h" +namespace ofx { +namespace piMapper { +class SourcesEditor; -namespace ofx{ - namespace piMapper{ - - class SourcesEditor; - - class SetSourceCmd : public BaseUndoCmd{ - - public: - SetSourceCmd(int sourceType, - string sourceId, - BaseSurface * surface, - SourcesEditor * sourcesEditor); - void exec(); - void undo(); - - private: - int _sourceType; - string _sourceId; - BaseSurface * _surface; - SourcesEditor * _sourcesEditor; - - int _oldSourceType; - string _oldSourceId; - }; - - } // namespace piMapper +class SetSourceCmd : public BaseUndoCmd { + + public: + SetSourceCmd(int sourceType, + string sourceId, + BaseSurface * surface, + SourcesEditor * sourcesEditor); + void exec(); + void undo(); + + private: + int _sourceType; + string _sourceId; + BaseSurface * _surface; + SourcesEditor * _sourcesEditor; + + int _oldSourceType; + string _oldSourceId; + +}; + +} // namespace piMapper } // namespace ofx diff --git a/src/MediaServer/DirectoryWatcher.cpp b/src/MediaServer/DirectoryWatcher.cpp index e55fa79..0a45fa0 100644 --- a/src/MediaServer/DirectoryWatcher.cpp +++ b/src/MediaServer/DirectoryWatcher.cpp @@ -9,38 +9,39 @@ #include "DirectoryWatcher.h" namespace ofx { - namespace piMapper { - DirectoryWatcher::DirectoryWatcher(std::string path, int watcherMediaType) { - mediaType = watcherMediaType; - // Decide what filter we need depending on media type - if (mediaType == SourceType::SOURCE_TYPE_VIDEO) { - filter = new VideoPathFilter(); - } else if (mediaType == SourceType::SOURCE_TYPE_IMAGE) { - filter = new ImagePathFilter(); - } else { - ofLogFatalError("DirectoryWatcher::DirectoryWatcher", "Unkonwn media type"); - std::exit(EXIT_FAILURE); - } - dirWatcher.registerAllEvents(this); - // For some reason the filters are not working, - // we leave just the path here and do the filter logic in the listeners - dirWatcher.addPath(path); - // Initial directory listing. Fill the file paths vector. - IO::DirectoryUtils::list(path, filePaths, true, filter); - } - - DirectoryWatcher::~DirectoryWatcher() { - delete filter; - filter = NULL; - } - - std::vector& DirectoryWatcher::getFilePaths() { - return filePaths; - } - - int DirectoryWatcher::getMediaType() { - return mediaType; - } - - } // namespace piMapper +namespace piMapper { + +DirectoryWatcher::DirectoryWatcher(std::string path, int watcherMediaType){ + mediaType = watcherMediaType; + // Decide what filter we need depending on media type + if(mediaType == SourceType::SOURCE_TYPE_VIDEO){ + filter = new VideoPathFilter(); + }else if(mediaType == SourceType::SOURCE_TYPE_IMAGE){ + filter = new ImagePathFilter(); + }else{ + ofLogFatalError("DirectoryWatcher::DirectoryWatcher", "Unkonwn media type"); + std::exit(EXIT_FAILURE); + } + dirWatcher.registerAllEvents(this); + // For some reason the filters are not working, + // we leave just the path here and do the filter logic in the listeners + dirWatcher.addPath(path); + // Initial directory listing. Fill the file paths vector. + IO::DirectoryUtils::list(path, filePaths, true, filter); +} + +DirectoryWatcher::~DirectoryWatcher(){ + delete filter; + filter = NULL; +} + +std::vector & DirectoryWatcher::getFilePaths(){ + return filePaths; +} + +int DirectoryWatcher::getMediaType(){ + return mediaType; +} + +} // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/MediaServer/DirectoryWatcher.h b/src/MediaServer/DirectoryWatcher.h index 40f0bf4..17c6c5f 100644 --- a/src/MediaServer/DirectoryWatcher.h +++ b/src/MediaServer/DirectoryWatcher.h @@ -15,130 +15,126 @@ namespace ofx { namespace piMapper { - class BasePathFilter : public ofx::IO::AbstractPathFilter { - public: - BasePathFilter() {}; - virtual ~BasePathFilter() {}; - virtual bool accept(const Poco::Path& path) const {}; - }; - +class BasePathFilter : public ofx::IO::AbstractPathFilter { + public: + BasePathFilter(){} + virtual ~BasePathFilter(){} + virtual bool accept(const Poco::Path & path) const {} +}; + class VideoPathFilter : public BasePathFilter { - public: - VideoPathFilter() {}; - virtual ~VideoPathFilter() {}; - - bool accept(const Poco::Path& path) const { - return !Poco::File(path).isHidden() && - (ofIsStringInString(path.toString(), ".mp4") || - ofIsStringInString(path.toString(), ".h264")|| - ofIsStringInString(path.toString(), ".mov") || - ofIsStringInString(path.toString(), ".avi") || - ofIsStringInString(path.toString(), ".mpeg")); - } + public: + VideoPathFilter(){} + virtual ~VideoPathFilter(){} + + bool accept(const Poco::Path & path) const { + return !Poco::File(path).isHidden() && + (ofIsStringInString(path.toString(), ".mp4") || + ofIsStringInString(path.toString(), ".h264") || + ofIsStringInString(path.toString(), ".mov") || + ofIsStringInString(path.toString(), ".avi") || + ofIsStringInString(path.toString(), ".mpeg")); + } }; class ImagePathFilter : public BasePathFilter { - public: - ImagePathFilter() {}; - virtual ~ImagePathFilter() {}; - - bool accept(const Poco::Path& path) const { - return !Poco::File(path).isHidden() && - (ofIsStringInString(path.toString(), ".png") || - ofIsStringInString(path.toString(), ".jpg") || - ofIsStringInString(path.toString(), ".jpeg")); - } + public: + ImagePathFilter(){} + virtual ~ImagePathFilter(){} + + bool accept(const Poco::Path & path) const { + return !Poco::File(path).isHidden() && + (ofIsStringInString(path.toString(), ".png") || + ofIsStringInString(path.toString(), ".jpg") || + ofIsStringInString(path.toString(), ".jpeg")); + } }; class DirectoryWatcher { - public: - DirectoryWatcher(std::string path, int watcherMediaType); - ~DirectoryWatcher(); - - // TODO make useful stuff with onDirectoryWatcher* - void onDirectoryWatcherItemAdded( - const ofx::IO::DirectoryWatcherManager::DirectoryEvent& evt) { - string path = evt.item.path(); - Poco::Path pocoPath = Poco::Path(path); - if (!filter->accept(pocoPath)) { - return; - } - filePaths.push_back(path); - ofNotifyEvent(onItemAdded, path, this); - } - - void onDirectoryWatcherItemRemoved( - const ofx::IO::DirectoryWatcherManager::DirectoryEvent& evt) { - string path = evt.item.path(); - Poco::Path pocoPath = Poco::Path(path); - if (!filter->accept(pocoPath)) { - return; - } - // Remove path from vector - for (int i = 0; i < filePaths.size(); i++) { - if (path == filePaths[i]) { - filePaths.erase(filePaths.begin() + i); - break; - } - } - ofNotifyEvent(onItemRemoved, path, this); - } - - void onDirectoryWatcherItemModified( - const ofx::IO::DirectoryWatcherManager::DirectoryEvent& evt) { - string path = evt.item.path(); - Poco::Path pocoPath = Poco::Path(path); - if (!filter->accept(pocoPath)) { - return; - } - ofNotifyEvent(onItemModified, path, this); - } - - void onDirectoryWatcherItemMovedFrom( - const ofx::IO::DirectoryWatcherManager::DirectoryEvent& evt) { - string path = evt.item.path(); - Poco::Path pocoPath = Poco::Path(path); - if (!filter->accept(pocoPath)) { - return; - } - ofLogNotice("ofApp::onDirectoryWatcherItemMovedFrom") - << "Moved From: " << path; - ofNotifyEvent(onItemMovedFrom, path, this); - } - - void onDirectoryWatcherItemMovedTo( - const ofx::IO::DirectoryWatcherManager::DirectoryEvent& evt) { - string path = evt.item.path(); - Poco::Path pocoPath = Poco::Path(path); - if (!filter->accept(pocoPath)) { - return; - } - ofLogNotice("ofApp::onDirectoryWatcherItemMovedTo") - << "Moved To: " << path; - ofNotifyEvent(onItemMovedTo, path, this); - } - - void onDirectoryWatcherError(const Poco::Exception& exc) { - ofLogError("ofApp::onDirectoryWatcherError") - << "Error: " << exc.displayText(); - } - - // Getters - std::vector& getFilePaths(); - int getMediaType(); - - // Custom events - ofEvent onItemAdded; - ofEvent onItemRemoved; - ofEvent onItemModified; - ofEvent onItemMovedFrom; - ofEvent onItemMovedTo; - - private: - ofx::IO::DirectoryWatcherManager dirWatcher; - BasePathFilter* filter; - std::vector filePaths; - int mediaType; + public: + DirectoryWatcher(std::string path, int watcherMediaType); + ~DirectoryWatcher(); + + // TODO make useful stuff with onDirectoryWatcher* + void onDirectoryWatcherItemAdded(const ofx::IO::DirectoryWatcherManager::DirectoryEvent & evt){ + string path = evt.item.path(); + Poco::Path pocoPath = Poco::Path(path); + if(!filter->accept(pocoPath)){ + return; + } + filePaths.push_back(path); + ofNotifyEvent(onItemAdded, path, this); + } + + void onDirectoryWatcherItemRemoved(const ofx::IO::DirectoryWatcherManager::DirectoryEvent & evt){ + string path = evt.item.path(); + Poco::Path pocoPath = Poco::Path(path); + if(!filter->accept(pocoPath)){ + return; + } + // Remove path from vector + for(int i = 0; i < filePaths.size(); i++){ + if(path == filePaths[i]){ + filePaths.erase(filePaths.begin() + i); + break; + } + } + ofNotifyEvent(onItemRemoved, path, this); + } + + void onDirectoryWatcherItemModified(const ofx::IO::DirectoryWatcherManager::DirectoryEvent & evt){ + string path = evt.item.path(); + Poco::Path pocoPath = Poco::Path(path); + if(!filter->accept(pocoPath)){ + return; + } + ofNotifyEvent(onItemModified, path, this); + } + + void onDirectoryWatcherItemMovedFrom(const ofx::IO::DirectoryWatcherManager::DirectoryEvent & evt){ + string path = evt.item.path(); + Poco::Path pocoPath = Poco::Path(path); + if(!filter->accept(pocoPath)){ + return; + } + ofLogNotice("ofApp::onDirectoryWatcherItemMovedFrom") + << "Moved From: " << path; + ofNotifyEvent(onItemMovedFrom, path, this); + } + + void onDirectoryWatcherItemMovedTo(const ofx::IO::DirectoryWatcherManager::DirectoryEvent & evt){ + string path = evt.item.path(); + Poco::Path pocoPath = Poco::Path(path); + if(!filter->accept(pocoPath)){ + return; + } + ofLogNotice("ofApp::onDirectoryWatcherItemMovedTo") + << "Moved To: " << path; + ofNotifyEvent(onItemMovedTo, path, this); + } + + void onDirectoryWatcherError(const Poco::Exception & exc){ + ofLogError("ofApp::onDirectoryWatcherError") + << "Error: " << exc.displayText(); + } + + // Getters + std::vector & getFilePaths(); + int getMediaType(); + + // Custom events + ofEvent onItemAdded; + ofEvent onItemRemoved; + ofEvent onItemModified; + ofEvent onItemMovedFrom; + ofEvent onItemMovedTo; + + private: + ofx::IO::DirectoryWatcherManager dirWatcher; + BasePathFilter * filter; + std::vector filePaths; + int mediaType; }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/MediaServer/MediaServer.cpp b/src/MediaServer/MediaServer.cpp index eee31cb..d175062 100644 --- a/src/MediaServer/MediaServer.cpp +++ b/src/MediaServer/MediaServer.cpp @@ -11,372 +11,378 @@ namespace ofx { namespace piMapper { - MediaServer::MediaServer(): - videoWatcher(ofToDataPath(DEFAULT_VIDEOS_DIR, true), SourceType::SOURCE_TYPE_VIDEO), - imageWatcher(ofToDataPath(DEFAULT_IMAGES_DIR, true), SourceType::SOURCE_TYPE_IMAGE) { - addWatcherListeners(); - } +MediaServer::MediaServer() : + videoWatcher(ofToDataPath(DEFAULT_VIDEOS_DIR, true), SourceType::SOURCE_TYPE_VIDEO), + imageWatcher(ofToDataPath(DEFAULT_IMAGES_DIR, true), SourceType::SOURCE_TYPE_IMAGE){ + addWatcherListeners(); +} - MediaServer::~MediaServer() { - removeWatcherListeners(); - }; +MediaServer::~MediaServer(){ + removeWatcherListeners(); +} - int MediaServer::getNumImages() { return imageWatcher.getFilePaths().size(); } - int MediaServer::getNumVideos() { return videoWatcher.getFilePaths().size(); } - int MediaServer::getNumFboSources() { return fboSources.size(); } +int MediaServer::getNumImages(){ + return imageWatcher.getFilePaths().size(); +} +int MediaServer::getNumVideos(){ + return videoWatcher.getFilePaths().size(); +} +int MediaServer::getNumFboSources(){ + return fboSources.size(); +} + +std::vector & MediaServer::getImagePaths(){ + return imageWatcher.getFilePaths(); +} + +std::vector MediaServer::getImageNames(){ + std::vector imageNames; + for(int i = 0; i < getNumImages(); i++){ + // Split image path + std::vector pathParts = ofSplitString(getImagePaths()[i], "/"); + // And get only the last piece + std::string name = pathParts[pathParts.size() - 1]; + imageNames.push_back(name); + } + return imageNames; +} + +std::vector MediaServer::getFboSourceNames(){ + std::vector fboSourceNames; + for(int i = 0; i < fboSources.size(); i++){ + fboSourceNames.push_back(fboSources[i]->getName()); + } + return fboSourceNames; +} + +std::vector & MediaServer::getVideoPaths(){ + return videoWatcher.getFilePaths(); +} + +std::vector MediaServer::getVideoNames(){ + std::vector videoNames; + for(int i = 0; i < getNumVideos(); i++){ + // Split video path + std::vector pathParts = ofSplitString(getVideoPaths()[i], "/"); + // And get only the last piece + std::string name = pathParts[pathParts.size() - 1]; + videoNames.push_back(name); + } + return videoNames; +} + +BaseSource * MediaServer::loadMedia(string & path, int mediaType){ + // Chose load method depending on type + if(mediaType == SourceType::SOURCE_TYPE_IMAGE){ + return loadImage(path); + }else if(mediaType == SourceType::SOURCE_TYPE_VIDEO){ + return loadVideo(path); + }else if(mediaType == SourceType::SOURCE_TYPE_FBO){ + return loadFboSource(path); + }else{ + std::stringstream ss; + ss << "Can not load media of unknown type: " << mediaType; + ofLogFatalError("MediaServer") << ss.str(); + std::exit(EXIT_FAILURE); + } + return NULL; +} + +BaseSource * MediaServer::loadImage(string & path){ + ImageSource * imageSource = NULL; + // Check if this image is already loaded + bool isImageLoaded = false; + if(loadedSources.count(path)){ + imageSource = static_cast (loadedSources[path]); + isImageLoaded = true; + } + // If image is loaded + if(isImageLoaded){ + // Increase reference count of this source + //referenceCount[path]++; + imageSource->referenceCount++; + std::stringstream refss; + refss << "Current reference count for " << path << " = " << imageSource->referenceCount; + ofLogNotice("MediaServer") << refss.str(); + // Notify objects registered to onImageLoaded event + std::stringstream ss; + ss << "Image " << path << " already loaded"; + ofLogNotice("MediaServer") << ss.str(); + ofNotifyEvent(onImageLoaded, path, this); + return imageSource; + } + // Else load fresh + imageSource = new ImageSource(); + imageSource->loadImage(path); + loadedSources[path] = imageSource; + // Set reference count of this image path to 1 + //referenceCount[path] = 1; + std::stringstream refss; + refss << "Initialized reference count of " << path << " to " << imageSource->referenceCount; + ofLogNotice("MediaServer") << refss.str(); + // Notify objects registered to onImageLoaded event + ofNotifyEvent(onImageLoaded, path, this); + return imageSource; +} + +void MediaServer::unloadImage(string & path){ + ImageSource * source = static_cast (getSourceByPath(path)); + ofLogNotice("MediaServer") << "Unload image, current reference count: " << source->referenceCount; + source->referenceCount--; + // Unload only if reference count is less or equal to 0 + ofLogNotice("MediaServer") << "New reference count: " << source->referenceCount; + if(source->referenceCount > 0){ + ofLogNotice("MediaServer") << "Not unloading image as it is being referenced elsewhere"; + return; + } + // Reference count 0 or less, unload image + std::stringstream ss; + ss << "Removing image " << path; + ofLogNotice("MediaServer") << ss.str(); + // Destroy image source + if(loadedSources.count(path)){ + ofLogNotice("MediaServer") << "Source count BEFORE image removal: " << loadedSources.size() << endl; + loadedSources[path]->clear(); + std::map ::iterator it = loadedSources.find(path); + delete it->second; + loadedSources.erase(it); + ofLogNotice("MediaServer") << "Source count AFTER image removal: " << loadedSources.size() << endl; + ofNotifyEvent(onImageUnloaded, path, this); + return; + } + // Something wrong here, we should be out of the routine by now + std::stringstream failss; + failss << "Failed to remove image source: " << path; + ofLogFatalError("MediaServer") << failss.str(); + std::exit(EXIT_FAILURE); +} + +BaseSource * MediaServer::loadVideo(string & path){ + VideoSource * videoSource = NULL; + // Check if this video is already loaded + bool isVideoLoaded = false; + if(loadedSources.count(path)){ + videoSource = static_cast (loadedSources[path]); + isVideoLoaded = true; + } + // If is loaded + if(isVideoLoaded){ + // Increase reference count of this source + videoSource->referenceCount++; + std::stringstream refss; + refss << "Current reference count for " << path << " = " << videoSource->referenceCount; + ofLogNotice("MediaServer") << refss.str(); + // Notify objects registered to onImageLoaded event + std::stringstream ss; + ss << "Video " << path << " already loaded"; + ofLogNotice("MediaServer") << ss.str(); + ofNotifyEvent(onVideoLoaded, path, this); + return videoSource; + } + // Else load fresh + videoSource = new VideoSource(); + videoSource->loadVideo(path); + loadedSources[path] = videoSource; + // Set reference count of this image path to 1 + //referenceCount[path] = 1; + std::stringstream refss; + refss << "Initialized reference count of " << path << " to " << videoSource->referenceCount; + ofLogNotice("MediaServer") << refss.str(); + ofNotifyEvent(onVideoLoaded, path, this); + return videoSource; +} + +void MediaServer::unloadVideo(string & path){ + VideoSource * videoSource = static_cast (getSourceByPath(path)); + // Decrease reference count of the video + //referenceCount[path]--; + videoSource->referenceCount--; + // Unload only if reference count is less or equal to 0 + if(videoSource->referenceCount > 0){ + ofLogNotice("MediaServer") << "Not unloading video as it is being referenced elsewhere"; + return; + } + // Reference count 0 or less, let's unload the video + ofLogNotice("MediaServer") << "Removing video " << path; + // Distroy video source + if(loadedSources.count(path)){ + ofLogNotice("MediaServer") << "Source count before video removal: " << loadedSources.size() << endl; + videoSource->clear(); + std::map ::iterator it = loadedSources.find(path); + delete it->second; + loadedSources.erase(it); + ofLogNotice("MediaServer") << "Source count after video removal: " << loadedSources.size() << endl; + ofNotifyEvent(onVideoUnloaded, path, this); + return; + } + // Something wrong here, we should be out of the routine by now + std::stringstream failss; + failss << "Failed to remove video source: " << path; + ofLogFatalError("MediaServer") << failss.str(); + std::exit(EXIT_FAILURE); +} + +void MediaServer::unloadMedia(string & path){ + if(loadedSources.count(path)){ + BaseSource * mediaSource = getSourceByPath(path); + if(mediaSource->getType() == SourceType::SOURCE_TYPE_IMAGE){ + unloadImage(path); + }else if(mediaSource->getType() == SourceType::SOURCE_TYPE_VIDEO){ + unloadVideo(path); + }else if(mediaSource->getType() == SourceType::SOURCE_TYPE_FBO){ + unloadFboSource(path); + }else{ + // Oh my god, what to do!? Relax and exit. + ofLogFatalError("MediaServer") << "Attempt to unload media of unknown type"; + std::exit(EXIT_FAILURE); + } + }else{ + ofLogNotice("MediaServer") << "Nothing to unload"; + } +} + +// Clear all loaded media +void MediaServer::clear(){ + typedef std::map ::iterator it_type; + for(it_type i = loadedSources.begin(); i != loadedSources.end(); i++){ + // Do not delete FBO source pointers as they are (and should be) initialized elsewhere + if(i->second->getType() != SourceType::SOURCE_TYPE_FBO){ + delete i->second; + } + } + loadedSources.clear(); +} + +// TODO: getLoadedSourceByPath +BaseSource * MediaServer::getSourceByPath(std::string & mediaPath){ + if(loadedSources.count(mediaPath)){ + return loadedSources[mediaPath]; + } + // Source not found, exit with error + std::stringstream ss; + ss << "Could not find source by path: " << mediaPath; + ofLogFatalError("MediaServer") << ss.str(); + std::exit(EXIT_FAILURE); +} + +std::string MediaServer::getDefaultImageDir(){ + return DEFAULT_IMAGES_DIR; +} + +std::string MediaServer::getDefaultVideoDir(){ + return DEFAULT_VIDEOS_DIR; +} + +std::string MediaServer::getDefaultMediaDir(int sourceType){ + if(sourceType == SourceType::SOURCE_TYPE_IMAGE){ + return getDefaultImageDir(); + }else if(sourceType == SourceType::SOURCE_TYPE_VIDEO){ + return getDefaultVideoDir(); + }else{ + std::stringstream ss; + ss << "Could not get default media dir. Unknown source type: " << sourceType; + ofLogFatalError("MediaServer") << ss.str(); + std::exit(EXIT_FAILURE); + } +} + +void MediaServer::addFboSource(ofx::piMapper::FboSource & fboSource){ + ofLogNotice("MediaServer") << "Attempting to add FBO source with name " << fboSource.getName(); + // FBO source has to be with unique name + for(int i = 0; i < fboSources.size(); i++){ + if(fboSources[i]->getName() == fboSource.getName()){ + ofLogWarning("MediaServer") << "Attempt to add FBO source with duplicate name"; + ofExit(EXIT_FAILURE); // Here we definitely need to fail to avoid confusion + } + } + ofLogNotice("MediaServer") << "Source new, adding"; + fboSources.push_back(&fboSource); +} // addFboSource + +BaseSource * MediaServer::loadFboSource(std::string & fboSourceName){ + ofLogNotice("MediaServer") << "Attempting to load FBO source with name " << fboSourceName; + // Search for FBO source name in our storage + FboSource * source = NULL; + for(int i = 0; i < fboSources.size(); i++){ + if(fboSources[i]->getName() == fboSourceName){ + source = fboSources[i]; + break; + } + } + // Panic if not in storage + if(source == NULL){ + ofLogError("MediaServer") << "Attempt to load non existing FBO source: " << fboSourceName; + ofExit(EXIT_FAILURE); + } + // Check if it is loaded/activated + if(loadedSources.count(fboSourceName)){ + // Is loaded, increase reference count and return existing + loadedSources[fboSourceName]->referenceCount++; + ofLogNotice("MediaServer") << "Current " << fboSourceName << "reference count: " << loadedSources[fboSourceName]->referenceCount; + return loadedSources[fboSourceName]; + } + // else + // Not loaded, add to loaded sources and activate + // source var should be set by now + source->addAppListeners(); + source->referenceCount = 1; + ofLogNotice("MediaServer") << "Current " << fboSourceName << " reference count: " << source->referenceCount; + loadedSources[fboSourceName] = source; + return loadedSources[fboSourceName]; +} // loadFboSource + +void MediaServer::unloadFboSource(std::string & fboSourceName){ + ofLogNotice("MediaServer") << "Attempt to unload FBO source " << fboSourceName; + // Check if loaded at all + if(!loadedSources.count(fboSourceName)){ + ofLogWarning("MediaServer") << "FBO source not loaded"; + return; + } + // TODO: remove static cast, make the sources handle reference counting, + // enabling and disabling by themselves + FboSource * source = static_cast (loadedSources[fboSourceName]); + // else decrease reference count + source->referenceCount--; + ofLogNotice("MediaServer") << "Current " << fboSourceName << "reference count: " << loadedSources[fboSourceName]->referenceCount; + // If no references left, disable + if(source->referenceCount <= 0){ + ofLogNotice("MediaServer") << fboSourceName << " reference count <= 0, removing from loaded sources"; + source->referenceCount = 0; + source->removeAppListeners(); + std::map ::iterator it = loadedSources.find(fboSourceName); + loadedSources.erase(it); + ofLogNotice("MediaServer") << "Source count after FBO source removal: " << loadedSources.size() << endl; + ofNotifyEvent(onFboSourceUnloaded, fboSourceName, this); + } +} // unloadFboSource + +void MediaServer::handleImageAdded(string & path){ + ofNotifyEvent(onImageAdded, path, this); +} +void MediaServer::handleImageRemoved(string & path){ + ofNotifyEvent(onImageRemoved, path, this); +} + +void MediaServer::handleVideoAdded(string & path){ + ofNotifyEvent(onVideoAdded, path, this); +} +void MediaServer::handleVideoRemoved(string & path){ + ofNotifyEvent(onVideoRemoved, path, this); +} + +void MediaServer::addWatcherListeners(){ + ofAddListener(imageWatcher.onItemAdded, this, &MediaServer::handleImageAdded); + ofAddListener(imageWatcher.onItemRemoved, this, &MediaServer::handleImageRemoved); + ofAddListener(videoWatcher.onItemAdded, this, &MediaServer::handleVideoAdded); + ofAddListener(videoWatcher.onItemRemoved, this, &MediaServer::handleVideoRemoved); +} + +void MediaServer::removeWatcherListeners(){ + ofRemoveListener(imageWatcher.onItemAdded, this, &MediaServer::handleImageAdded); + ofRemoveListener(imageWatcher.onItemRemoved, this, &MediaServer::handleImageRemoved); + ofRemoveListener(videoWatcher.onItemAdded, this, &MediaServer::handleVideoAdded); + ofRemoveListener(videoWatcher.onItemRemoved, this, &MediaServer::handleVideoRemoved); +} - std::vector& MediaServer::getImagePaths() { - return imageWatcher.getFilePaths(); - } - - std::vector MediaServer::getImageNames() { - std::vector imageNames; - for (int i = 0; i < getNumImages(); i++) { - // Split image path - std::vector pathParts = ofSplitString(getImagePaths()[i], "/"); - // And get only the last piece - std::string name = pathParts[pathParts.size()-1]; - imageNames.push_back(name); - } - return imageNames; - } - - std::vector MediaServer::getFboSourceNames() { - std::vector fboSourceNames; - for (int i = 0; i < fboSources.size(); i++) { - fboSourceNames.push_back(fboSources[i]->getName()); - } - return fboSourceNames; - } - - std::vector& MediaServer::getVideoPaths() { - return videoWatcher.getFilePaths(); - } - - std::vector MediaServer::getVideoNames() { - std::vector videoNames; - for (int i = 0; i < getNumVideos(); i++) { - // Split video path - std::vector pathParts = ofSplitString(getVideoPaths()[i], "/"); - // And get only the last piece - std::string name = pathParts[pathParts.size()-1]; - videoNames.push_back(name); - } - return videoNames; - } - - BaseSource* MediaServer::loadMedia(string &path, int mediaType) { - // Chose load method depending on type - if (mediaType == SourceType::SOURCE_TYPE_IMAGE) { - return loadImage(path); - } else if (mediaType == SourceType::SOURCE_TYPE_VIDEO) { - return loadVideo(path); - } else if (mediaType == SourceType::SOURCE_TYPE_FBO) { - return loadFboSource(path); - } else { - std::stringstream ss; - ss << "Can not load media of unknown type: " << mediaType; - ofLogFatalError("MediaServer") << ss.str(); - std::exit(EXIT_FAILURE); - } - return NULL; - } - - BaseSource* MediaServer::loadImage(string& path) { - ImageSource* imageSource = NULL; - // Check if this image is already loaded - bool isImageLoaded = false; - if (loadedSources.count(path)) { - imageSource = static_cast(loadedSources[path]); - isImageLoaded = true; - } - // If image is loaded - if (isImageLoaded) { - // Increase reference count of this source - //referenceCount[path]++; - imageSource->referenceCount++; - std::stringstream refss; - refss << "Current reference count for " << path << " = " << imageSource->referenceCount; - ofLogNotice("MediaServer") << refss.str(); - // Notify objects registered to onImageLoaded event - std::stringstream ss; - ss << "Image " << path << " already loaded"; - ofLogNotice("MediaServer") << ss.str(); - ofNotifyEvent(onImageLoaded, path, this); - return imageSource; - } - // Else load fresh - imageSource = new ImageSource(); - imageSource->loadImage(path); - loadedSources[path] = imageSource; - // Set reference count of this image path to 1 - //referenceCount[path] = 1; - std::stringstream refss; - refss << "Initialized reference count of " << path << " to " << imageSource->referenceCount; - ofLogNotice("MediaServer") << refss.str(); - // Notify objects registered to onImageLoaded event - ofNotifyEvent(onImageLoaded, path, this); - return imageSource; - } - - void MediaServer::unloadImage(string& path) { - ImageSource* source = static_cast(getSourceByPath(path)); - ofLogNotice("MediaServer") << "Unload image, current reference count: " << source->referenceCount; - source->referenceCount--; - // Unload only if reference count is less or equal to 0 - ofLogNotice("MediaServer") << "New reference count: " << source->referenceCount; - if (source->referenceCount > 0) { - ofLogNotice("MediaServer") << "Not unloading image as it is being referenced elsewhere"; - return; - } - // Reference count 0 or less, unload image - std::stringstream ss; - ss << "Removing image " << path; - ofLogNotice("MediaServer") << ss.str(); - // Destroy image source - if (loadedSources.count(path)) { - ofLogNotice("MediaServer") << "Source count BEFORE image removal: " << loadedSources.size() << endl; - loadedSources[path]->clear(); - std::map::iterator it = loadedSources.find(path); - delete it->second; - loadedSources.erase(it); - ofLogNotice("MediaServer") << "Source count AFTER image removal: " << loadedSources.size() << endl; - ofNotifyEvent(onImageUnloaded, path, this); - return; - } - // Something wrong here, we should be out of the routine by now - std::stringstream failss; - failss << "Failed to remove image source: " << path; - ofLogFatalError("MediaServer") << failss.str(); - std::exit(EXIT_FAILURE); - } - - BaseSource* MediaServer::loadVideo(string& path) { - VideoSource* videoSource = NULL; - // Check if this video is already loaded - bool isVideoLoaded = false; - if (loadedSources.count(path)) { - videoSource = static_cast(loadedSources[path]); - isVideoLoaded = true; - } - // If is loaded - if (isVideoLoaded) { - // Increase reference count of this source - videoSource->referenceCount++; - std::stringstream refss; - refss << "Current reference count for " << path << " = " << videoSource->referenceCount; - ofLogNotice("MediaServer") << refss.str(); - // Notify objects registered to onImageLoaded event - std::stringstream ss; - ss << "Video " << path << " already loaded"; - ofLogNotice("MediaServer") << ss.str(); - ofNotifyEvent(onVideoLoaded, path, this); - return videoSource; - } - // Else load fresh - videoSource = new VideoSource(); - videoSource->loadVideo(path); - loadedSources[path] = videoSource; - // Set reference count of this image path to 1 - //referenceCount[path] = 1; - std::stringstream refss; - refss << "Initialized reference count of " << path << " to " << videoSource->referenceCount; - ofLogNotice("MediaServer") << refss.str(); - ofNotifyEvent(onVideoLoaded, path, this); - return videoSource; - } - - void MediaServer::unloadVideo(string& path) { - VideoSource* videoSource = static_cast(getSourceByPath(path)); - // Decrease reference count of the video - //referenceCount[path]--; - videoSource->referenceCount--; - // Unload only if reference count is less or equal to 0 - if (videoSource->referenceCount > 0) { - ofLogNotice("MediaServer") << "Not unloading video as it is being referenced elsewhere"; - return; - } - // Reference count 0 or less, let's unload the video - ofLogNotice("MediaServer") << "Removing video " << path; - // Distroy video source - if (loadedSources.count(path)) { - ofLogNotice("MediaServer") << "Source count before video removal: " << loadedSources.size() << endl; - videoSource->clear(); - std::map::iterator it = loadedSources.find(path); - delete it->second; - loadedSources.erase(it); - ofLogNotice("MediaServer") << "Source count after video removal: " << loadedSources.size() << endl; - ofNotifyEvent(onVideoUnloaded, path, this); - return; - } - // Something wrong here, we should be out of the routine by now - std::stringstream failss; - failss << "Failed to remove video source: " << path; - ofLogFatalError("MediaServer") << failss.str(); - std::exit(EXIT_FAILURE); - } - - void MediaServer::unloadMedia(string &path) { - if (loadedSources.count(path)) { - BaseSource* mediaSource = getSourceByPath(path); - if (mediaSource->getType() == SourceType::SOURCE_TYPE_IMAGE) { - unloadImage(path); - } else if (mediaSource->getType() == SourceType::SOURCE_TYPE_VIDEO) { - unloadVideo(path); - } else if (mediaSource->getType() == SourceType::SOURCE_TYPE_FBO) { - unloadFboSource(path); - } else { - // Oh my god, what to do!? Relax and exit. - ofLogFatalError("MediaServer") << "Attempt to unload media of unknown type"; - std::exit(EXIT_FAILURE); - } - } else { - ofLogNotice("MediaServer") << "Nothing to unload"; - } - } - - // Clear all loaded media - void MediaServer::clear() { - typedef std::map::iterator it_type; - for (it_type i = loadedSources.begin(); i != loadedSources.end(); i++) { - // Do not delete FBO source pointers as they are (and should be) initialized elsewhere - if (i->second->getType() != SourceType::SOURCE_TYPE_FBO) { - delete i->second; - } - } - loadedSources.clear(); - } - - // TODO: getLoadedSourceByPath - BaseSource* MediaServer::getSourceByPath(std::string& mediaPath) { - if (loadedSources.count(mediaPath)) { - return loadedSources[mediaPath]; - } - // Source not found, exit with error - std::stringstream ss; - ss << "Could not find source by path: " << mediaPath; - ofLogFatalError("MediaServer") << ss.str(); - std::exit(EXIT_FAILURE); - } - - std::string MediaServer::getDefaultImageDir() { - return DEFAULT_IMAGES_DIR; - } - - std::string MediaServer::getDefaultVideoDir() { - return DEFAULT_VIDEOS_DIR; - } - - std::string MediaServer::getDefaultMediaDir(int sourceType) { - if (sourceType == SourceType::SOURCE_TYPE_IMAGE) { - return getDefaultImageDir(); - } else if (sourceType == SourceType::SOURCE_TYPE_VIDEO) { - return getDefaultVideoDir(); - } else { - std::stringstream ss; - ss << "Could not get default media dir. Unknown source type: " << sourceType; - ofLogFatalError("MediaServer") << ss.str(); - std::exit(EXIT_FAILURE); - } - } - - void MediaServer::addFboSource(ofx::piMapper::FboSource &fboSource) { - ofLogNotice("MediaServer") << "Attempting to add FBO source with name " << fboSource.getName(); - // FBO source has to be with unique name - for (int i = 0; i < fboSources.size(); i++) { - if (fboSources[i]->getName() == fboSource.getName()) { - ofLogWarning("MediaServer") << "Attempt to add FBO source with duplicate name"; - ofExit(EXIT_FAILURE); // Here we definitely need to fail to avoid confusion - } - } - ofLogNotice("MediaServer") << "Source new, adding"; - fboSources.push_back(&fboSource); - } // addFboSource - - BaseSource* MediaServer::loadFboSource(std::string &fboSourceName) { - ofLogNotice("MediaServer") << "Attempting to load FBO source with name " << fboSourceName; - // Search for FBO source name in our storage - FboSource* source = NULL; - for (int i = 0; i < fboSources.size(); i++) { - if (fboSources[i]->getName() == fboSourceName) { - source = fboSources[i]; - break; - } - } - // Panic if not in storage - if (source == NULL) { - ofLogError("MediaServer") << "Attempt to load non existing FBO source: " << fboSourceName; - ofExit(EXIT_FAILURE); - } - // Check if it is loaded/activated - if (loadedSources.count(fboSourceName)) { - // Is loaded, increase reference count and return existing - loadedSources[fboSourceName]->referenceCount++; - ofLogNotice("MediaServer") << "Current " << fboSourceName << "reference count: " << loadedSources[fboSourceName]->referenceCount; - return loadedSources[fboSourceName]; - } - // else - // Not loaded, add to loaded sources and activate - // source var should be set by now - source->addAppListeners(); - source->referenceCount = 1; - ofLogNotice("MediaServer") << "Current " << fboSourceName << " reference count: " << source->referenceCount; - loadedSources[fboSourceName] = source; - return loadedSources[fboSourceName]; - } // loadFboSource - - void MediaServer::unloadFboSource(std::string &fboSourceName) { - ofLogNotice("MediaServer") << "Attempt to unload FBO source " << fboSourceName; - // Check if loaded at all - if (!loadedSources.count(fboSourceName)) { - ofLogWarning("MediaServer") << "FBO source not loaded"; - return; - } - // TODO: remove static cast, make the sources handle reference counting, - // enabling and disabling by themselves - FboSource* source = static_cast(loadedSources[fboSourceName]); - // else decrease reference count - source->referenceCount--; - ofLogNotice("MediaServer") << "Current " << fboSourceName << "reference count: " << loadedSources[fboSourceName]->referenceCount; - // If no references left, disable - if (source->referenceCount <= 0) { - ofLogNotice("MediaServer") << fboSourceName << " reference count <= 0, removing from loaded sources"; - source->referenceCount = 0; - source->removeAppListeners(); - std::map::iterator it = loadedSources.find(fboSourceName); - loadedSources.erase(it); - ofLogNotice("MediaServer") << "Source count after FBO source removal: " << loadedSources.size() << endl; - ofNotifyEvent(onFboSourceUnloaded, fboSourceName, this); - } - } // unloadFboSource - - void MediaServer::handleImageAdded(string& path) { - ofNotifyEvent(onImageAdded, path, this); - } - void MediaServer::handleImageRemoved(string& path) { - ofNotifyEvent(onImageRemoved, path, this); - } - - void MediaServer::handleVideoAdded(string& path) { - ofNotifyEvent(onVideoAdded, path, this); - } - void MediaServer::handleVideoRemoved(string& path) { - ofNotifyEvent(onVideoRemoved, path, this); - } - - void MediaServer::addWatcherListeners() { - ofAddListener(imageWatcher.onItemAdded, this, &MediaServer::handleImageAdded); - ofAddListener(imageWatcher.onItemRemoved, this, &MediaServer::handleImageRemoved); - ofAddListener(videoWatcher.onItemAdded, this, &MediaServer::handleVideoAdded); - ofAddListener(videoWatcher.onItemRemoved, this, &MediaServer::handleVideoRemoved); - } - - void MediaServer::removeWatcherListeners() { - ofRemoveListener(imageWatcher.onItemAdded, this, &MediaServer::handleImageAdded); - ofRemoveListener(imageWatcher.onItemRemoved, this, &MediaServer::handleImageRemoved); - ofRemoveListener(videoWatcher.onItemAdded, this, &MediaServer::handleVideoAdded); - ofRemoveListener(videoWatcher.onItemRemoved, this, &MediaServer::handleVideoRemoved); - } - } // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/MediaServer/MediaServer.h b/src/MediaServer/MediaServer.h index 9777818..705aa36 100644 --- a/src/MediaServer/MediaServer.h +++ b/src/MediaServer/MediaServer.h @@ -30,85 +30,86 @@ namespace ofx { namespace piMapper { class MediaServer { - public: - MediaServer(); - virtual ~MediaServer(); - - int getNumVideos(); - int getNumImages(); - int getNumFboSources(); // new - std::vector& getVideoPaths(); - std::vector getVideoNames(); - std::vector& getImagePaths(); - std::vector getImageNames(); - std::vector getFboSourceNames(); // new - - BaseSource* loadMedia(string& path, int mediaType); - BaseSource* loadImage(string& path); - void unloadImage(string& path); - BaseSource* loadVideo(string& path); - void unloadVideo(string& path); - void unloadMedia(string& path); - void clear(); // Force all loaded source unload - BaseSource* getSourceByPath(std::string& mediaPath); - std::string getDefaultImageDir(); - std::string getDefaultVideoDir(); - std::string getDefaultMediaDir(int sourceType); - - // Do things with FBO sources - void addFboSource(FboSource& fboSource); // could be called also as register FBO source - BaseSource* loadFboSource(std::string& fboSourceName); - void unloadFboSource(std::string& fboSourceName); - - // Custom events, add/remove - ofEvent onImageAdded; - ofEvent onImageRemoved; - ofEvent onVideoAdded; - ofEvent onVideoRemoved; - ofEvent onFboSourceAdded; - ofEvent onFboSourceRemoved; - // load/unload - ofEvent onImageLoaded; - ofEvent onImageUnloaded; - ofEvent onVideoLoaded; - ofEvent onVideoUnloaded; - ofEvent onFboSourceLoaded; - ofEvent onFboSourceUnloaded; - - private: - // Directory Watchers - ofx::piMapper::DirectoryWatcher videoWatcher; - ofx::piMapper::DirectoryWatcher imageWatcher; - std::map loadedSources; - // imageWatcher event listeners - void handleImageAdded(string& path); - void handleImageRemoved(string& path); - // TODO rest of listeners - /* - void onImageModified(); - void onImageMovedFrom(); - void onImageMovedTo(); - */ - - // videoWatcher event listeners - void handleVideoAdded(string& path); - void handleVideoRemoved(string& path); - // TODO rest of listeners - /* - void onVideoModified(); - void onVideoMovedFrom(); - void onVideoMovedTo(); - */ - - // Add/remove event listeners. - // Add event listeners to image and video watcher events. - void addWatcherListeners(); - - // Remove event listeners to image and video watcher events - void removeWatcherListeners(); - - // FBO source storage before they go to loadedSources - std::vector fboSources; // FBO source storage + public: + MediaServer(); + virtual ~MediaServer(); + + int getNumVideos(); + int getNumImages(); + int getNumFboSources(); // new + std::vector & getVideoPaths(); + std::vector getVideoNames(); + std::vector & getImagePaths(); + std::vector getImageNames(); + std::vector getFboSourceNames(); // new + + BaseSource * loadMedia(string & path, int mediaType); + BaseSource * loadImage(string & path); + void unloadImage(string & path); + BaseSource * loadVideo(string & path); + void unloadVideo(string & path); + void unloadMedia(string & path); + void clear(); // Force all loaded source unload + BaseSource * getSourceByPath(std::string & mediaPath); + std::string getDefaultImageDir(); + std::string getDefaultVideoDir(); + std::string getDefaultMediaDir(int sourceType); + + // Do things with FBO sources + void addFboSource(FboSource & fboSource); // could be called also as register FBO source + BaseSource * loadFboSource(std::string & fboSourceName); + void unloadFboSource(std::string & fboSourceName); + + // Custom events, add/remove + ofEvent onImageAdded; + ofEvent onImageRemoved; + ofEvent onVideoAdded; + ofEvent onVideoRemoved; + ofEvent onFboSourceAdded; + ofEvent onFboSourceRemoved; + // load/unload + ofEvent onImageLoaded; + ofEvent onImageUnloaded; + ofEvent onVideoLoaded; + ofEvent onVideoUnloaded; + ofEvent onFboSourceLoaded; + ofEvent onFboSourceUnloaded; + + private: + // Directory Watchers + ofx::piMapper::DirectoryWatcher videoWatcher; + ofx::piMapper::DirectoryWatcher imageWatcher; + std::map loadedSources; + // imageWatcher event listeners + void handleImageAdded(string & path); + void handleImageRemoved(string & path); + // TODO rest of listeners + /* + void onImageModified(); + void onImageMovedFrom(); + void onImageMovedTo(); + */ + + // videoWatcher event listeners + void handleVideoAdded(string & path); + void handleVideoRemoved(string & path); + // TODO rest of listeners + /* + void onVideoModified(); + void onVideoMovedFrom(); + void onVideoMovedTo(); + */ + + // Add/remove event listeners. + // Add event listeners to image and video watcher events. + void addWatcherListeners(); + + // Remove event listeners to image and video watcher events + void removeWatcherListeners(); + + // FBO source storage before they go to loadedSources + std::vector fboSources; // FBO source storage }; + } // namespace piMapper } // namespace ofx diff --git a/src/Sources/BaseSource.cpp b/src/Sources/BaseSource.cpp index d984b72..7e84af3 100644 --- a/src/Sources/BaseSource.cpp +++ b/src/Sources/BaseSource.cpp @@ -1,59 +1,61 @@ #include "BaseSource.h" namespace ofx { - namespace piMapper { - BaseSource::BaseSource() { - //cout << "BaseSource" << endl; - init(); - } - - BaseSource::BaseSource(ofTexture* newTexture) { - init(); - texture = newTexture; - } - - BaseSource::~BaseSource() {} - - ofTexture* BaseSource::getTexture() { - return texture; - } - - std::string& BaseSource::getName() { - return name; - } - - bool BaseSource::isLoadable() { - return loadable; - } - - bool BaseSource::isLoaded() { - return loaded; - } - - int BaseSource::getType() { - return type; - } - - std::string& BaseSource::getPath() { - return path; - } - - void BaseSource::init() { - texture = NULL; - name = ""; - path = ""; - loadable = false; - loaded = false; - type = SourceType::SOURCE_TYPE_NONE; - referenceCount = 1; // We have one instance on init - } - - void BaseSource::setNameFromPath(std::string& fullPath) { - std::vector pathParts; - //cout << "fullPath: " << fullPath << endl; - pathParts = ofSplitString(fullPath, "/"); // Maybe on win "/" is "\", have to test - //cout << "lastPathPart: " << pathParts[pathParts.size() - 1] << endl; - name = pathParts[pathParts.size() - 1]; - } - } -} \ No newline at end of file +namespace piMapper { + +BaseSource::BaseSource(){ + //cout << "BaseSource" << endl; + init(); +} + +BaseSource::BaseSource(ofTexture * newTexture){ + init(); + texture = newTexture; +} + +BaseSource::~BaseSource(){} + +ofTexture * BaseSource::getTexture(){ + return texture; +} + +std::string & BaseSource::getName(){ + return name; +} + +bool BaseSource::isLoadable(){ + return loadable; +} + +bool BaseSource::isLoaded(){ + return loaded; +} + +int BaseSource::getType(){ + return type; +} + +std::string & BaseSource::getPath(){ + return path; +} + +void BaseSource::init(){ + texture = NULL; + name = ""; + path = ""; + loadable = false; + loaded = false; + type = SourceType::SOURCE_TYPE_NONE; + referenceCount = 1; // We have one instance on init +} + +void BaseSource::setNameFromPath(std::string & fullPath){ + std::vector pathParts; + //cout << "fullPath: " << fullPath << endl; + pathParts = ofSplitString(fullPath, "/"); // Maybe on win "/" is "\", have to test + //cout << "lastPathPart: " << pathParts[pathParts.size() - 1] << endl; + name = pathParts[pathParts.size() - 1]; +} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Sources/BaseSource.h b/src/Sources/BaseSource.h index 5dbc894..c989fb5 100644 --- a/src/Sources/BaseSource.h +++ b/src/Sources/BaseSource.h @@ -4,36 +4,40 @@ #include "SourceType.h" namespace ofx { - namespace piMapper { - // Use this for adding generative sources to your surfaces - class BaseSource { - public: - BaseSource(); - BaseSource(ofTexture* newTexture); // Only one clean way of passing the texture - ~BaseSource(); - ofTexture* getTexture(); - std::string& getName(); - bool isLoadable(); // Maybe the loading features shoud go to a derrived class - bool isLoaded(); // as BaseSourceLoadable - int getType(); - std::string& getPath(); - virtual void clear() {}; - - // TODO: add virtual increaseReferenceCount and decreaseReferenceCount methods - // and make the variable protected - int referenceCount; - - private: - void init(); - - protected: - void setNameFromPath(std::string& fullPath); - ofTexture* texture; - std::string name; - std::string path; // This is set only if loadable is true - bool loadable; // If the source can be loaded from disk like image and video - bool loaded; // Is the source loaded? - int type; - }; - } -} +namespace piMapper { + +// Use this for adding generative sources to your surfaces +class BaseSource { + + public: + BaseSource(); + BaseSource(ofTexture * newTexture); // Only one clean way of passing the texture + ~BaseSource(); + ofTexture * getTexture(); + std::string & getName(); + bool isLoadable(); // Maybe the loading features shoud go to a derrived class + bool isLoaded(); // as BaseSourceLoadable + int getType(); + std::string & getPath(); + virtual void clear(){} + + // TODO: add virtual increaseReferenceCount and decreaseReferenceCount methods + // and make the variable protected + int referenceCount; + + private: + void init(); + + protected: + void setNameFromPath(std::string & fullPath); + ofTexture * texture; + std::string name; + std::string path; // This is set only if loadable is true + bool loadable; // If the source can be loaded from disk like image and video + bool loaded; // Is the source loaded? + int type; + +}; + +} // namespace piMapper +} // namespace ofx diff --git a/src/Sources/FboSource.cpp b/src/Sources/FboSource.cpp index d61bad9..85ae028 100644 --- a/src/Sources/FboSource.cpp +++ b/src/Sources/FboSource.cpp @@ -1,115 +1,115 @@ #include "FboSource.h" namespace ofx { - namespace piMapper { - - FboSource::FboSource() : fbo(NULL) { - name = PIMAPPER_FBO_SOURCE_DEF_NAME; - loadable = false; - loaded = false; - type = SourceType::SOURCE_TYPE_FBO; - ofAddListener(ofEvents().setup, this, - &FboSource::onAppSetup, OF_EVENT_ORDER_BEFORE_APP); - } - - FboSource::~FboSource() { - removeAppListeners(); - clear(); - } - - void FboSource::addAppListeners() { - ofLogNotice("FboSource") << "Adding app listeners"; - ofAddListener(ofEvents().update, this, - &FboSource::onAppUpdate, OF_EVENT_ORDER_BEFORE_APP); - ofAddListener(ofEvents().draw, this, - &FboSource::onAppDraw, OF_EVENT_ORDER_BEFORE_APP); - ofAddListener(ofEvents().exit, this, - &FboSource::onAppExit, OF_EVENT_ORDER_AFTER_APP); - } - - void FboSource::removeAppListeners() { - ofLogNotice("FboSource") << "Removing app listeners"; - ofRemoveListener(ofEvents().update, this, - &FboSource::onAppUpdate, OF_EVENT_ORDER_BEFORE_APP); - ofRemoveListener(ofEvents().draw, this, - &FboSource::onAppDraw, OF_EVENT_ORDER_BEFORE_APP); - ofRemoveListener(ofEvents().exit, this, - &FboSource::onAppExit, OF_EVENT_ORDER_AFTER_APP); - } - - void FboSource::onAppSetup(ofEventArgs &args) { - ofRemoveListener(ofEvents().setup, this, - &FboSource::onAppSetup, OF_EVENT_ORDER_BEFORE_APP); - setup(); - - // Check if FBO was allocated in user defined setup - // If not, show warning and alocate to avoid panic - if (!fbo->isAllocated()) { - ofLogWarning("FboSource::onAppSetup") << - "FBO not allocated, allocating with default values"; - allocate(PIMAPPER_FBO_SOURCE_DEF_WIDTH, - PIMAPPER_FBO_SOURCE_DEF_HEIGHT); - } - } - - void FboSource::onAppUpdate(ofEventArgs &args) { - if (fbo == NULL || !fbo->isAllocated()) { - ofLogWarning("FboSource") << "FBO not allocated"; - return; - } - update(); - } - - void FboSource::onAppDraw(ofEventArgs &args) { - if (fbo == NULL || !fbo->isAllocated()) { - ofLogWarning("FboSource") << "FBO not allocated"; - return; - } - fbo->begin(); - draw(); - fbo->end(); - } - - void FboSource::onAppExit(ofEventArgs &args) { - exit(); - } - - void FboSource::allocate(int width, int height) { - clear(); - fbo = new ofFbo(); - fbo->allocate(width, height); - - // Clear FBO - fbo->begin(); - ofClear(0); - fbo->end(); - - texture = &(fbo->getTextureReference()); - } - - void FboSource::clear() { - texture = NULL; - if (fbo != NULL) { - delete fbo; - fbo = NULL; - } - } - - int FboSource::getWidth() { - if (fbo->isAllocated()) { - return fbo->getWidth(); - } else { - return 0; - } - } - - int FboSource::getHeight() { - if (fbo->isAllocated()) { - return fbo->getHeight(); - } else { - return 0; - } - } - - } // namespace piMapper +namespace piMapper { + +FboSource::FboSource() : fbo(NULL){ + name = PIMAPPER_FBO_SOURCE_DEF_NAME; + loadable = false; + loaded = false; + type = SourceType::SOURCE_TYPE_FBO; + ofAddListener(ofEvents().setup, this, + &FboSource::onAppSetup, OF_EVENT_ORDER_BEFORE_APP); +} + +FboSource::~FboSource(){ + removeAppListeners(); + clear(); +} + +void FboSource::addAppListeners(){ + ofLogNotice("FboSource") << "Adding app listeners"; + ofAddListener(ofEvents().update, this, + &FboSource::onAppUpdate, OF_EVENT_ORDER_BEFORE_APP); + ofAddListener(ofEvents().draw, this, + &FboSource::onAppDraw, OF_EVENT_ORDER_BEFORE_APP); + ofAddListener(ofEvents().exit, this, + &FboSource::onAppExit, OF_EVENT_ORDER_AFTER_APP); +} + +void FboSource::removeAppListeners(){ + ofLogNotice("FboSource") << "Removing app listeners"; + ofRemoveListener(ofEvents().update, this, + &FboSource::onAppUpdate, OF_EVENT_ORDER_BEFORE_APP); + ofRemoveListener(ofEvents().draw, this, + &FboSource::onAppDraw, OF_EVENT_ORDER_BEFORE_APP); + ofRemoveListener(ofEvents().exit, this, + &FboSource::onAppExit, OF_EVENT_ORDER_AFTER_APP); +} + +void FboSource::onAppSetup(ofEventArgs & args){ + ofRemoveListener(ofEvents().setup, this, + &FboSource::onAppSetup, OF_EVENT_ORDER_BEFORE_APP); + setup(); + + // Check if FBO was allocated in user defined setup + // If not, show warning and alocate to avoid panic + if(!fbo->isAllocated()){ + ofLogWarning("FboSource::onAppSetup") + << "FBO not allocated, allocating with default values"; + allocate(PIMAPPER_FBO_SOURCE_DEF_WIDTH, + PIMAPPER_FBO_SOURCE_DEF_HEIGHT); + } +} + +void FboSource::onAppUpdate(ofEventArgs & args){ + if(fbo == NULL || !fbo->isAllocated()){ + ofLogWarning("FboSource") << "FBO not allocated"; + return; + } + update(); +} + +void FboSource::onAppDraw(ofEventArgs & args){ + if(fbo == NULL || !fbo->isAllocated()){ + ofLogWarning("FboSource") << "FBO not allocated"; + return; + } + fbo->begin(); + draw(); + fbo->end(); +} + +void FboSource::onAppExit(ofEventArgs & args){ + exit(); +} + +void FboSource::allocate(int width, int height){ + clear(); + fbo = new ofFbo(); + fbo->allocate(width, height); + + // Clear FBO + fbo->begin(); + ofClear(0); + fbo->end(); + + texture = &(fbo->getTextureReference()); +} + +void FboSource::clear(){ + texture = NULL; + if(fbo != NULL){ + delete fbo; + fbo = NULL; + } +} + +int FboSource::getWidth(){ + if(fbo->isAllocated()){ + return fbo->getWidth(); + }else{ + return 0; + } +} + +int FboSource::getHeight(){ + if(fbo->isAllocated()){ + return fbo->getHeight(); + }else{ + return 0; + } +} + +} // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/Sources/FboSource.h b/src/Sources/FboSource.h index ea54e92..819529c 100644 --- a/src/Sources/FboSource.h +++ b/src/Sources/FboSource.h @@ -8,38 +8,40 @@ #define PIMAPPER_FBO_SOURCE_DEF_HEIGHT 500 namespace ofx { - namespace piMapper { - - class FboSource : public BaseSource { - public: - FboSource(); - ~FboSource(); - - // Override these in your custom FBO source - virtual void setup() {}; - virtual void update() {}; - virtual void draw() {}; - virtual void exit() {}; - - // The only method from BaseSource to be overriden - void clear(); - - // App listeners - void addAppListeners(); - void removeAppListeners(); - void onAppSetup(ofEventArgs & args); - void onAppUpdate(ofEventArgs & args); - void onAppDraw(ofEventArgs & args); - void onAppExit(ofEventArgs & args); - - protected: - ofFbo * fbo; - void allocate(int width, int height); - - // Some handy getters - int getWidth(); - int getHeight(); - }; - - } // namespace piMapper +namespace piMapper { + +class FboSource : public BaseSource { + + public: + FboSource(); + ~FboSource(); + + // Override these in your custom FBO source + virtual void setup(){} + virtual void update(){} + virtual void draw(){} + virtual void exit(){} + + // The only method from BaseSource to be overriden + void clear(); + + // App listeners + void addAppListeners(); + void removeAppListeners(); + void onAppSetup(ofEventArgs & args); + void onAppUpdate(ofEventArgs & args); + void onAppDraw(ofEventArgs & args); + void onAppExit(ofEventArgs & args); + + protected: + ofFbo * fbo; + void allocate(int width, int height); + + // Some handy getters + int getWidth(); + int getHeight(); + +}; + +} // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/Sources/ImageSource.cpp b/src/Sources/ImageSource.cpp index 0cf8dde..b41366d 100644 --- a/src/Sources/ImageSource.cpp +++ b/src/Sources/ImageSource.cpp @@ -1,39 +1,40 @@ #include "ImageSource.h" namespace ofx { - namespace piMapper { - ImageSource::ImageSource() { - //cout << "ImageSource" << endl; - loadable = true; - loaded = false; - type = SourceType::SOURCE_TYPE_IMAGE; - } - - ImageSource::~ImageSource() {} - - void ImageSource::loadImage(std::string& filePath) { - path = filePath; - //cout << "loading image: " << filePath << endl; - setNameFromPath(filePath); - //cout << "path: " << path << endl; - image = new ofImage(); - if (!image->loadImage(filePath)) { - ofLogWarning("ImageSource") << "Could not load image"; - //std::exit(EXIT_FAILURE); - } - texture = &image->getTextureReference(); - loaded = true; - } - - void ImageSource::clear() { - texture = NULL; - image->clear(); - delete image; - image = NULL; - //path = ""; - //name = ""; - loaded = false; - } - - } -} \ No newline at end of file +namespace piMapper { + +ImageSource::ImageSource(){ + //cout << "ImageSource" << endl; + loadable = true; + loaded = false; + type = SourceType::SOURCE_TYPE_IMAGE; +} + +ImageSource::~ImageSource(){} + +void ImageSource::loadImage(std::string & filePath){ + path = filePath; + //cout << "loading image: " << filePath << endl; + setNameFromPath(filePath); + //cout << "path: " << path << endl; + image = new ofImage(); + if(!image->loadImage(filePath)){ + ofLogWarning("ImageSource") << "Could not load image"; + //std::exit(EXIT_FAILURE); + } + texture = &image->getTextureReference(); + loaded = true; +} + +void ImageSource::clear(){ + texture = NULL; + image->clear(); + delete image; + image = NULL; + //path = ""; + //name = ""; + loaded = false; +} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Sources/ImageSource.h b/src/Sources/ImageSource.h index 29a5d79..2d34270 100644 --- a/src/Sources/ImageSource.h +++ b/src/Sources/ImageSource.h @@ -3,16 +3,20 @@ #include "BaseSource.h" namespace ofx { - namespace piMapper { - class ImageSource : public BaseSource { - public: - ImageSource(); - ~ImageSource(); - std::string& getPath(); - void loadImage(std::string& filePath); - void clear(); - private: - ofImage* image; - }; - } -} \ No newline at end of file +namespace piMapper { + +class ImageSource : public BaseSource { + + public: + ImageSource(); + ~ImageSource(); + std::string & getPath(); + void loadImage(std::string & filePath); + void clear(); + private: + ofImage * image; + +}; + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Sources/SourceType.h b/src/Sources/SourceType.h index ad4ebe5..ebd2e1f 100644 --- a/src/Sources/SourceType.h +++ b/src/Sources/SourceType.h @@ -8,44 +8,50 @@ #define SOURCE_TYPE_NAME_FBO "fbo" namespace ofx { - namespace piMapper { - class SourceType { - public: - enum { SOURCE_TYPE_NONE, SOURCE_TYPE_IMAGE, SOURCE_TYPE_VIDEO, SOURCE_TYPE_FBO }; - - static std::string GetSourceTypeName(int sourceTypeEnum) { - if (sourceTypeEnum == SOURCE_TYPE_IMAGE) { - return SOURCE_TYPE_NAME_IMAGE; - } else if (sourceTypeEnum == SOURCE_TYPE_VIDEO) { - return SOURCE_TYPE_NAME_VIDEO; - } else if (sourceTypeEnum == SOURCE_TYPE_NONE) { - return SOURCE_TYPE_NAME_NONE; - } else if (sourceTypeEnum == SOURCE_TYPE_FBO) { - return SOURCE_TYPE_NAME_FBO; - } else { - std::stringstream ss; - ss << "Invalid source type: " << sourceTypeEnum; - ofLogFatalError("SourceType") << ss.str(); - std::exit(EXIT_FAILURE); - } - }; - - static int GetSourceTypeEnum(std::string sourceTypeName) { - if (sourceTypeName == SOURCE_TYPE_NAME_IMAGE) { - return SOURCE_TYPE_IMAGE; - } else if (sourceTypeName == SOURCE_TYPE_NAME_VIDEO) { - return SOURCE_TYPE_VIDEO; - } else if (sourceTypeName == SOURCE_TYPE_NAME_NONE) { - return SOURCE_TYPE_NONE; - } else if (sourceTypeName == SOURCE_TYPE_NAME_FBO) { - return SOURCE_TYPE_FBO; - } else { - std::stringstream ss; - ss << "Invalid source type name: " << sourceTypeName; - ofLogFatalError("SourceType") << ss.str(); - std::exit(EXIT_FAILURE); - } - } - }; - } -} \ No newline at end of file +namespace piMapper { + +class SourceType { + + public: + enum { + SOURCE_TYPE_NONE, SOURCE_TYPE_IMAGE, SOURCE_TYPE_VIDEO, SOURCE_TYPE_FBO + }; + + static std::string GetSourceTypeName(int sourceTypeEnum){ + if(sourceTypeEnum == SOURCE_TYPE_IMAGE){ + return SOURCE_TYPE_NAME_IMAGE; + }else if(sourceTypeEnum == SOURCE_TYPE_VIDEO){ + return SOURCE_TYPE_NAME_VIDEO; + }else if(sourceTypeEnum == SOURCE_TYPE_NONE){ + return SOURCE_TYPE_NAME_NONE; + }else if(sourceTypeEnum == SOURCE_TYPE_FBO){ + return SOURCE_TYPE_NAME_FBO; + }else{ + std::stringstream ss; + ss << "Invalid source type: " << sourceTypeEnum; + ofLogFatalError("SourceType") << ss.str(); + std::exit(EXIT_FAILURE); + } + } + + static int GetSourceTypeEnum(std::string sourceTypeName){ + if(sourceTypeName == SOURCE_TYPE_NAME_IMAGE){ + return SOURCE_TYPE_IMAGE; + }else if(sourceTypeName == SOURCE_TYPE_NAME_VIDEO){ + return SOURCE_TYPE_VIDEO; + }else if(sourceTypeName == SOURCE_TYPE_NAME_NONE){ + return SOURCE_TYPE_NONE; + }else if(sourceTypeName == SOURCE_TYPE_NAME_FBO){ + return SOURCE_TYPE_FBO; + }else{ + std::stringstream ss; + ss << "Invalid source type name: " << sourceTypeName; + ofLogFatalError("SourceType") << ss.str(); + std::exit(EXIT_FAILURE); + } + } + +}; + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Sources/VideoSource.cpp b/src/Sources/VideoSource.cpp index b8ca1de..7b7d460 100644 --- a/src/Sources/VideoSource.cpp +++ b/src/Sources/VideoSource.cpp @@ -1,70 +1,71 @@ #include "VideoSource.h" namespace ofx { - namespace piMapper { - - bool VideoSource::enableAudio = false; - - VideoSource::VideoSource() { - loadable = true; - loaded = false; - type = SourceType::SOURCE_TYPE_VIDEO; -#ifdef TARGET_RASPBERRY_PI - omxPlayer = NULL; -#else - videoPlayer = NULL; -#endif - } - - VideoSource::~VideoSource() {} - - void VideoSource::loadVideo(std::string & filePath) { - path = filePath; - setNameFromPath(filePath); -#ifdef TARGET_RASPBERRY_PI - ofxOMXPlayerSettings settings; - settings.videoPath = filePath; - settings.useHDMIForAudio = true; - settings.enableTexture = true; - settings.enableLooping = true; - settings.enableAudio = VideoSource::enableAudio; - omxPlayer = new ofxOMXPlayer(); - omxPlayer->setup(settings); - texture = &(omxPlayer->getTextureReference()); -#else - videoPlayer = new ofVideoPlayer(); - videoPlayer->load(filePath); - videoPlayer->setLoopState(OF_LOOP_NORMAL); - videoPlayer->setVolume(VideoSource::enableAudio ? 1.0f : 0.0f); - videoPlayer->play(); - texture = &(videoPlayer->getTexture()); - ofAddListener(ofEvents().update, this, &VideoSource::update); -#endif - loaded = true; - } - - void VideoSource::clear() { - texture = NULL; -#ifdef TARGET_RASPBERRY_PI - omxPlayer->close(); - delete omxPlayer; - omxPlayer = NULL; -#else - ofRemoveListener(ofEvents().update, this, &VideoSource::update); - videoPlayer->stop(); - videoPlayer->close(); - delete videoPlayer; - videoPlayer = NULL; -#endif - loaded = false; - } - +namespace piMapper { + +bool VideoSource::enableAudio = false; + +VideoSource::VideoSource(){ + loadable = true; + loaded = false; + type = SourceType::SOURCE_TYPE_VIDEO; + #ifdef TARGET_RASPBERRY_PI + omxPlayer = NULL; + #else + videoPlayer = NULL; + #endif +} + +VideoSource::~VideoSource(){} + +void VideoSource::loadVideo(std::string & filePath){ + path = filePath; + setNameFromPath(filePath); + #ifdef TARGET_RASPBERRY_PI + ofxOMXPlayerSettings settings; + settings.videoPath = filePath; + settings.useHDMIForAudio = true; + settings.enableTexture = true; + settings.enableLooping = true; + settings.enableAudio = VideoSource::enableAudio; + omxPlayer = new ofxOMXPlayer(); + omxPlayer->setup(settings); + texture = &(omxPlayer->getTextureReference()); + #else + videoPlayer = new ofVideoPlayer(); + videoPlayer->load(filePath); + videoPlayer->setLoopState(OF_LOOP_NORMAL); + videoPlayer->setVolume(VideoSource::enableAudio ? 1.0f : 0.0f); + videoPlayer->play(); + texture = &(videoPlayer->getTexture()); + ofAddListener(ofEvents().update, this, &VideoSource::update); + #endif + loaded = true; +} + +void VideoSource::clear(){ + texture = NULL; + #ifdef TARGET_RASPBERRY_PI + omxPlayer->close(); + delete omxPlayer; + omxPlayer = NULL; + #else + ofRemoveListener(ofEvents().update, this, &VideoSource::update); + videoPlayer->stop(); + videoPlayer->close(); + delete videoPlayer; + videoPlayer = NULL; + #endif + loaded = false; +} + #ifndef TARGET_RASPBERRY_PI - void VideoSource::update(ofEventArgs & args) { - if (videoPlayer != NULL) { - videoPlayer->update(); - } - } + void VideoSource::update(ofEventArgs & args){ + if(videoPlayer != NULL){ + videoPlayer->update(); + } + } #endif - } // namespace piMapper + +} // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/Sources/VideoSource.h b/src/Sources/VideoSource.h index 5e14a44..514989e 100644 --- a/src/Sources/VideoSource.h +++ b/src/Sources/VideoSource.h @@ -4,39 +4,42 @@ #include "BaseSource.h" #ifdef TARGET_RASPBERRY_PI - #include "ofxOMXPlayer.h" + #include "ofxOMXPlayer.h" #endif namespace ofx { - namespace piMapper { - class VideoSource : public BaseSource { - public: - - // TODO: Create enableAudio() and disableAudio() methods - // for live audio enabling and disabling. - static bool enableAudio; - - VideoSource(); - ~VideoSource(); - - std::string & getPath(); - void loadVideo(std::string & path); - void clear(); - -#ifndef TARGET_RASPBERRY_PI - void update(ofEventArgs & args); -#endif - - private: +namespace piMapper { -#ifdef TARGET_RASPBERRY_PI - ofxOMXPlayer * omxPlayer; // Naming different for less confusion -#else - // Go with ofVideoPlayer or - // TODO: High Performance Video player on newer Macs - ofVideoPlayer * videoPlayer; -#endif - - }; - } -} \ No newline at end of file +class VideoSource : public BaseSource { + + public: + + // TODO: Create enableAudio() and disableAudio() methods + // for live audio enabling and disabling. + static bool enableAudio; + + VideoSource(); + ~VideoSource(); + + std::string & getPath(); + void loadVideo(std::string & path); + void clear(); + + #ifndef TARGET_RASPBERRY_PI + void update(ofEventArgs & args); + #endif + + private: + + #ifdef TARGET_RASPBERRY_PI + ofxOMXPlayer * omxPlayer; // Naming different for less confusion + #else + // Go with ofVideoPlayer or + // TODO: High Performance Video player on newer Macs + ofVideoPlayer * videoPlayer; + #endif + +}; + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/BaseSurface.cpp b/src/Surfaces/BaseSurface.cpp index 8e835ba..65326d0 100644 --- a/src/Surfaces/BaseSurface.cpp +++ b/src/Surfaces/BaseSurface.cpp @@ -1,94 +1,100 @@ #include "BaseSurface.h" namespace ofx { - namespace piMapper { - - BaseSurface::BaseSurface() { - _moved = false; - ofEnableNormalizedTexCoords(); - createDefaultTexture(); - } - - BaseSurface::~BaseSurface() { - delete defaultSource; - defaultSource = NULL; - defaultTexture.clear(); - } - - void BaseSurface::createDefaultTexture() { - ofPixels pixels; - pixels.allocate(500, 500, 1); - for (int i = 0; i < pixels.size(); i++) { - pixels[i] = 255; - } - int squareSize = 10; // size of each test pattern square - bool sy = false; - for (int y = 0; y < pixels.getWidth(); y += squareSize) { - bool sx = false; - for (int x = 0; x < pixels.getHeight(); x += squareSize) { - for (int yi = 0; yi < squareSize; yi++) { - for (int xi = 0; xi < squareSize; xi++) { - if (sx && sy) - pixels[(y + yi) * pixels.getWidth() + x + xi] = 255; - else if (sx && !sy) - pixels[(y + yi) * pixels.getWidth() + x + xi] = 0; - else if (!sx && sy) - pixels[(y + yi) * pixels.getWidth() + x + xi] = 0; - else - pixels[(y + yi) * pixels.getWidth() + x + xi] = 255; - } - } - sx = !sx; - } - sy = !sy; - } - - // load pixels into texture - defaultTexture.loadData(pixels); - // Create new source to be the default - defaultSource = new BaseSource(&defaultTexture); - source = defaultSource; - } - - void BaseSurface::drawTexture(ofVec2f position) { - if (source->getTexture() == NULL) { - ofLogWarning("BaseSurface") << "Source texture empty. Not drawing."; - return; - } - - ofMesh texMesh; - texMesh.addVertex(position); - texMesh.addVertex(position + ofVec2f(source->getTexture()->getWidth(), 0.0f)); - texMesh.addVertex(position + - ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight())); - texMesh.addVertex(position + ofVec2f(0.0f, source->getTexture()->getHeight())); - texMesh.addTriangle(0, 2, 3); - texMesh.addTriangle(0, 1, 2); - texMesh.addTexCoord(ofVec2f(0.0f, 0.0f)); - texMesh.addTexCoord(ofVec2f(1.0f, 0.0f)); - texMesh.addTexCoord(ofVec2f(1.0f, 1.0f)); - texMesh.addTexCoord(ofVec2f(0.0f, 1.0f)); - source->getTexture()->bind(); - texMesh.draw(); - source->getTexture()->unbind(); - } - - //void BaseSurface::setTexture(ofTexture* texturePtr) { texture = texturePtr; } - void BaseSurface::setSource(BaseSource* newSource) { - source = newSource; - } - - //ofTexture* BaseSurface::getTexture() { return texture; } - BaseSource* BaseSurface::getSource() { - return source; - } - - //ofTexture* BaseSurface::getDefaultTexture() { return &defaultTexture; } - BaseSource* BaseSurface::getDefaultSource() { - return defaultSource; - } - - void BaseSurface::setMoved(bool moved){ _moved = moved; } - bool BaseSurface::getMoved(){ return _moved; } - } -} \ No newline at end of file +namespace piMapper { + +BaseSurface::BaseSurface(){ + _moved = false; + ofEnableNormalizedTexCoords(); + createDefaultTexture(); +} + +BaseSurface::~BaseSurface(){ + delete defaultSource; + defaultSource = NULL; + defaultTexture.clear(); +} + +void BaseSurface::createDefaultTexture(){ + ofPixels pixels; + pixels.allocate(500, 500, 1); + for(int i = 0; i < pixels.size(); i++){ + pixels[i] = 255; + } + int squareSize = 10; // size of each test pattern square + bool sy = false; + for(int y = 0; y < pixels.getWidth(); y += squareSize){ + bool sx = false; + for(int x = 0; x < pixels.getHeight(); x += squareSize){ + for(int yi = 0; yi < squareSize; yi++){ + for(int xi = 0; xi < squareSize; xi++){ + if(sx && sy){ + pixels[(y + yi) * pixels.getWidth() + x + xi] = 255; + }else if(sx && !sy){ + pixels[(y + yi) * pixels.getWidth() + x + xi] = 0; + }else if(!sx && sy){ + pixels[(y + yi) * pixels.getWidth() + x + xi] = 0; + }else{ + pixels[(y + yi) * pixels.getWidth() + x + xi] = 255; + } + } + } + sx = !sx; + } + sy = !sy; + } + + // load pixels into texture + defaultTexture.loadData(pixels); + // Create new source to be the default + defaultSource = new BaseSource(&defaultTexture); + source = defaultSource; +} + +void BaseSurface::drawTexture(ofVec2f position){ + if(source->getTexture() == NULL){ + ofLogWarning("BaseSurface") << "Source texture empty. Not drawing."; + return; + } + + ofMesh texMesh; + texMesh.addVertex(position); + texMesh.addVertex(position + ofVec2f(source->getTexture()->getWidth(), 0.0f)); + texMesh.addVertex(position + + ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight())); + texMesh.addVertex(position + ofVec2f(0.0f, source->getTexture()->getHeight())); + texMesh.addTriangle(0, 2, 3); + texMesh.addTriangle(0, 1, 2); + texMesh.addTexCoord(ofVec2f(0.0f, 0.0f)); + texMesh.addTexCoord(ofVec2f(1.0f, 0.0f)); + texMesh.addTexCoord(ofVec2f(1.0f, 1.0f)); + texMesh.addTexCoord(ofVec2f(0.0f, 1.0f)); + source->getTexture()->bind(); + texMesh.draw(); + source->getTexture()->unbind(); +} + +//void BaseSurface::setTexture(ofTexture* texturePtr) { texture = texturePtr; } +void BaseSurface::setSource(BaseSource * newSource){ + source = newSource; +} + +//ofTexture* BaseSurface::getTexture() { return texture; } +BaseSource * BaseSurface::getSource(){ + return source; +} + +//ofTexture* BaseSurface::getDefaultTexture() { return &defaultTexture; } +BaseSource * BaseSurface::getDefaultSource(){ + return defaultSource; +} + +void BaseSurface::setMoved(bool moved){ + _moved = moved; +} +bool BaseSurface::getMoved(){ + return _moved; +} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/BaseSurface.h b/src/Surfaces/BaseSurface.h index 5f5a151..19d090b 100644 --- a/src/Surfaces/BaseSurface.h +++ b/src/Surfaces/BaseSurface.h @@ -7,38 +7,42 @@ using namespace std; namespace ofx { - namespace piMapper { - class BaseSurface { - public: - BaseSurface(); - ~BaseSurface(); - virtual void setup() {}; - virtual void draw() {}; - virtual void setVertex(int index, ofVec2f p) {}; - virtual void setTexCoord(int index, ofVec2f t) {}; - virtual void moveBy(ofVec2f v) {}; - virtual int getType() {}; - virtual bool hitTest(ofVec2f p) {}; - virtual ofPolyline getHitArea() {}; - virtual ofPolyline getTextureHitArea() {}; - virtual vector& getVertices() {}; - virtual vector& getTexCoords() {}; - - void drawTexture(ofVec2f position); - void setSource(BaseSource* newSource); - BaseSource* getSource(); - BaseSource* getDefaultSource(); - - void setMoved(bool moved); - bool getMoved(); - - protected: - ofMesh mesh; - ofTexture defaultTexture; - BaseSource* source; - BaseSource* defaultSource; - void createDefaultTexture(); - bool _moved; - }; - } -} \ No newline at end of file +namespace piMapper { + +class BaseSurface { + + public: + BaseSurface(); + ~BaseSurface(); + virtual void setup(){} + virtual void draw(){} + virtual void setVertex(int index, ofVec2f p){} + virtual void setTexCoord(int index, ofVec2f t){} + virtual void moveBy(ofVec2f v){} + virtual int getType(){} + virtual bool hitTest(ofVec2f p){} + virtual ofPolyline getHitArea(){} + virtual ofPolyline getTextureHitArea(){} + virtual vector & getVertices(){} + virtual vector & getTexCoords(){} + + void drawTexture(ofVec2f position); + void setSource(BaseSource * newSource); + BaseSource * getSource(); + BaseSource * getDefaultSource(); + + void setMoved(bool moved); + bool getMoved(); + + protected: + ofMesh mesh; + ofTexture defaultTexture; + BaseSource * source; + BaseSource * defaultSource; + void createDefaultTexture(); + bool _moved; + +}; + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/QuadSurface.cpp b/src/Surfaces/QuadSurface.cpp index c61eb10..2de508f 100644 --- a/src/Surfaces/QuadSurface.cpp +++ b/src/Surfaces/QuadSurface.cpp @@ -2,253 +2,261 @@ namespace ofx { namespace piMapper { -QuadSurface::QuadSurface() { - setup(); + +QuadSurface::QuadSurface(){ + setup(); } -QuadSurface::~QuadSurface() { cout << "QuadSurface destructor." << endl; } +QuadSurface::~QuadSurface(){ + cout << "QuadSurface destructor." << endl; +} -void QuadSurface::setup() { - // Create 4 points for the 2 triangles - ofVec2f p1 = ofVec2f(0, 0); - ofVec2f p2 = ofVec2f(0, ofGetHeight()); - ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); - ofVec2f p4 = ofVec2f(ofGetWidth(), 0); +void QuadSurface::setup(){ + // Create 4 points for the 2 triangles + ofVec2f p1 = ofVec2f(0, 0); + ofVec2f p2 = ofVec2f(0, ofGetHeight()); + ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); + ofVec2f p4 = ofVec2f(ofGetWidth(), 0); - // Create 4 point for the texture coordinates - ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 0.0f)); - ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 0.0f)); - ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f)); - ofVec2f t4 = ofVec2f(ofVec2f(0.0f, 1.0f)); + // Create 4 point for the texture coordinates + ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 0.0f)); + ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 0.0f)); + ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f)); + ofVec2f t4 = ofVec2f(ofVec2f(0.0f, 1.0f)); - setup(p1, p2, p3, p4, t1, t2, t3, t4, source); + setup(p1, p2, p3, p4, t1, t2, t3, t4, source); } void QuadSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, - ofVec2f t1, ofVec2f t2, ofVec2f t3, ofVec2f t4, - BaseSource* newSource) { - // Assign texture - source = newSource; - - // Clear mesh - mesh.clear(); - - // Create a surface with the points - mesh.addVertex(p1); - mesh.addVertex(p2); - mesh.addVertex(p3); - mesh.addVertex(p4); - - // Add 2 triangles - mesh.addTriangle(0, 2, 3); - mesh.addTriangle(0, 1, 2); - - // Add texture coordinates - mesh.addTexCoord(t1); - mesh.addTexCoord(t2); - mesh.addTexCoord(t3); - mesh.addTexCoord(t4); - - // Pure GL setup - // indices - quadIndices[0] = 0; - quadIndices[1] = 1; - quadIndices[2] = 2; - quadIndices[3] = 0; - quadIndices[4] = 2; - quadIndices[5] = 3; - // tex coords (those are alway 0) - quadTexCoordinates[2] = 0; - quadTexCoordinates[6] = 0; - quadTexCoordinates[10] = 0; - quadTexCoordinates[14] = 0; - - calculate4dTextureCoords(); -} - -void QuadSurface::draw() { - if (source->getTexture() == NULL) { - ofLogWarning("QuadSurface") << "Source texture empty. Not drawing."; - return; - } - - /*if(mesh.haveVertsChanged() || mesh.haveTexCoordsChanged()){ - calculate4dTextureCoords(); - }*/ - /* - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(4, GL_FLOAT, 0, quadTexCoordinates); - glVertexPointer(3, GL_FLOAT, 0, quadVertices); - - source->getTexture()->bind(); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, quadIndices); - source->getTexture()->unbind(); - */ - - source->getTexture()->bind(); - mesh.draw(); - source->getTexture()->unbind(); -} - -void QuadSurface::setVertex(int index, ofVec2f p) { - if (index > 3) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - return; - } - - mesh.setVertex(index, p); - calculate4dTextureCoords(); -} - -void QuadSurface::setTexCoord(int index, ofVec2f t) { - if (index > 3) { - ofLog() << "Texture coordinate with this index does not exist: " << index - << endl; - return; - } - - mesh.setTexCoord(index, t); - calculate4dTextureCoords(); -} - -void QuadSurface::moveBy(ofVec2f v) { - vector& vertices = getVertices(); - for (int i = 0; i < vertices.size(); i++) { - vertices[i] += v; - } - calculate4dTextureCoords(); - setMoved(true); -} - -int QuadSurface::getType() { return SurfaceType::QUAD_SURFACE; } - -bool QuadSurface::hitTest(ofVec2f p) { - // Construct ofPolyline from vertices - ofPolyline line = getHitArea(); - - if (line.inside(p.x, p.y)) { - return true; - } else { - return false; - } -} - -ofVec2f QuadSurface::getVertex(int index) { - if (index > 3) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - throw std::runtime_error("Vertex index out of bounds."); - } - - ofVec3f vert = mesh.getVertex(index); - return ofVec2f(vert.x, vert.y); -} - -ofVec2f QuadSurface::getTexCoord(int index) { - if (index > 3) { - throw std::runtime_error("Texture coordinate index out of bounds."); - } - - return mesh.getTexCoord(index); -} - -ofPolyline QuadSurface::getHitArea() { - ofPolyline line; - line.addVertex(ofPoint(mesh.getVertex(0).x, mesh.getVertex(0).y)); - line.addVertex(ofPoint(mesh.getVertex(1).x, mesh.getVertex(1).y)); - line.addVertex(ofPoint(mesh.getVertex(2).x, mesh.getVertex(2).y)); - line.addVertex(ofPoint(mesh.getVertex(3).x, mesh.getVertex(3).y)); - line.close(); - - return line; -} - -ofPolyline QuadSurface::getTextureHitArea() { - ofPolyline line; - vector& texCoords = mesh.getTexCoords(); - ofVec2f textureSize = ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight()); - for (int i = 0; i < texCoords.size(); i++) { - line.addVertex(ofPoint(texCoords[i] * textureSize)); - } - line.close(); - - return line; -} - -vector& QuadSurface::getVertices() { - // return only joint vertices - return mesh.getVertices(); -} - -vector& QuadSurface::getTexCoords() { return mesh.getTexCoords(); } - -void QuadSurface::calculate4dTextureCoords() { - // Perspective Warping with OpenGL Fixed Pipeline and q coordinates - // see: - // http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/ - // for information on the technique - // Pue OpenGL is used because the ofMesh sadly doesn't support ofVec4f as - // texture coordinates. - // calculate intersection point - ofVec3f p0 = mesh.getVertex(0); - ofVec3f p1 = mesh.getVertex(1); - ofVec3f p2 = mesh.getVertex(2); - ofVec3f p3 = mesh.getVertex(3); - - ofVec3f t0 = mesh.getTexCoord(0); - ofVec3f t1 = mesh.getTexCoord(1); - ofVec3f t2 = mesh.getTexCoord(2); - ofVec3f t3 = mesh.getTexCoord(3); - - ofPoint interSect; - ofLineSegmentIntersection(ofPoint(p0.x, p0.y), ofPoint(p2.x, p2.y), - ofPoint(p1.x, p1.y), ofPoint(p3.x, p3.y), - interSect); - ofVec3f interSecVec = ofVec3f(interSect.x, interSect.y, 0); - - // calculate distances to intersection point - float d0 = interSecVec.distance(p0); - float d1 = interSecVec.distance(p1); - float d2 = interSecVec.distance(p2); - float d3 = interSecVec.distance(p3); - - // vertices - // top left corner - quadVertices[0] = p0.x; - quadVertices[1] = p0.y; - quadVertices[2] = 0; - // top right corner - quadVertices[3] = p1.x; - quadVertices[4] = p1.y; - quadVertices[5] = 0; - // bottom right corner - quadVertices[6] = p2.x; - quadVertices[7] = p2.y; - quadVertices[8] = 0; - // bottom left corner - quadVertices[9] = p3.x; - quadVertices[10] = p3.y; - quadVertices[11] = 0; - - float q0 = (d0 + d2) / (d2); - float q1 = (d1 + d3) / (d3); - float q2 = (d2 + d0) / (d0); - float q3 = (d3 + d1) / (d1); - - quadTexCoordinates[0] = t0.x; - quadTexCoordinates[1] = t0.y; - quadTexCoordinates[3] = q0; - - quadTexCoordinates[4] = t1.x * q1; - quadTexCoordinates[5] = t1.y; - quadTexCoordinates[7] = q1; - - quadTexCoordinates[8] = t2.x * q2; - quadTexCoordinates[9] = t2.y * q2; - quadTexCoordinates[11] = q2; - - quadTexCoordinates[12] = t3.x; - quadTexCoordinates[13] = t3.y * q3; - quadTexCoordinates[15] = q3; -} -} -} \ No newline at end of file + ofVec2f t1, ofVec2f t2, ofVec2f t3, ofVec2f t4, + BaseSource * newSource){ + // Assign texture + source = newSource; + + // Clear mesh + mesh.clear(); + + // Create a surface with the points + mesh.addVertex(p1); + mesh.addVertex(p2); + mesh.addVertex(p3); + mesh.addVertex(p4); + + // Add 2 triangles + mesh.addTriangle(0, 2, 3); + mesh.addTriangle(0, 1, 2); + + // Add texture coordinates + mesh.addTexCoord(t1); + mesh.addTexCoord(t2); + mesh.addTexCoord(t3); + mesh.addTexCoord(t4); + + // Pure GL setup + // indices + quadIndices[0] = 0; + quadIndices[1] = 1; + quadIndices[2] = 2; + quadIndices[3] = 0; + quadIndices[4] = 2; + quadIndices[5] = 3; + // tex coords (those are alway 0) + quadTexCoordinates[2] = 0; + quadTexCoordinates[6] = 0; + quadTexCoordinates[10] = 0; + quadTexCoordinates[14] = 0; + + calculate4dTextureCoords(); +} + +void QuadSurface::draw(){ + if(source->getTexture() == NULL){ + ofLogWarning("QuadSurface") << "Source texture empty. Not drawing."; + return; + } + + /*if(mesh.haveVertsChanged() || mesh.haveTexCoordsChanged()){ + calculate4dTextureCoords(); + }*/ + /* + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(4, GL_FLOAT, 0, quadTexCoordinates); + glVertexPointer(3, GL_FLOAT, 0, quadVertices); + + source->getTexture()->bind(); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, quadIndices); + source->getTexture()->unbind(); + */ + + source->getTexture()->bind(); + mesh.draw(); + source->getTexture()->unbind(); +} + +void QuadSurface::setVertex(int index, ofVec2f p){ + if(index > 3){ + ofLog() << "Vertex with this index does not exist: " << index << endl; + return; + } + + mesh.setVertex(index, p); + calculate4dTextureCoords(); +} + +void QuadSurface::setTexCoord(int index, ofVec2f t){ + if(index > 3){ + ofLog() << "Texture coordinate with this index does not exist: " << index + << endl; + return; + } + + mesh.setTexCoord(index, t); + calculate4dTextureCoords(); +} + +void QuadSurface::moveBy(ofVec2f v){ + vector & vertices = getVertices(); + for(int i = 0; i < vertices.size(); i++){ + vertices[i] += v; + } + calculate4dTextureCoords(); + setMoved(true); +} + +int QuadSurface::getType(){ + return SurfaceType::QUAD_SURFACE; +} + +bool QuadSurface::hitTest(ofVec2f p){ + // Construct ofPolyline from vertices + ofPolyline line = getHitArea(); + + if(line.inside(p.x, p.y)){ + return true; + }else{ + return false; + } +} + +ofVec2f QuadSurface::getVertex(int index){ + if(index > 3){ + ofLog() << "Vertex with this index does not exist: " << index << endl; + throw std::runtime_error("Vertex index out of bounds."); + } + + ofVec3f vert = mesh.getVertex(index); + return ofVec2f(vert.x, vert.y); +} + +ofVec2f QuadSurface::getTexCoord(int index){ + if(index > 3){ + throw std::runtime_error("Texture coordinate index out of bounds."); + } + + return mesh.getTexCoord(index); +} + +ofPolyline QuadSurface::getHitArea(){ + ofPolyline line; + line.addVertex(ofPoint(mesh.getVertex(0).x, mesh.getVertex(0).y)); + line.addVertex(ofPoint(mesh.getVertex(1).x, mesh.getVertex(1).y)); + line.addVertex(ofPoint(mesh.getVertex(2).x, mesh.getVertex(2).y)); + line.addVertex(ofPoint(mesh.getVertex(3).x, mesh.getVertex(3).y)); + line.close(); + + return line; +} + +ofPolyline QuadSurface::getTextureHitArea(){ + ofPolyline line; + vector & texCoords = mesh.getTexCoords(); + ofVec2f textureSize = ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight()); + for(int i = 0; i < texCoords.size(); i++){ + line.addVertex(ofPoint(texCoords[i] * textureSize)); + } + line.close(); + + return line; +} + +vector & QuadSurface::getVertices(){ + // return only joint vertices + return mesh.getVertices(); +} + +vector & QuadSurface::getTexCoords(){ + return mesh.getTexCoords(); +} + +void QuadSurface::calculate4dTextureCoords(){ + // Perspective Warping with OpenGL Fixed Pipeline and q coordinates + // see: + // http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/ + // for information on the technique + // Pue OpenGL is used because the ofMesh sadly doesn't support ofVec4f as + // texture coordinates. + // calculate intersection point + ofVec3f p0 = mesh.getVertex(0); + ofVec3f p1 = mesh.getVertex(1); + ofVec3f p2 = mesh.getVertex(2); + ofVec3f p3 = mesh.getVertex(3); + + ofVec3f t0 = mesh.getTexCoord(0); + ofVec3f t1 = mesh.getTexCoord(1); + ofVec3f t2 = mesh.getTexCoord(2); + ofVec3f t3 = mesh.getTexCoord(3); + + ofPoint interSect; + ofLineSegmentIntersection(ofPoint(p0.x, p0.y), ofPoint(p2.x, p2.y), + ofPoint(p1.x, p1.y), ofPoint(p3.x, p3.y), + interSect); + ofVec3f interSecVec = ofVec3f(interSect.x, interSect.y, 0); + + // calculate distances to intersection point + float d0 = interSecVec.distance(p0); + float d1 = interSecVec.distance(p1); + float d2 = interSecVec.distance(p2); + float d3 = interSecVec.distance(p3); + + // vertices + // top left corner + quadVertices[0] = p0.x; + quadVertices[1] = p0.y; + quadVertices[2] = 0; + // top right corner + quadVertices[3] = p1.x; + quadVertices[4] = p1.y; + quadVertices[5] = 0; + // bottom right corner + quadVertices[6] = p2.x; + quadVertices[7] = p2.y; + quadVertices[8] = 0; + // bottom left corner + quadVertices[9] = p3.x; + quadVertices[10] = p3.y; + quadVertices[11] = 0; + + float q0 = (d0 + d2) / (d2); + float q1 = (d1 + d3) / (d3); + float q2 = (d2 + d0) / (d0); + float q3 = (d3 + d1) / (d1); + + quadTexCoordinates[0] = t0.x; + quadTexCoordinates[1] = t0.y; + quadTexCoordinates[3] = q0; + + quadTexCoordinates[4] = t1.x * q1; + quadTexCoordinates[5] = t1.y; + quadTexCoordinates[7] = q1; + + quadTexCoordinates[8] = t2.x * q2; + quadTexCoordinates[9] = t2.y * q2; + quadTexCoordinates[11] = q2; + + quadTexCoordinates[12] = t3.x; + quadTexCoordinates[13] = t3.y * q3; + quadTexCoordinates[15] = q3; +} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/QuadSurface.h b/src/Surfaces/QuadSurface.h old mode 100755 new mode 100644 index 6422a6f..b53ac95 --- a/src/Surfaces/QuadSurface.h +++ b/src/Surfaces/QuadSurface.h @@ -6,35 +6,38 @@ namespace ofx { namespace piMapper { + class QuadSurface : public BaseSurface { - public: - QuadSurface(); - ~QuadSurface(); - - void setup(); - - void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, ofVec2f t1, - ofVec2f t2, ofVec2f t3, ofVec2f t4, BaseSource* newSource); - - void draw(); - void setVertex(int index, ofVec2f p); - void setTexCoord(int index, ofVec2f t); - void moveBy(ofVec2f v); - - int getType(); - bool hitTest(ofVec2f p); - ofVec2f getVertex(int index); - ofVec2f getTexCoord(int index); - ofPolyline getHitArea(); - ofPolyline getTextureHitArea(); - vector& getVertices(); - vector& getTexCoords(); - - private: - void calculate4dTextureCoords(); - GLfloat quadVertices[12]; - GLubyte quadIndices[6]; - GLfloat quadTexCoordinates[16]; + public: + QuadSurface(); + ~QuadSurface(); + + void setup(); + + void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, ofVec2f t1, + ofVec2f t2, ofVec2f t3, ofVec2f t4, BaseSource * newSource); + + void draw(); + void setVertex(int index, ofVec2f p); + void setTexCoord(int index, ofVec2f t); + void moveBy(ofVec2f v); + + int getType(); + bool hitTest(ofVec2f p); + ofVec2f getVertex(int index); + ofVec2f getTexCoord(int index); + ofPolyline getHitArea(); + ofPolyline getTextureHitArea(); + vector & getVertices(); + vector & getTexCoords(); + + private: + void calculate4dTextureCoords(); + GLfloat quadVertices[12]; + GLubyte quadIndices[6]; + GLfloat quadTexCoordinates[16]; + }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/SurfaceManager.cpp b/src/Surfaces/SurfaceManager.cpp index 5f0e757..6eae296 100644 --- a/src/Surfaces/SurfaceManager.cpp +++ b/src/Surfaces/SurfaceManager.cpp @@ -2,423 +2,428 @@ namespace ofx { namespace piMapper { - SurfaceManager::SurfaceManager() : - mediaServer(NULL), - selectedSurface(NULL) {} -SurfaceManager::~SurfaceManager() { clear(); } +SurfaceManager::SurfaceManager() : + mediaServer(NULL), + selectedSurface(NULL){} -void SurfaceManager::draw() { - for (int i = 0; i < surfaces.size(); i++) { - ofSetColor(255, 255, 255, 255); - surfaces[i]->draw(); - } +SurfaceManager::~SurfaceManager(){ + clear(); } -void SurfaceManager::addSurface(int surfaceType) { - if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { - surfaces.push_back(new TriangleSurface()); - } else if (surfaceType == SurfaceType::QUAD_SURFACE) { - surfaces.push_back(new QuadSurface()); - } else { - ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; - std::exit(EXIT_FAILURE); - } +void SurfaceManager::draw(){ + for(int i = 0; i < surfaces.size(); i++){ + ofSetColor(255, 255, 255, 255); + surfaces[i]->draw(); + } } -void SurfaceManager::addSurface(int surfaceType, BaseSource* newSource) { - if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { - surfaces.push_back(new TriangleSurface()); - surfaces.back()->setSource(newSource); - } else if (surfaceType == SurfaceType::QUAD_SURFACE) { - surfaces.push_back(new QuadSurface()); - surfaces.back()->setSource(newSource); - } else { - ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; - std::exit(EXIT_FAILURE); - } +void SurfaceManager::addSurface(int surfaceType){ + if(surfaceType == SurfaceType::TRIANGLE_SURFACE){ + surfaces.push_back(new TriangleSurface()); + }else if(surfaceType == SurfaceType::QUAD_SURFACE){ + surfaces.push_back(new QuadSurface()); + }else{ + ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; + std::exit(EXIT_FAILURE); + } } -void SurfaceManager::addSurface(int surfaceType, vector vertices, - vector texCoords) { - if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { - if (vertices.size() < 3) { - throw std::runtime_error( - "There must be 3 vertices for a triangle surface."); - } else if (texCoords.size() < 3) { - throw std::runtime_error( - "There must be 3 texture coordinates for a triangle surface."); - } - - surfaces.push_back(new TriangleSurface()); - - for (int i = 0; i < 3; i++) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - - } else if (surfaceType == SurfaceType::QUAD_SURFACE) { - if (vertices.size() < 4) { - throw std::runtime_error("There must be 4 vertices for a quad surface."); - } else if (texCoords.size() < 4) { - throw std::runtime_error( - "There must be 4 texture coordinates for a quad surface."); - } - - surfaces.push_back(new QuadSurface()); - - for (int i = 0; i < 4; i++) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - } else { - ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; - std::exit(EXIT_FAILURE); - } +void SurfaceManager::addSurface(int surfaceType, BaseSource * newSource){ + if(surfaceType == SurfaceType::TRIANGLE_SURFACE){ + surfaces.push_back(new TriangleSurface()); + surfaces.back()->setSource(newSource); + }else if(surfaceType == SurfaceType::QUAD_SURFACE){ + surfaces.push_back(new QuadSurface()); + surfaces.back()->setSource(newSource); + }else{ + ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; + std::exit(EXIT_FAILURE); + } } -void SurfaceManager::addSurface(int surfaceType, BaseSource* newSource, - vector vertices, - vector texCoords) { - if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { - if (vertices.size() < 3) { - throw std::runtime_error( - "There must be 3 vertices for a triangle surface."); - } else if (texCoords.size() < 3) { - throw std::runtime_error( - "Thre must be 3 texture coordinates for a triangle surface."); - } - - surfaces.push_back(new TriangleSurface()); - surfaces.back()->setSource(newSource); - - for (int i = 0; i < 3; i++) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - - } else if (surfaceType == SurfaceType::QUAD_SURFACE) { - if (vertices.size() < 4) { - throw std::runtime_error("There must be 4 vertices for a quad surface."); - } else if (texCoords.size() < 4) { - throw std::runtime_error( - "Thre must be 4 texture coordinates for a quad surface."); - } - - surfaces.push_back(new QuadSurface()); - surfaces.back()->setSource(newSource); - - for (int i = 0; i < 4; i++) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - } else { - ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; - std::exit(EXIT_FAILURE); - } +void SurfaceManager::addSurface(int surfaceType, vector vertices, + vector texCoords){ + if(surfaceType == SurfaceType::TRIANGLE_SURFACE){ + if(vertices.size() < 3){ + throw std::runtime_error( + "There must be 3 vertices for a triangle surface."); + }else if(texCoords.size() < 3){ + throw std::runtime_error( + "There must be 3 texture coordinates for a triangle surface."); + } + + surfaces.push_back(new TriangleSurface()); + + for(int i = 0; i < 3; i++){ + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + + }else if(surfaceType == SurfaceType::QUAD_SURFACE){ + if(vertices.size() < 4){ + throw std::runtime_error("There must be 4 vertices for a quad surface."); + }else if(texCoords.size() < 4){ + throw std::runtime_error( + "There must be 4 texture coordinates for a quad surface."); + } + + surfaces.push_back(new QuadSurface()); + + for(int i = 0; i < 4; i++){ + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + }else{ + ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; + std::exit(EXIT_FAILURE); + } +} + +void SurfaceManager::addSurface(int surfaceType, BaseSource * newSource, + vector vertices, + vector texCoords){ + if(surfaceType == SurfaceType::TRIANGLE_SURFACE){ + if(vertices.size() < 3){ + throw std::runtime_error( + "There must be 3 vertices for a triangle surface."); + }else if(texCoords.size() < 3){ + throw std::runtime_error( + "Thre must be 3 texture coordinates for a triangle surface."); + } + + surfaces.push_back(new TriangleSurface()); + surfaces.back()->setSource(newSource); + + for(int i = 0; i < 3; i++){ + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + + }else if(surfaceType == SurfaceType::QUAD_SURFACE){ + if(vertices.size() < 4){ + throw std::runtime_error("There must be 4 vertices for a quad surface."); + }else if(texCoords.size() < 4){ + throw std::runtime_error( + "Thre must be 4 texture coordinates for a quad surface."); + } + + surfaces.push_back(new QuadSurface()); + surfaces.back()->setSource(newSource); + + for(int i = 0; i < 4; i++){ + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + }else{ + ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type"; + std::exit(EXIT_FAILURE); + } } // Add existing surface void SurfaceManager::addSurface(BaseSurface * surface){ - surfaces.push_back(surface); + surfaces.push_back(surface); } void SurfaceManager::removeSelectedSurface(){ - if (selectedSurface == NULL){ - return; - } - for (int i = 0; i < surfaces.size(); i++){ - if (surfaces[i] == selectedSurface){ - // Do not delete pointer as we are storing the - // surface in the RemoveSurfaceCommand. - //delete surfaces[i]; - surfaces.erase(surfaces.begin() + i); - selectedSurface = NULL; - break; - } - } + if(selectedSurface == NULL){ + return; + } + for(int i = 0; i < surfaces.size(); i++){ + if(surfaces[i] == selectedSurface){ + // Do not delete pointer as we are storing the + // surface in the RemoveSurfaceCommand. + //delete surfaces[i]; + surfaces.erase(surfaces.begin() + i); + selectedSurface = NULL; + break; + } + } } -void SurfaceManager::removeSurface() { - if (!surfaces.size()) { - return; - } - delete surfaces.back(); - surfaces.pop_back(); +void SurfaceManager::removeSurface(){ + if(!surfaces.size()){ + return; + } + delete surfaces.back(); + surfaces.pop_back(); } -void SurfaceManager::clear() { - // delete all extra allocations from the heap - while (surfaces.size()) { - delete surfaces.back(); - surfaces.pop_back(); - } +void SurfaceManager::clear(){ + // delete all extra allocations from the heap + while(surfaces.size()){ + delete surfaces.back(); + surfaces.pop_back(); + } } -void SurfaceManager::saveXmlSettings(string fileName) { - // Exit if mediaServer not set - if (mediaServer == NULL) { - ofLogFatalError("SurfaceManager") << "Media server not set"; - std::exit(EXIT_FAILURE); - } - // We need a fresh copy of the xml settings object - xmlSettings.clear(); - // Save surfaces - xmlSettings.addTag("surfaces"); - xmlSettings.pushTag("surfaces"); - for (int i = 0; i < surfaces.size(); i++) { - xmlSettings.addTag("surface"); - xmlSettings.pushTag("surface", i); - BaseSurface* surface = surfaces[i]; - - xmlSettings.addTag("vertices"); - xmlSettings.pushTag("vertices"); - vector* 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* texCoords = &surface->getTexCoords(); - for (int j = 0; j < texCoords->size(); j++) { - xmlSettings.addTag("texCoord"); - xmlSettings.pushTag("texCoord", j); - ofVec2f* 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 = SourceType::GetSourceTypeName(surface->getSource()->getType()); - cout << "sourceTypeName: " << sourceTypeName << endl; - xmlSettings.addValue("source-type", sourceTypeName); - xmlSettings.addValue("source-name", surface->getSource()->getName()); - xmlSettings.popTag(); // source - xmlSettings.popTag(); // surface - } - xmlSettings.popTag(); // surfaces - xmlSettings.save(fileName); +void SurfaceManager::saveXmlSettings(string fileName){ + // Exit if mediaServer not set + if(mediaServer == NULL){ + ofLogFatalError("SurfaceManager") << "Media server not set"; + std::exit(EXIT_FAILURE); + } + // We need a fresh copy of the xml settings object + xmlSettings.clear(); + // Save surfaces + xmlSettings.addTag("surfaces"); + xmlSettings.pushTag("surfaces"); + for(int i = 0; i < surfaces.size(); i++){ + xmlSettings.addTag("surface"); + xmlSettings.pushTag("surface", i); + BaseSurface * surface = surfaces[i]; + + xmlSettings.addTag("vertices"); + xmlSettings.pushTag("vertices"); + vector * 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 * texCoords = &surface->getTexCoords(); + for(int j = 0; j < texCoords->size(); j++){ + xmlSettings.addTag("texCoord"); + xmlSettings.pushTag("texCoord", j); + ofVec2f * 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 = SourceType::GetSourceTypeName(surface->getSource()->getType()); + cout << "sourceTypeName: " << sourceTypeName << endl; + xmlSettings.addValue("source-type", sourceTypeName); + xmlSettings.addValue("source-name", surface->getSource()->getName()); + xmlSettings.popTag(); // source + xmlSettings.popTag(); // surface + } + xmlSettings.popTag(); // surfaces + xmlSettings.save(fileName); } -void SurfaceManager::loadXmlSettings(string fileName) { - // Exit if there is no media server - if (mediaServer == NULL) { - ofLogFatalError("SurfaceManager") << "Media server not set"; - std::exit(EXIT_FAILURE); - } - if (!xmlSettings.loadFile(fileName)) { - ofLogWarning("SurfaceManager") << "Could not load XML settings"; - return; - } - if (!xmlSettings.tagExists("surfaces")) { - ofLogWarning("SurfaceManager") << "XML settings is empty or has wrong markup"; - return; - } - - xmlSettings.pushTag("surfaces"); - - int numSurfaces = xmlSettings.getNumTags("surface"); - for (int i = 0; i < numSurfaces; i++) { - xmlSettings.pushTag("surface", i); - // attempt to load surface source - xmlSettings.pushTag("source"); - string sourceType = xmlSettings.getValue("source-type", ""); - string sourceName = xmlSettings.getValue("source-name", ""); - BaseSource* source = NULL; - if (sourceName != "" && sourceName != "none" && sourceType != "") { - // Load source depending on type - int typeEnum = SourceType::GetSourceTypeEnum(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); - std::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 - xmlSettings.pushTag("vertices"); - vector vertices; - int vertexCount = xmlSettings.getNumTags("vertex"); - // it's a triangle ? - if (vertexCount == 3) { - //ofLog(OF_LOG_NOTICE, "create Triangle"); - xmlSettings.pushTag("vertex", 0); - vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 1); - vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 2); - vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 100.0f))); - xmlSettings.popTag(); - - xmlSettings.popTag(); // vertices - - xmlSettings.pushTag("texCoords"); - - vector texCoords; - - xmlSettings.pushTag("texCoord", 0); - texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 1); - texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 2); - texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 1.0f))); - xmlSettings.popTag(); - - xmlSettings.popTag(); // texCoords - - // now we have variables sourceName and sourceTexture - // by checking those we can use one or another addSurface method - if (sourceName != "none" && source != NULL) { - addSurface(SurfaceType::TRIANGLE_SURFACE, source, vertices, - texCoords); - } else { - addSurface(SurfaceType::TRIANGLE_SURFACE, vertices, texCoords); - } - } - // it's a quad ? - else if (vertexCount == 4) - // if (surface-type == QUAD_SURFACE) - { - xmlSettings.pushTag("vertex", 0); - vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 1); - vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 2); - vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), - xmlSettings.getValue("y", 100.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 3); - vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 100.0f))); - xmlSettings.popTag(); - - xmlSettings.popTag(); // vertices - - xmlSettings.pushTag("texCoords"); - - vector texCoords; - - xmlSettings.pushTag("texCoord", 0); - texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 1); - texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), - xmlSettings.getValue("y", 0.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 2); - texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), - xmlSettings.getValue("y", 1.0f))); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 3); - texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), - xmlSettings.getValue("y", 1.0f))); - xmlSettings.popTag(); - - xmlSettings.popTag(); // texCoords - - // now we have variables sourceName and sourceTexture - // by checking those we can use one or another addSurface method - if (sourceName != "none" && source != NULL) { - addSurface(SurfaceType::QUAD_SURFACE, source, vertices, - texCoords); - } else { - addSurface(SurfaceType::QUAD_SURFACE, vertices, texCoords); - } - } - - xmlSettings.popTag(); // surface - } - - xmlSettings.popTag(); // surfaces +void SurfaceManager::loadXmlSettings(string fileName){ + // Exit if there is no media server + if(mediaServer == NULL){ + ofLogFatalError("SurfaceManager") << "Media server not set"; + std::exit(EXIT_FAILURE); + } + if(!xmlSettings.loadFile(fileName)){ + ofLogWarning("SurfaceManager") << "Could not load XML settings"; + return; + } + if(!xmlSettings.tagExists("surfaces")){ + ofLogWarning("SurfaceManager") << "XML settings is empty or has wrong markup"; + return; + } + + xmlSettings.pushTag("surfaces"); + + int numSurfaces = xmlSettings.getNumTags("surface"); + for(int i = 0; i < numSurfaces; i++){ + xmlSettings.pushTag("surface", i); + // attempt to load surface source + xmlSettings.pushTag("source"); + string sourceType = xmlSettings.getValue("source-type", ""); + string sourceName = xmlSettings.getValue("source-name", ""); + BaseSource * source = NULL; + if(sourceName != "" && sourceName != "none" && sourceType != ""){ + // Load source depending on type + int typeEnum = SourceType::GetSourceTypeEnum(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); + std::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 + xmlSettings.pushTag("vertices"); + vector vertices; + int vertexCount = xmlSettings.getNumTags("vertex"); + // it's a triangle ? + if(vertexCount == 3){ + //ofLog(OF_LOG_NOTICE, "create Triangle"); + xmlSettings.pushTag("vertex", 0); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 1); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 2); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 100.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // vertices + + xmlSettings.pushTag("texCoords"); + + vector texCoords; + + xmlSettings.pushTag("texCoord", 0); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 1); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 2); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 1.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // texCoords + + // now we have variables sourceName and sourceTexture + // by checking those we can use one or another addSurface method + if(sourceName != "none" && source != NULL){ + addSurface(SurfaceType::TRIANGLE_SURFACE, source, vertices, + texCoords); + }else{ + addSurface(SurfaceType::TRIANGLE_SURFACE, vertices, texCoords); + } + } + // it's a quad ? + else if(vertexCount == 4){ + // if (surface-type == QUAD_SURFACE) + xmlSettings.pushTag("vertex", 0); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 1); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 2); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), + xmlSettings.getValue("y", 100.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 3); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 100.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // vertices + + xmlSettings.pushTag("texCoords"); + + vector texCoords; + + xmlSettings.pushTag("texCoord", 0); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 1); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 2); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), + xmlSettings.getValue("y", 1.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 3); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 1.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // texCoords + + // now we have variables sourceName and sourceTexture + // by checking those we can use one or another addSurface method + if(sourceName != "none" && source != NULL){ + addSurface(SurfaceType::QUAD_SURFACE, source, vertices, + texCoords); + }else{ + addSurface(SurfaceType::QUAD_SURFACE, vertices, texCoords); + } + } + + xmlSettings.popTag(); // surface + } + + xmlSettings.popTag(); // surfaces } - - void SurfaceManager::setMediaServer(MediaServer* newMediaServer) { - mediaServer = newMediaServer; - } - - BaseSurface * SurfaceManager::selectSurface(int index) { - if (index >= surfaces.size()) { - throw std::runtime_error("Surface index out of bounds."); - } - selectedSurface = surfaces[index]; - - // notify that a new surface has been selected - ofSendMessage("surfaceSelected"); - return selectedSurface; - } - - BaseSurface * SurfaceManager::selectSurface(BaseSurface * surface){ - for (int i = 0; i < surfaces.size(); i++) { - if (surfaces[i] == surface){ - selectedSurface = surface; - ofSendMessage("surfaceSelected"); - return selectedSurface; - } - } - deselectSurface(); - return 0; - } - -BaseSurface* SurfaceManager::getSelectedSurface() { - return selectedSurface; + +void SurfaceManager::setMediaServer(MediaServer * newMediaServer){ + mediaServer = newMediaServer; +} + +BaseSurface * SurfaceManager::selectSurface(int index){ + if(index >= surfaces.size()){ + throw std::runtime_error("Surface index out of bounds."); + } + selectedSurface = surfaces[index]; + + // notify that a new surface has been selected + ofSendMessage("surfaceSelected"); + return selectedSurface; } -void SurfaceManager::deselectSurface() { - selectedSurface = NULL; +BaseSurface * SurfaceManager::selectSurface(BaseSurface * surface){ + for(int i = 0; i < surfaces.size(); i++){ + if(surfaces[i] == surface){ + selectedSurface = surface; + ofSendMessage("surfaceSelected"); + return selectedSurface; + } + } + deselectSurface(); + return 0; } -BaseSurface* SurfaceManager::getSurface(int index) { - if (index >= surfaces.size()) { - throw std::runtime_error("Surface index out of bounds."); - return NULL; - } +BaseSurface * SurfaceManager::getSelectedSurface(){ + return selectedSurface; +} - return surfaces[index]; +void SurfaceManager::deselectSurface(){ + selectedSurface = NULL; } -int SurfaceManager::size() { return surfaces.size(); } +BaseSurface * SurfaceManager::getSurface(int index){ + if(index >= surfaces.size()){ + throw std::runtime_error("Surface index out of bounds."); + return NULL; + } + + return surfaces[index]; } + +int SurfaceManager::size(){ + return surfaces.size(); } + +} // namespace piMapper +} // namespace ofx diff --git a/src/Surfaces/SurfaceManager.h b/src/Surfaces/SurfaceManager.h old mode 100755 new mode 100644 index 5e026b4..405ebb2 --- a/src/Surfaces/SurfaceManager.h +++ b/src/Surfaces/SurfaceManager.h @@ -15,44 +15,48 @@ using namespace std; namespace ofx { namespace piMapper { + class SurfaceManager { - public: - SurfaceManager(); - ~SurfaceManager(); - - void draw(); - - // TODO: These should be renamed to createSurface - void addSurface(int surfaceType); - void addSurface(int surfaceType, BaseSource* newSource); - void addSurface(int surfaceType, vector vertices, - vector texCoords); - void addSurface(int surfaceType, BaseSource* newSource, - vector vertices, vector texCoords); - - // Except this, as it adds existing surface - void addSurface(BaseSurface * surface); - - void removeSelectedSurface(); - void removeSurface(); - - void clear(); - void saveXmlSettings(string fileName); - void loadXmlSettings(string fileName); - void setMediaServer(MediaServer* newMediaServer); - - BaseSurface* getSurface(int index); - int size(); - BaseSurface* selectSurface(int index); - BaseSurface* selectSurface(BaseSurface * surface); - BaseSurface* getSelectedSurface(); - void deselectSurface(); - - private: - std::vector surfaces; - BaseSurface* selectedSurface; - ofxXmlSettings xmlSettings; - MediaServer* mediaServer; + + public: + SurfaceManager(); + ~SurfaceManager(); + + void draw(); + + // TODO: These should be renamed to createSurface + void addSurface(int surfaceType); + void addSurface(int surfaceType, BaseSource * newSource); + void addSurface(int surfaceType, vector vertices, + vector texCoords); + void addSurface(int surfaceType, BaseSource * newSource, + vector vertices, vector texCoords); + + // Except this, as it adds existing surface + void addSurface(BaseSurface * surface); + + void removeSelectedSurface(); + void removeSurface(); + + void clear(); + void saveXmlSettings(string fileName); + void loadXmlSettings(string fileName); + void setMediaServer(MediaServer * newMediaServer); + + BaseSurface * getSurface(int index); + int size(); + BaseSurface * selectSurface(int index); + BaseSurface * selectSurface(BaseSurface * surface); + BaseSurface * getSelectedSurface(); + void deselectSurface(); + + private: + std::vector surfaces; + BaseSurface * selectedSurface; + ofxXmlSettings xmlSettings; + MediaServer * mediaServer; + }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/SurfaceManagerGui.cpp b/src/Surfaces/SurfaceManagerGui.cpp index f65fd52..ab08d6c 100644 --- a/src/Surfaces/SurfaceManagerGui.cpp +++ b/src/Surfaces/SurfaceManagerGui.cpp @@ -1,311 +1,322 @@ #include "SurfaceManagerGui.h" namespace ofx { - namespace piMapper { - SurfaceManagerGui::SurfaceManagerGui() { - surfaceManager = NULL; - guiMode = GuiMode::NONE; - bDrag = false; - registerMouseEvents(); - ofHideCursor(); - _cmdManager = 0; - } - - SurfaceManagerGui::~SurfaceManagerGui() { - unregisterMouseEvents(); - surfaceManager = NULL; - _cmdManager = 0; - } - - void SurfaceManagerGui::registerMouseEvents() { - ofAddListener(ofEvents().mousePressed, this, - &SurfaceManagerGui::mousePressed); - ofAddListener(ofEvents().mouseReleased, this, - &SurfaceManagerGui::mouseReleased); - ofAddListener(ofEvents().mouseDragged, this, - &SurfaceManagerGui::mouseDragged); - } - - void SurfaceManagerGui::unregisterMouseEvents() { - ofRemoveListener(ofEvents().mousePressed, this, - &SurfaceManagerGui::mousePressed); - ofRemoveListener(ofEvents().mouseReleased, this, - &SurfaceManagerGui::mouseReleased); - ofRemoveListener(ofEvents().mouseDragged, this, - &SurfaceManagerGui::mouseDragged); - } - - void SurfaceManagerGui::draw() { - if (surfaceManager == NULL) return; - - if (guiMode == GuiMode::NONE) { - surfaceManager->draw(); - } else if (guiMode == GuiMode::TEXTURE_MAPPING) { - // draw the texture of the selected surface - if (surfaceManager->getSelectedSurface() != NULL) { - // Reset default color to white first - ofSetColor(255, 255, 255, 255); - surfaceManager->getSelectedSurface()->drawTexture(ofVec2f(0, 0)); - } - - // draw surfaces with opacity - ofPushStyle(); - ofSetColor(255, 255, 255, 200); - surfaceManager->draw(); - ofPopStyle(); - - // highlight selected surface - drawSelectedSurfaceHighlight(); - - // hilight selected surface texture - drawSelectedSurfaceTextureHighlight(); - - // draw texture editing GUI on top - textureEditor.draw(); - - } else if (guiMode == GuiMode::PROJECTION_MAPPING) { - // draw projection surfaces first - surfaceManager->draw(); - - // highlight selected surface - drawSelectedSurfaceHighlight(); - - // draw projection mapping editing gui - projectionEditor.draw(); - - } else if (guiMode == GuiMode::SOURCE_SELECTION) { - // draw projection surfaces first - surfaceManager->draw(); - - // highlight selected surface - drawSelectedSurfaceHighlight(); - - sourcesEditor.draw(); - } - } - - void SurfaceManagerGui::mousePressed(ofMouseEventArgs& args) { - if (guiMode == GuiMode::NONE) { - return; - } else if (guiMode == GuiMode::TEXTURE_MAPPING) { - bool bSurfaceSelected = false; - CircleJoint* hitJoint = - textureEditor.hitTestJoints(ofVec2f(args.x, args.y)); - if (hitJoint != NULL) { - textureEditor.unselectAllJoints(); - - hitJoint->select(); - hitJoint->startDrag(); - bSurfaceSelected = true; - - int jointIndex = -1; - for (int i = 0; i < textureEditor.getJoints().size(); i++) { - if (textureEditor.getJoints()[i] == hitJoint) { - jointIndex = i; - break; - } - } - - if (jointIndex != -1) { - _cmdManager->exec(new MvTexCoordCmd(jointIndex, &textureEditor)); - } - - } else { - textureEditor.unselectAllJoints(); - } - - if (surfaceManager->getSelectedSurface() != NULL && !bSurfaceSelected) { - // hittest texture area to see if we are hitting the texture surface - if (surfaceManager->getSelectedSurface()->getTextureHitArea().inside( - args.x, args.y)) { - - // TODO: move these to a separate routine - clickPosition = ofVec2f(args.x, args.y); - startDrag(); - - _cmdManager->exec(new MvAllTexCoordsCmd( - surfaceManager->getSelectedSurface(), - &textureEditor)); - - } - } - - } else if (guiMode == GuiMode::PROJECTION_MAPPING) { - bool bSurfaceSelected = false; - - CircleJoint* hitJoint = - projectionEditor.hitTestJoints(ofVec2f(args.x, args.y)); - if (hitJoint != NULL) { - projectionEditor.unselectAllJoints(); - hitJoint->select(); - hitJoint->startDrag(); - int jointVertIndex = 0; - for (int i = 0; i < projectionEditor.getJoints()->size(); i++) { - if ((*projectionEditor.getJoints())[i] == hitJoint) { - jointVertIndex = i; - break; - } - } - _cmdManager->exec(new MvSurfaceVertCmd( - jointVertIndex, - surfaceManager->getSelectedSurface(), - &projectionEditor)); - bSurfaceSelected = true; - } - - // attempt to select surface, loop from end to beginning - if (!bSurfaceSelected) { - for (int i = surfaceManager->size() - 1; i >= 0; i--) { - if (surfaceManager->getSurface(i)->hitTest(ofVec2f(args.x, args.y))) { - - // Do not repeat this command if attempting to select an - // already selected surface. - if (surfaceManager->getSelectedSurface() != surfaceManager->getSurface(i)){ - _cmdManager->exec(new SelSurfaceCmd( - surfaceManager, - surfaceManager->getSurface(i), - &projectionEditor)); - } - - bSurfaceSelected = true; - break; - } - } - } - - if (bSurfaceSelected && hitJoint == NULL) { - - // if not hitting the joints, start drag only if - // we have a selected surface - clickPosition = ofVec2f(args.x, args.y); - startDrag(); - - _cmdManager->exec( - new MvSurfaceCmd( - surfaceManager->getSelectedSurface(), - &projectionEditor)); - } - - if (!bSurfaceSelected) { - // unselect if no surface selected - projectionEditor.clearJoints(); - surfaceManager->deselectSurface(); - } - } else if (guiMode == GuiMode::SOURCE_SELECTION) { - } - } - - void SurfaceManagerGui::mouseReleased(ofMouseEventArgs& args) { - stopDrag(); - projectionEditor.stopDragJoints(); - textureEditor.stopDragJoints(); - - // Check if surface has moved - if (surfaceManager->getSelectedSurface()){ - if (!surfaceManager->getSelectedSurface()->getMoved()) { - _cmdManager->undo(); - } - } - - } - - void SurfaceManagerGui::mouseDragged(ofMouseEventArgs& args) { - if (bDrag) { - ofVec2f mousePosition = ofVec2f(args.x, args.y); - ofVec2f distance = mousePosition - clickPosition; - - if (guiMode == GuiMode::PROJECTION_MAPPING) { - // add this distance to all vertices in surface - projectionEditor.moveSelectedSurface(distance); - } else if (guiMode == GuiMode::TEXTURE_MAPPING) { - textureEditor.moveTexCoords(distance); - } - clickPosition = mousePosition; - } - } - - void SurfaceManagerGui::setSurfaceManager(SurfaceManager* newSurfaceManager) { - surfaceManager = newSurfaceManager; - projectionEditor.setSurfaceManager(surfaceManager); - sourcesEditor.setSurfaceManager(surfaceManager); - } - - // Set external media server so we can access it from wherever we need - void SurfaceManagerGui::setMediaServer(MediaServer* newMediaServer) { - mediaServer = newMediaServer; - // Set the media server of the sources editor here - sourcesEditor.setMediaServer(mediaServer); - } - - void SurfaceManagerGui::setCmdManager(CmdManager * cmdManager){ - _cmdManager = cmdManager; - sourcesEditor.setCmdManager(_cmdManager); - } - - void SurfaceManagerGui::setMode(int newGuiMode) { - if (newGuiMode != GuiMode::NONE && newGuiMode != GuiMode::TEXTURE_MAPPING && - newGuiMode != GuiMode::PROJECTION_MAPPING && - newGuiMode != GuiMode::SOURCE_SELECTION) { - throw std::runtime_error("Trying to set invalid mode."); - } - - if (newGuiMode == GuiMode::NONE) { - ofHideCursor(); - } else { - ofShowCursor(); - } - - guiMode = newGuiMode; - - if (guiMode == GuiMode::SOURCE_SELECTION) { - sourcesEditor.enable(); - //string sourceName = surfaceManager->getSelectedSurfaceSourceName(); - //sourcesEditor.selectImageSourceRadioButton(sourceName); - } else { - sourcesEditor.disable(); - } - - if (guiMode == GuiMode::TEXTURE_MAPPING) { - textureEditor.enable(); - // refresh texture editor surface reference - textureEditor.setSurface(surfaceManager->getSelectedSurface()); - } else { - textureEditor.disable(); - } - - if (guiMode == GuiMode::PROJECTION_MAPPING) { - projectionEditor.enable(); - } else { - projectionEditor.disable(); - } - } - - int SurfaceManagerGui::getMode(){ - return guiMode; - } - - void SurfaceManagerGui::drawSelectedSurfaceHighlight() { - if (surfaceManager->getSelectedSurface() == NULL) return; - ofPolyline line = surfaceManager->getSelectedSurface()->getHitArea(); - ofPushStyle(); - ofSetLineWidth(1); - ofSetColor(255, 255, 255, 255); - line.draw(); - ofPopStyle(); - } - - void SurfaceManagerGui::drawSelectedSurfaceTextureHighlight() { - if (surfaceManager->getSelectedSurface() == NULL) return; - ofPolyline line = surfaceManager->getSelectedSurface()->getTextureHitArea(); - ofPushStyle(); - ofSetLineWidth(1); - ofSetColor(255, 255, 0, 255); - line.draw(); - ofPopStyle(); - } - - void SurfaceManagerGui::startDrag() { bDrag = true; } - - void SurfaceManagerGui::stopDrag() { bDrag = false; } - } -} \ No newline at end of file +namespace piMapper { + +SurfaceManagerGui::SurfaceManagerGui(){ + surfaceManager = NULL; + guiMode = GuiMode::NONE; + bDrag = false; + registerMouseEvents(); + ofHideCursor(); + _cmdManager = 0; +} + +SurfaceManagerGui::~SurfaceManagerGui(){ + unregisterMouseEvents(); + surfaceManager = NULL; + _cmdManager = 0; +} + +void SurfaceManagerGui::registerMouseEvents(){ + ofAddListener(ofEvents().mousePressed, this, + &SurfaceManagerGui::mousePressed); + ofAddListener(ofEvents().mouseReleased, this, + &SurfaceManagerGui::mouseReleased); + ofAddListener(ofEvents().mouseDragged, this, + &SurfaceManagerGui::mouseDragged); +} + +void SurfaceManagerGui::unregisterMouseEvents(){ + ofRemoveListener(ofEvents().mousePressed, this, + &SurfaceManagerGui::mousePressed); + ofRemoveListener(ofEvents().mouseReleased, this, + &SurfaceManagerGui::mouseReleased); + ofRemoveListener(ofEvents().mouseDragged, this, + &SurfaceManagerGui::mouseDragged); +} + +void SurfaceManagerGui::draw(){ + if(surfaceManager == NULL){ + return; + } + + if(guiMode == GuiMode::NONE){ + surfaceManager->draw(); + }else if(guiMode == GuiMode::TEXTURE_MAPPING){ + // draw the texture of the selected surface + if(surfaceManager->getSelectedSurface() != NULL){ + // Reset default color to white first + ofSetColor(255, 255, 255, 255); + surfaceManager->getSelectedSurface()->drawTexture(ofVec2f(0, 0)); + } + + // draw surfaces with opacity + ofPushStyle(); + ofSetColor(255, 255, 255, 200); + surfaceManager->draw(); + ofPopStyle(); + + // highlight selected surface + drawSelectedSurfaceHighlight(); + + // hilight selected surface texture + drawSelectedSurfaceTextureHighlight(); + + // draw texture editing GUI on top + textureEditor.draw(); + + }else if(guiMode == GuiMode::PROJECTION_MAPPING){ + // draw projection surfaces first + surfaceManager->draw(); + + // highlight selected surface + drawSelectedSurfaceHighlight(); + + // draw projection mapping editing gui + projectionEditor.draw(); + + }else if(guiMode == GuiMode::SOURCE_SELECTION){ + // draw projection surfaces first + surfaceManager->draw(); + + // highlight selected surface + drawSelectedSurfaceHighlight(); + + sourcesEditor.draw(); + } +} + +void SurfaceManagerGui::mousePressed(ofMouseEventArgs & args){ + if(guiMode == GuiMode::NONE){ + return; + }else if(guiMode == GuiMode::TEXTURE_MAPPING){ + bool bSurfaceSelected = false; + CircleJoint * hitJoint = + textureEditor.hitTestJoints(ofVec2f(args.x, args.y)); + if(hitJoint != NULL){ + textureEditor.unselectAllJoints(); + + hitJoint->select(); + hitJoint->startDrag(); + bSurfaceSelected = true; + + int jointIndex = -1; + for(int i = 0; i < textureEditor.getJoints().size(); i++){ + if(textureEditor.getJoints()[i] == hitJoint){ + jointIndex = i; + break; + } + } + + if(jointIndex != -1){ + _cmdManager->exec(new MvTexCoordCmd(jointIndex, &textureEditor)); + } + + }else{ + textureEditor.unselectAllJoints(); + } + + if(surfaceManager->getSelectedSurface() != NULL && !bSurfaceSelected){ + // hittest texture area to see if we are hitting the texture surface + if(surfaceManager->getSelectedSurface()->getTextureHitArea().inside( + args.x, args.y)){ + + // TODO: move these to a separate routine + clickPosition = ofVec2f(args.x, args.y); + startDrag(); + + _cmdManager->exec(new MvAllTexCoordsCmd( + surfaceManager->getSelectedSurface(), + &textureEditor)); + + } + } + + }else if(guiMode == GuiMode::PROJECTION_MAPPING){ + bool bSurfaceSelected = false; + + CircleJoint * hitJoint = + projectionEditor.hitTestJoints(ofVec2f(args.x, args.y)); + if(hitJoint != NULL){ + projectionEditor.unselectAllJoints(); + hitJoint->select(); + hitJoint->startDrag(); + int jointVertIndex = 0; + for(int i = 0; i < projectionEditor.getJoints()->size(); i++){ + if((*projectionEditor.getJoints())[i] == hitJoint){ + jointVertIndex = i; + break; + } + } + _cmdManager->exec(new MvSurfaceVertCmd( + jointVertIndex, + surfaceManager->getSelectedSurface(), + &projectionEditor)); + bSurfaceSelected = true; + } + + // attempt to select surface, loop from end to beginning + if(!bSurfaceSelected){ + for(int i = surfaceManager->size() - 1; i >= 0; i--){ + if(surfaceManager->getSurface(i)->hitTest(ofVec2f(args.x, args.y))){ + + // Do not repeat this command if attempting to select an + // already selected surface. + if(surfaceManager->getSelectedSurface() != surfaceManager->getSurface(i)){ + _cmdManager->exec(new SelSurfaceCmd( + surfaceManager, + surfaceManager->getSurface(i), + &projectionEditor)); + } + + bSurfaceSelected = true; + break; + } + } + } + + if(bSurfaceSelected && hitJoint == NULL){ + + // if not hitting the joints, start drag only if + // we have a selected surface + clickPosition = ofVec2f(args.x, args.y); + startDrag(); + + _cmdManager->exec( + new MvSurfaceCmd( + surfaceManager->getSelectedSurface(), + &projectionEditor)); + } + + if(!bSurfaceSelected){ + // unselect if no surface selected + projectionEditor.clearJoints(); + surfaceManager->deselectSurface(); + } + }else if(guiMode == GuiMode::SOURCE_SELECTION){} +} + +void SurfaceManagerGui::mouseReleased(ofMouseEventArgs & args){ + stopDrag(); + projectionEditor.stopDragJoints(); + textureEditor.stopDragJoints(); + + // Check if surface has moved + if(surfaceManager->getSelectedSurface()){ + if(!surfaceManager->getSelectedSurface()->getMoved()){ + _cmdManager->undo(); + } + } + +} + +void SurfaceManagerGui::mouseDragged(ofMouseEventArgs & args){ + if(bDrag){ + ofVec2f mousePosition = ofVec2f(args.x, args.y); + ofVec2f distance = mousePosition - clickPosition; + + if(guiMode == GuiMode::PROJECTION_MAPPING){ + // add this distance to all vertices in surface + projectionEditor.moveSelectedSurface(distance); + }else if(guiMode == GuiMode::TEXTURE_MAPPING){ + textureEditor.moveTexCoords(distance); + } + clickPosition = mousePosition; + } +} + +void SurfaceManagerGui::setSurfaceManager(SurfaceManager * newSurfaceManager){ + surfaceManager = newSurfaceManager; + projectionEditor.setSurfaceManager(surfaceManager); + sourcesEditor.setSurfaceManager(surfaceManager); +} + +// Set external media server so we can access it from wherever we need +void SurfaceManagerGui::setMediaServer(MediaServer * newMediaServer){ + mediaServer = newMediaServer; + // Set the media server of the sources editor here + sourcesEditor.setMediaServer(mediaServer); +} + +void SurfaceManagerGui::setCmdManager(CmdManager * cmdManager){ + _cmdManager = cmdManager; + sourcesEditor.setCmdManager(_cmdManager); +} + +void SurfaceManagerGui::setMode(int newGuiMode){ + if(newGuiMode != GuiMode::NONE && newGuiMode != GuiMode::TEXTURE_MAPPING && + newGuiMode != GuiMode::PROJECTION_MAPPING && + newGuiMode != GuiMode::SOURCE_SELECTION){ + throw std::runtime_error("Trying to set invalid mode."); + } + + if(newGuiMode == GuiMode::NONE){ + ofHideCursor(); + }else{ + ofShowCursor(); + } + + guiMode = newGuiMode; + + if(guiMode == GuiMode::SOURCE_SELECTION){ + sourcesEditor.enable(); + //string sourceName = surfaceManager->getSelectedSurfaceSourceName(); + //sourcesEditor.selectImageSourceRadioButton(sourceName); + }else{ + sourcesEditor.disable(); + } + + if(guiMode == GuiMode::TEXTURE_MAPPING){ + textureEditor.enable(); + // refresh texture editor surface reference + textureEditor.setSurface(surfaceManager->getSelectedSurface()); + }else{ + textureEditor.disable(); + } + + if(guiMode == GuiMode::PROJECTION_MAPPING){ + projectionEditor.enable(); + }else{ + projectionEditor.disable(); + } +} + +int SurfaceManagerGui::getMode(){ + return guiMode; +} + +void SurfaceManagerGui::drawSelectedSurfaceHighlight(){ + if(surfaceManager->getSelectedSurface() == NULL){ + return; + } + ofPolyline line = surfaceManager->getSelectedSurface()->getHitArea(); + ofPushStyle(); + ofSetLineWidth(1); + ofSetColor(255, 255, 255, 255); + line.draw(); + ofPopStyle(); +} + +void SurfaceManagerGui::drawSelectedSurfaceTextureHighlight(){ + if(surfaceManager->getSelectedSurface() == NULL){ + return; + } + ofPolyline line = surfaceManager->getSelectedSurface()->getTextureHitArea(); + ofPushStyle(); + ofSetLineWidth(1); + ofSetColor(255, 255, 0, 255); + line.draw(); + ofPopStyle(); +} + +void SurfaceManagerGui::startDrag(){ + bDrag = true; +} + +void SurfaceManagerGui::stopDrag(){ + bDrag = false; +} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/SurfaceManagerGui.h b/src/Surfaces/SurfaceManagerGui.h index 2204428..e650b04 100644 --- a/src/Surfaces/SurfaceManagerGui.h +++ b/src/Surfaces/SurfaceManagerGui.h @@ -18,41 +18,45 @@ #include "MvTexCoordCmd.h" namespace ofx { - namespace piMapper { - class SurfaceManagerGui { - public: - SurfaceManagerGui(); - ~SurfaceManagerGui(); - - void registerMouseEvents(); - void unregisterMouseEvents(); - - void draw(); - void mousePressed(ofMouseEventArgs& args); - void mouseReleased(ofMouseEventArgs& args); - void mouseDragged(ofMouseEventArgs& args); - - void setSurfaceManager(SurfaceManager* newSurfaceManager); - void setMediaServer(MediaServer* newMediaServer); - void setCmdManager(CmdManager * cmdManager); - - void setMode(int newGuiMode); - int getMode(); - void drawSelectedSurfaceHighlight(); - void drawSelectedSurfaceTextureHighlight(); - void startDrag(); - void stopDrag(); - - private: - SurfaceManager* surfaceManager; - MediaServer* mediaServer; - TextureEditor textureEditor; - ProjectionEditor projectionEditor; - SourcesEditor sourcesEditor; - int guiMode; - bool bDrag; - ofVec2f clickPosition; - CmdManager * _cmdManager; - }; - } -} \ No newline at end of file +namespace piMapper { + +class SurfaceManagerGui { + + public: + SurfaceManagerGui(); + ~SurfaceManagerGui(); + + void registerMouseEvents(); + void unregisterMouseEvents(); + + void draw(); + void mousePressed(ofMouseEventArgs & args); + void mouseReleased(ofMouseEventArgs & args); + void mouseDragged(ofMouseEventArgs & args); + + void setSurfaceManager(SurfaceManager * newSurfaceManager); + void setMediaServer(MediaServer * newMediaServer); + void setCmdManager(CmdManager * cmdManager); + + void setMode(int newGuiMode); + int getMode(); + void drawSelectedSurfaceHighlight(); + void drawSelectedSurfaceTextureHighlight(); + void startDrag(); + void stopDrag(); + + private: + SurfaceManager * surfaceManager; + MediaServer * mediaServer; + TextureEditor textureEditor; + ProjectionEditor projectionEditor; + SourcesEditor sourcesEditor; + int guiMode; + bool bDrag; + ofVec2f clickPosition; + CmdManager * _cmdManager; + +}; + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/SurfaceType.h b/src/Surfaces/SurfaceType.h old mode 100755 new mode 100644 index e00e875..d46f6e9 --- a/src/Surfaces/SurfaceType.h +++ b/src/Surfaces/SurfaceType.h @@ -1,9 +1,13 @@ #pragma once namespace ofx { - namespace piMapper { - struct SurfaceType { - enum { TRIANGLE_SURFACE, QUAD_SURFACE }; - }; - } -} \ No newline at end of file +namespace piMapper { + +struct SurfaceType { + enum { + TRIANGLE_SURFACE, QUAD_SURFACE + }; +}; + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/TriangleSurface.cpp b/src/Surfaces/TriangleSurface.cpp index a5bbcec..7eb20ac 100644 --- a/src/Surfaces/TriangleSurface.cpp +++ b/src/Surfaces/TriangleSurface.cpp @@ -2,141 +2,147 @@ namespace ofx { namespace piMapper { -TriangleSurface::TriangleSurface() { - setup(); + +TriangleSurface::TriangleSurface(){ + setup(); } -TriangleSurface::~TriangleSurface() {} +TriangleSurface::~TriangleSurface(){} -void TriangleSurface::setup() { - // Create 3 points for the triangle - ofVec2f p1 = ofVec2f(ofGetWidth() / 2.0f, 0); - ofVec2f p2 = ofVec2f(ofVec2f(0, ofGetHeight())); - ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); +void TriangleSurface::setup(){ + // Create 3 points for the triangle + ofVec2f p1 = ofVec2f(ofGetWidth() / 2.0f, 0); + ofVec2f p2 = ofVec2f(ofVec2f(0, ofGetHeight())); + ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); - // Create 3 point for the texture coordinates - ofVec2f t1 = ofVec2f(0.5f, 0); - ofVec2f t2 = ofVec2f(0, 1.0f); - ofVec2f t3 = ofVec2f(1, 1.0f); + // Create 3 point for the texture coordinates + ofVec2f t1 = ofVec2f(0.5f, 0); + ofVec2f t2 = ofVec2f(0, 1.0f); + ofVec2f t3 = ofVec2f(1, 1.0f); - setup(p1, p2, p3, t1, t2, t3, source); + setup(p1, p2, p3, t1, t2, t3, source); } void TriangleSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, - ofVec2f t2, ofVec2f t3, BaseSource* newSource) { - // Assign texture - source = newSource; - - // Clear mesh - mesh.clear(); - - // Create a surface with the points - mesh.addVertex(p1); - mesh.addVertex(p2); - mesh.addVertex(p3); - - // Add texture coordinates - mesh.addTexCoord(t1); - mesh.addTexCoord(t2); - mesh.addTexCoord(t3); + ofVec2f t2, ofVec2f t3, BaseSource * newSource){ + // Assign texture + source = newSource; + + // Clear mesh + mesh.clear(); + + // Create a surface with the points + mesh.addVertex(p1); + mesh.addVertex(p2); + mesh.addVertex(p3); + + // Add texture coordinates + mesh.addTexCoord(t1); + mesh.addTexCoord(t2); + mesh.addTexCoord(t3); } -void TriangleSurface::draw() { - if (source->getTexture() == NULL) { - ofLogWarning("TriangleSurface") << "Source texture is empty. Not drawing."; - return; - } - - source->getTexture()->bind(); - mesh.draw(); - source->getTexture()->unbind(); +void TriangleSurface::draw(){ + if(source->getTexture() == NULL){ + ofLogWarning("TriangleSurface") << "Source texture is empty. Not drawing."; + return; + } + + source->getTexture()->bind(); + mesh.draw(); + source->getTexture()->unbind(); } -void TriangleSurface::setVertex(int index, ofVec2f p) { - if (index > 2) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - return; - } +void TriangleSurface::setVertex(int index, ofVec2f p){ + if(index > 2){ + ofLog() << "Vertex with this index does not exist: " << index << endl; + return; + } - mesh.setVertex(index, p); + mesh.setVertex(index, p); } -void TriangleSurface::setTexCoord(int index, ofVec2f t) { - if (index > 2) { - ofLog() << "Texture coordinate with this index does not exist: " << index - << endl; - return; - } +void TriangleSurface::setTexCoord(int index, ofVec2f t){ + if(index > 2){ + ofLog() << "Texture coordinate with this index does not exist: " << index + << endl; + return; + } - mesh.setTexCoord(index, t); + mesh.setTexCoord(index, t); } -void TriangleSurface::moveBy(ofVec2f v) { - vector& vertices = getVertices(); - for (int i = 0; i < vertices.size(); i++) { - vertices[i] += v; - } - setMoved(true); +void TriangleSurface::moveBy(ofVec2f v){ + vector & vertices = getVertices(); + for(int i = 0; i < vertices.size(); i++){ + vertices[i] += v; + } + setMoved(true); } -int TriangleSurface::getType() { return SurfaceType::TRIANGLE_SURFACE; } +int TriangleSurface::getType(){ + return SurfaceType::TRIANGLE_SURFACE; +} -bool TriangleSurface::hitTest(ofVec2f p) { - // Construct ofPolyline from vertices - ofPolyline line = getHitArea(); +bool TriangleSurface::hitTest(ofVec2f p){ + // Construct ofPolyline from vertices + ofPolyline line = getHitArea(); - if (line.inside(p.x, p.y)) { - return true; - } else { - return false; - } + if(line.inside(p.x, p.y)){ + return true; + }else{ + return false; + } } -ofVec2f TriangleSurface::getVertex(int index) { - if (index > 2) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - throw std::runtime_error("Vertex index out of bounds."); - } +ofVec2f TriangleSurface::getVertex(int index){ + if(index > 2){ + ofLog() << "Vertex with this index does not exist: " << index << endl; + throw std::runtime_error("Vertex index out of bounds."); + } - ofVec3f vert = mesh.getVertex(index); - return ofVec2f(vert.x, vert.y); + ofVec3f vert = mesh.getVertex(index); + return ofVec2f(vert.x, vert.y); } -ofVec2f TriangleSurface::getTexCoord(int index) { - if (index > 2) { - throw std::runtime_error("Texture coordinate index out of bounds."); - } +ofVec2f TriangleSurface::getTexCoord(int index){ + if(index > 2){ + throw std::runtime_error("Texture coordinate index out of bounds."); + } - return mesh.getTexCoord(index); + return mesh.getTexCoord(index); } -ofPolyline TriangleSurface::getHitArea() { - ofPolyline line; - line.addVertex(ofPoint(mesh.getVertex(0).x, mesh.getVertex(0).y)); - line.addVertex(ofPoint(mesh.getVertex(1).x, mesh.getVertex(1).y)); - line.addVertex(ofPoint(mesh.getVertex(2).x, mesh.getVertex(2).y)); - line.close(); +ofPolyline TriangleSurface::getHitArea(){ + ofPolyline line; + line.addVertex(ofPoint(mesh.getVertex(0).x, mesh.getVertex(0).y)); + line.addVertex(ofPoint(mesh.getVertex(1).x, mesh.getVertex(1).y)); + line.addVertex(ofPoint(mesh.getVertex(2).x, mesh.getVertex(2).y)); + line.close(); - return line; + return line; } -ofPolyline TriangleSurface::getTextureHitArea() { - ofPolyline line; - vector& texCoords = mesh.getTexCoords(); - ofVec2f textureSize = ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight()); - for (int i = 0; i < texCoords.size(); i++) { - line.addVertex(ofPoint(texCoords[i] * textureSize)); - } - line.close(); +ofPolyline TriangleSurface::getTextureHitArea(){ + ofPolyline line; + vector & texCoords = mesh.getTexCoords(); + ofVec2f textureSize = ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight()); + for(int i = 0; i < texCoords.size(); i++){ + line.addVertex(ofPoint(texCoords[i] * textureSize)); + } + line.close(); - return line; + return line; } -vector& TriangleSurface::getVertices() { - // return only joint vertices - return mesh.getVertices(); +vector & TriangleSurface::getVertices(){ + // return only joint vertices + return mesh.getVertices(); } -vector& TriangleSurface::getTexCoords() { return mesh.getTexCoords(); } +vector & TriangleSurface::getTexCoords(){ + return mesh.getTexCoords(); } -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/Surfaces/TriangleSurface.h b/src/Surfaces/TriangleSurface.h index 073719b..9edfcf4 100644 --- a/src/Surfaces/TriangleSurface.h +++ b/src/Surfaces/TriangleSurface.h @@ -6,27 +6,29 @@ namespace ofx { namespace piMapper { + class TriangleSurface : public BaseSurface { - public: - TriangleSurface(); - ~TriangleSurface(); + public: + TriangleSurface(); + ~TriangleSurface(); - void setup(); - void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, ofVec2f t2, - ofVec2f t3, BaseSource* newSource); - void draw(); - void setVertex(int index, ofVec2f p); - void setTexCoord(int index, ofVec2f t); - void moveBy(ofVec2f v); + void setup(); + void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, ofVec2f t2, + ofVec2f t3, BaseSource * newSource); + void draw(); + void setVertex(int index, ofVec2f p); + void setTexCoord(int index, ofVec2f t); + void moveBy(ofVec2f v); - int getType(); - bool hitTest(ofVec2f p); - ofVec2f getVertex(int index); - ofVec2f getTexCoord(int index); - ofPolyline getHitArea(); - ofPolyline getTextureHitArea(); - vector& getVertices(); - vector& getTexCoords(); + int getType(); + bool hitTest(ofVec2f p); + ofVec2f getVertex(int index); + ofVec2f getTexCoord(int index); + ofPolyline getHitArea(); + ofPolyline getTextureHitArea(); + vector & getVertices(); + vector & getTexCoords(); }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/BaseJoint.cpp b/src/UserInterface/BaseJoint.cpp index 37b96b2..2788d7a 100644 --- a/src/UserInterface/BaseJoint.cpp +++ b/src/UserInterface/BaseJoint.cpp @@ -3,70 +3,89 @@ namespace ofx { namespace piMapper { -BaseJoint::BaseJoint() { - setDefaultColors(); - setDefaultProperties(); - registerMouseEvents(); +BaseJoint::BaseJoint(){ + setDefaultColors(); + setDefaultProperties(); + registerMouseEvents(); } -BaseJoint::~BaseJoint() { unregisterMouseEvents(); } - -void BaseJoint::registerMouseEvents() { - ofAddListener(ofEvents().mousePressed, this, &BaseJoint::mousePressed); - ofAddListener(ofEvents().mouseDragged, this, &BaseJoint::mouseDragged); +BaseJoint::~BaseJoint(){ + unregisterMouseEvents(); } -void BaseJoint::unregisterMouseEvents() { - ofRemoveListener(ofEvents().mousePressed, this, &BaseJoint::mousePressed); - ofRemoveListener(ofEvents().mouseDragged, this, &BaseJoint::mouseDragged); +void BaseJoint::registerMouseEvents(){ + ofAddListener(ofEvents().mousePressed, this, &BaseJoint::mousePressed); + ofAddListener(ofEvents().mouseDragged, this, &BaseJoint::mouseDragged); } -void BaseJoint::mousePressed(ofMouseEventArgs& args) { - if (hitTest(ofVec2f(args.x, args.y))) { - // selected = true; - clickDistance = position - ofVec2f(args.x, args.y); - // startDrag(); - } +void BaseJoint::unregisterMouseEvents(){ + ofRemoveListener(ofEvents().mousePressed, this, &BaseJoint::mousePressed); + ofRemoveListener(ofEvents().mouseDragged, this, &BaseJoint::mouseDragged); } -void BaseJoint::mouseReleased(int x, int y, int button) { stopDrag(); } +void BaseJoint::mousePressed(ofMouseEventArgs & args){ + if(hitTest(ofVec2f(args.x, args.y))){ + // selected = true; + clickDistance = position - ofVec2f(args.x, args.y); + // startDrag(); + } +} -void BaseJoint::mouseDragged(ofMouseEventArgs& args) { - if (!bDrag) return; - position = ofVec2f(args.x, args.y) + clickDistance; +void BaseJoint::mouseReleased(int x, int y, int button){ + stopDrag(); } -void BaseJoint::startDrag() { bDrag = true; } +void BaseJoint::mouseDragged(ofMouseEventArgs & args){ + if(!bDrag){ + return; + } + position = ofVec2f(args.x, args.y) + clickDistance; +} -void BaseJoint::stopDrag() { bDrag = false; } +void BaseJoint::startDrag(){ + bDrag = true; +} -void BaseJoint::select() { selected = true; } +void BaseJoint::stopDrag(){ + bDrag = false; +} -void BaseJoint::unselect() { selected = false; } +void BaseJoint::select(){ + selected = true; +} -void BaseJoint::setClickDistance(ofVec2f newClickDistance) { - clickDistance = newClickDistance; +void BaseJoint::unselect(){ + selected = false; } -bool BaseJoint::isDragged() { return bDrag; } +void BaseJoint::setClickDistance(ofVec2f newClickDistance){ + clickDistance = newClickDistance; +} -bool BaseJoint::isSelected() { return selected; } +bool BaseJoint::isDragged(){ + return bDrag; +} -void BaseJoint::setDefaultColors() { - fillColor = ofColor(0, 255, 255, 0); - strokeColor = ofColor(255, 255, 255); - fillColorSelected = ofColor(255, 255, 0, 0); - strokeColorSelected = ofColor(255, 0, 0); +bool BaseJoint::isSelected(){ + return selected; } -void BaseJoint::setDefaultProperties() { - enabled = true; - visible = true; - position = ofVec2f(20.0f, 20.0f); - clickDistance = ofVec2f(0.0f, 0.0f); - bDrag = false; - selected = false; - strokeWidth = 1.5f; +void BaseJoint::setDefaultColors(){ + fillColor = ofColor(0, 255, 255, 0); + strokeColor = ofColor(255, 255, 255); + fillColorSelected = ofColor(255, 255, 0, 0); + strokeColorSelected = ofColor(255, 0, 0); } + +void BaseJoint::setDefaultProperties(){ + enabled = true; + visible = true; + position = ofVec2f(20.0f, 20.0f); + clickDistance = ofVec2f(0.0f, 0.0f); + bDrag = false; + selected = false; + strokeWidth = 1.5f; } -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/BaseJoint.h b/src/UserInterface/BaseJoint.h index d2fdcf0..4d65166 100644 --- a/src/UserInterface/BaseJoint.h +++ b/src/UserInterface/BaseJoint.h @@ -6,46 +6,49 @@ namespace ofx { namespace piMapper { class BaseJoint { - public: - BaseJoint(); - ~BaseJoint(); - - void registerMouseEvents(); - void unregisterMouseEvents(); - - ofVec2f position; - bool enabled; - bool visible; - bool selected; - - void mousePressed(ofMouseEventArgs& args); - void mouseReleased(int x, int y, int button); - void mouseDragged(ofMouseEventArgs& args); - void startDrag(); - void stopDrag(); - void select(); - void unselect(); - void setClickDistance(ofVec2f newClickDistance); - bool isDragged(); - bool isSelected(); - - virtual void update() {}; - virtual void draw() {}; - virtual bool hitTest(ofVec2f position) {}; - - protected: - ofColor fillColor; - ofColor strokeColor; - ofColor fillColorSelected; - ofColor strokeColorSelected; - float strokeWidth; - ofVec2f clickDistance; // How far from the center of the joint the user has - // clicked? - bool bDrag; - - private: - void setDefaultColors(); - void setDefaultProperties(); + + public: + BaseJoint(); + ~BaseJoint(); + + void registerMouseEvents(); + void unregisterMouseEvents(); + + ofVec2f position; + bool enabled; + bool visible; + bool selected; + + void mousePressed(ofMouseEventArgs & args); + void mouseReleased(int x, int y, int button); + void mouseDragged(ofMouseEventArgs & args); + void startDrag(); + void stopDrag(); + void select(); + void unselect(); + void setClickDistance(ofVec2f newClickDistance); + bool isDragged(); + bool isSelected(); + + virtual void update(){} + virtual void draw(){} + virtual bool hitTest(ofVec2f position){} + + protected: + ofColor fillColor; + ofColor strokeColor; + ofColor fillColorSelected; + ofColor strokeColorSelected; + float strokeWidth; + ofVec2f clickDistance; // How far from the center of the joint the user has + // clicked? + bool bDrag; + + private: + void setDefaultColors(); + void setDefaultProperties(); + }; -} -} + +} // namespace piMapper +} // namespace ofx diff --git a/src/UserInterface/CircleJoint.cpp b/src/UserInterface/CircleJoint.cpp index 1e3bb3d..05a841f 100644 --- a/src/UserInterface/CircleJoint.cpp +++ b/src/UserInterface/CircleJoint.cpp @@ -3,47 +3,59 @@ namespace ofx { namespace piMapper { -CircleJoint::CircleJoint() { setDefaultProperties(); } - -void CircleJoint::update() { - if (!enabled) return; +CircleJoint::CircleJoint(){ + setDefaultProperties(); } -void CircleJoint::draw() { - if (!visible) return; - if (!enabled) return; - - ofPushStyle(); - ofFill(); - - if (selected) { - ofSetColor(fillColorSelected); - } else { - ofSetColor(fillColor); - } - - ofCircle(position.x, position.y, radius); - ofNoFill(); - - if (selected) { - ofSetColor(strokeColorSelected); - } else { - ofSetColor(strokeColor); - } - - ofSetLineWidth(strokeWidth); - ofCircle(position.x, position.y, radius); - ofPopStyle(); +void CircleJoint::update(){ + if(!enabled){ + return; + } } -void CircleJoint::setDefaultProperties() { radius = 10.0f; } +void CircleJoint::draw(){ + if(!visible){ + return; + } + if(!enabled){ + return; + } + + ofPushStyle(); + ofFill(); + + if(selected){ + ofSetColor(fillColorSelected); + }else{ + ofSetColor(fillColor); + } + + ofCircle(position.x, position.y, radius); + ofNoFill(); + + if(selected){ + ofSetColor(strokeColorSelected); + }else{ + ofSetColor(strokeColor); + } + + ofSetLineWidth(strokeWidth); + ofCircle(position.x, position.y, radius); + ofPopStyle(); +} -bool CircleJoint::hitTest(ofVec2f pos) { - float distance = position.distance(pos); - if (distance < radius) - return true; - else - return false; +void CircleJoint::setDefaultProperties(){ + radius = 10.0f; } + +bool CircleJoint::hitTest(ofVec2f pos){ + float distance = position.distance(pos); + if(distance < radius){ + return true; + }else{ + return false; + } } -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/CircleJoint.h b/src/UserInterface/CircleJoint.h index ade616f..9b4ef2b 100644 --- a/src/UserInterface/CircleJoint.h +++ b/src/UserInterface/CircleJoint.h @@ -6,17 +6,20 @@ namespace ofx { namespace piMapper { class CircleJoint : public BaseJoint { - public: - CircleJoint(); - void update(); - void draw(); - bool hitTest(ofVec2f position); + public: + CircleJoint(); - private: - float radius; + void update(); + void draw(); + bool hitTest(ofVec2f position); + + private: + float radius; + + void setDefaultProperties(); - void setDefaultProperties(); }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/EditorType.h b/src/UserInterface/EditorType.h index b7fdc14..71f2053 100644 --- a/src/UserInterface/EditorType.h +++ b/src/UserInterface/EditorType.h @@ -2,8 +2,12 @@ namespace ofx { namespace piMapper { + struct EditorType { - enum { TEXTURE, PROJECTION }; + enum { + TEXTURE, PROJECTION + }; }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/GuiMode.h b/src/UserInterface/GuiMode.h index f6b1ac4..926eeb6 100644 --- a/src/UserInterface/GuiMode.h +++ b/src/UserInterface/GuiMode.h @@ -2,8 +2,12 @@ namespace ofx { namespace piMapper { + struct GuiMode { - enum { NONE, TEXTURE_MAPPING, PROJECTION_MAPPING, SOURCE_SELECTION }; + enum { + NONE, TEXTURE_MAPPING, PROJECTION_MAPPING, SOURCE_SELECTION + }; }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/ProjectionEditor.cpp b/src/UserInterface/ProjectionEditor.cpp index f62d8bf..fea1fc7 100644 --- a/src/UserInterface/ProjectionEditor.cpp +++ b/src/UserInterface/ProjectionEditor.cpp @@ -1,270 +1,289 @@ #include "ProjectionEditor.h" namespace ofx { - namespace piMapper { - ProjectionEditor::ProjectionEditor() { - surfaceManager = NULL; - bShiftKeyDown = false; - fSnapDistance = 10.0f; - enable(); - } - - ProjectionEditor::~ProjectionEditor() { - clearJoints(); - surfaceManager = NULL; - disable(); - } - - void ProjectionEditor::registerAppEvents() { - ofAddListener(ofEvents().update, this, &ProjectionEditor::update); - ofAddListener(ofEvents().messageEvent, this, &ProjectionEditor::gotMessage); - } - - void ProjectionEditor::unregisterAppEvents() { - ofRemoveListener(ofEvents().update, this, &ProjectionEditor::update); - ofRemoveListener(ofEvents().messageEvent, this, - &ProjectionEditor::gotMessage); - } - - void ProjectionEditor::registerMouseEvents() { - ofAddListener(ofEvents().mouseDragged, this, &ProjectionEditor::mouseDragged); - } - - void ProjectionEditor::unregisterMouseEvents() { - ofRemoveListener(ofEvents().mouseDragged, this, - &ProjectionEditor::mouseDragged); - } - - void ProjectionEditor::registerKeyEvents() { - ofAddListener(ofEvents().keyPressed, this, &ProjectionEditor::keyPressed); - ofAddListener(ofEvents().keyReleased, this, &ProjectionEditor::keyReleased); - } - - void ProjectionEditor::unregisterKeyEvents() { - ofRemoveListener(ofEvents().keyPressed, this, &ProjectionEditor::keyPressed); - ofRemoveListener(ofEvents().keyReleased, this, - &ProjectionEditor::keyReleased); - } - - void ProjectionEditor::enable() { - registerAppEvents(); - registerMouseEvents(); - registerKeyEvents(); - } - - void ProjectionEditor::disable() { - unregisterAppEvents(); - unregisterMouseEvents(); - unregisterKeyEvents(); - } - - void ProjectionEditor::update(ofEventArgs& args) { - // update surface if one of the joints is being dragged - for (int i = 0; i < joints.size(); i++) { - if (joints[i]->isDragged() || joints[i]->isSelected()) { - if (surfaceManager->getSelectedSurface() != NULL) { - // update vertex to new location - surfaceManager->getSelectedSurface()->setVertex(i, joints[i]->position); - } else { - // clear joints if there is no surface selected - // as the remove selected surface in the surface manager - // is not supposed to access joints here - joints.clear(); - } - break; - } - } - } - - void ProjectionEditor::draw() { - if (surfaceManager == NULL) return; - if (surfaceManager->getSelectedSurface() == NULL) return; - if (joints.size() <= 0) createJoints(); - drawJoints(); - } - - void ProjectionEditor::mouseDragged(ofMouseEventArgs& args) { - ofVec2f mousePosition = ofVec2f(args.x, args.y); - - // Collect all vertices of the projection surfaces - vector allVertices; - for (int i = 0; i < surfaceManager->size(); i++) { - BaseSurface* surface = surfaceManager->getSurface(i); - if (surface == surfaceManager->getSelectedSurface()) { - continue; // Don't add vertices of selected surface - } - for (int j = 0; j < surface->getVertices().size(); j++) { - allVertices.push_back(&surface->getVertices()[j]); - } - } - - // Snap currently dragged joint to nearest vertex - for (int i = 0; i < joints.size(); i++) { - if (joints[i]->isDragged()) { - // Snap it! - for (int j = 0; j < allVertices.size(); j++) { - float distance = mousePosition.distance(*allVertices[j]); - // cout << "distance: " << distance << endl; - if (distance < fSnapDistance) { - joints[i]->position = *allVertices[j]; - ofVec2f clickDistance = joints[i]->position - ofVec2f(args.x, args.y); - joints[i]->setClickDistance(clickDistance); - break; - } - } - } - } - } - - void ProjectionEditor::keyPressed(ofKeyEventArgs& args) { - int key = args.key; - float moveStep; - - if (bShiftKeyDown) - moveStep = 10.0f; - else - moveStep = 0.5f; - - switch (key) { - case OF_KEY_LEFT: - moveSelection(ofVec2f(-moveStep, 0.0f)); - break; - case OF_KEY_RIGHT: - moveSelection(ofVec2f(moveStep, 0.0f)); - break; - case OF_KEY_UP: - moveSelection(ofVec2f(0.0f, -moveStep)); - break; - case OF_KEY_DOWN: - moveSelection(ofVec2f(0.0f, moveStep)); - break; - case OF_KEY_SHIFT: - bShiftKeyDown = true; - break; - } - } - - void ProjectionEditor::keyReleased(ofKeyEventArgs& args) { - int key = args.key; - switch (key) { - case OF_KEY_SHIFT: - bShiftKeyDown = false; - break; - } - } - - void ProjectionEditor::gotMessage(ofMessage& msg) { - if (msg.message == "surfaceSelected") { - // refresh gui - clearJoints(); - createJoints(); - } - } - - void ProjectionEditor::setSurfaceManager(SurfaceManager* newSurfaceManager) { - surfaceManager = newSurfaceManager; - } - - void ProjectionEditor::clearJoints() { - while (joints.size()) { - delete joints.back(); - joints.pop_back(); - } - } - - void ProjectionEditor::createJoints() { - if (surfaceManager == NULL) return; - clearJoints(); - - if (surfaceManager->getSelectedSurface() == NULL) { - ofLog(OF_LOG_WARNING, "Trying to create joints while no surface selected."); - return; - } - - vector& vertices = - surfaceManager->getSelectedSurface()->getVertices(); - - for (int i = 0; i < vertices.size(); i++) { - joints.push_back(new CircleJoint()); - joints.back()->position = ofVec2f(vertices[i].x, vertices[i].y); - } - } - - void ProjectionEditor::updateJoints() { - if (surfaceManager->getSelectedSurface()) { - vector& vertices = - surfaceManager->getSelectedSurface()->getVertices(); - for (int i = 0; i < vertices.size(); i++) { - joints[i]->position = ofVec2f(vertices[i].x, vertices[i].y); - } - } - - } - - void ProjectionEditor::unselectAllJoints() { - for (int i = 0; i < joints.size(); i++) { - joints[i]->unselect(); - } - } - - void ProjectionEditor::moveSelectedSurface(ofVec2f by) { - if (surfaceManager == NULL) return; - if (surfaceManager->getSelectedSurface() == NULL) return; - surfaceManager->getSelectedSurface()->moveBy(by); - /*vector& vertices = - surfaceManager->getSelectedSurface()->getVertices(); - for (int i=0; istopDrag(); - } - } - - void ProjectionEditor::moveSelection(ofVec2f by) { - // check if joints selected - bool bJointSelected = false; - BaseJoint* selectedJoint; - for (int i = 0; i < joints.size(); i++) { - if (joints[i]->isSelected()) { - bJointSelected = true; - selectedJoint = joints[i]; - break; - } - } - - if (bJointSelected) { - selectedJoint->position += by; - } else { - moveSelectedSurface(by); - } - } - - void ProjectionEditor::setSnapDistance(float newSnapDistance) { - fSnapDistance = newSnapDistance; - } - - CircleJoint* ProjectionEditor::hitTestJoints(ofVec2f pos) { - for (int i = 0; i < joints.size(); i++) { - if (joints[i]->hitTest(pos)) { - return joints[i]; - } - } - return NULL; - } - - vector * ProjectionEditor::getJoints(){ - return &joints; - } - - void ProjectionEditor::drawJoints() { - for (int i = 0; i < joints.size(); i++) { - joints[i]->draw(); - } - } - } -} \ No newline at end of file +namespace piMapper { + +ProjectionEditor::ProjectionEditor(){ + surfaceManager = NULL; + bShiftKeyDown = false; + fSnapDistance = 10.0f; + enable(); +} + +ProjectionEditor::~ProjectionEditor(){ + clearJoints(); + surfaceManager = NULL; + disable(); +} + +void ProjectionEditor::registerAppEvents(){ + ofAddListener(ofEvents().update, this, &ProjectionEditor::update); + ofAddListener(ofEvents().messageEvent, this, &ProjectionEditor::gotMessage); +} + +void ProjectionEditor::unregisterAppEvents(){ + ofRemoveListener(ofEvents().update, this, &ProjectionEditor::update); + ofRemoveListener(ofEvents().messageEvent, this, + &ProjectionEditor::gotMessage); +} + +void ProjectionEditor::registerMouseEvents(){ + ofAddListener(ofEvents().mouseDragged, this, &ProjectionEditor::mouseDragged); +} + +void ProjectionEditor::unregisterMouseEvents(){ + ofRemoveListener(ofEvents().mouseDragged, this, + &ProjectionEditor::mouseDragged); +} + +void ProjectionEditor::registerKeyEvents(){ + ofAddListener(ofEvents().keyPressed, this, &ProjectionEditor::keyPressed); + ofAddListener(ofEvents().keyReleased, this, &ProjectionEditor::keyReleased); +} + +void ProjectionEditor::unregisterKeyEvents(){ + ofRemoveListener(ofEvents().keyPressed, this, &ProjectionEditor::keyPressed); + ofRemoveListener(ofEvents().keyReleased, this, + &ProjectionEditor::keyReleased); +} + +void ProjectionEditor::enable(){ + registerAppEvents(); + registerMouseEvents(); + registerKeyEvents(); +} + +void ProjectionEditor::disable(){ + unregisterAppEvents(); + unregisterMouseEvents(); + unregisterKeyEvents(); +} + +void ProjectionEditor::update(ofEventArgs & args){ + // update surface if one of the joints is being dragged + for(int i = 0; i < joints.size(); i++){ + if(joints[i]->isDragged() || joints[i]->isSelected()){ + if(surfaceManager->getSelectedSurface() != NULL){ + // update vertex to new location + surfaceManager->getSelectedSurface()->setVertex(i, joints[i]->position); + }else{ + // clear joints if there is no surface selected + // as the remove selected surface in the surface manager + // is not supposed to access joints here + joints.clear(); + } + break; + } + } +} + +void ProjectionEditor::draw(){ + if(surfaceManager == NULL){ + return; + } + if(surfaceManager->getSelectedSurface() == NULL){ + return; + } + if(joints.size() <= 0){ + createJoints(); + } + drawJoints(); +} + +void ProjectionEditor::mouseDragged(ofMouseEventArgs & args){ + ofVec2f mousePosition = ofVec2f(args.x, args.y); + + // Collect all vertices of the projection surfaces + vector allVertices; + for(int i = 0; i < surfaceManager->size(); i++){ + BaseSurface * surface = surfaceManager->getSurface(i); + if(surface == surfaceManager->getSelectedSurface()){ + continue; // Don't add vertices of selected surface + } + for(int j = 0; j < surface->getVertices().size(); j++){ + allVertices.push_back(&surface->getVertices()[j]); + } + } + + // Snap currently dragged joint to nearest vertex + for(int i = 0; i < joints.size(); i++){ + if(joints[i]->isDragged()){ + // Snap it! + for(int j = 0; j < allVertices.size(); j++){ + float distance = mousePosition.distance(*allVertices[j]); + // cout << "distance: " << distance << endl; + if(distance < fSnapDistance){ + joints[i]->position = *allVertices[j]; + ofVec2f clickDistance = joints[i]->position - ofVec2f(args.x, args.y); + joints[i]->setClickDistance(clickDistance); + break; + } + } + } + } +} + +void ProjectionEditor::keyPressed(ofKeyEventArgs & args){ + int key = args.key; + float moveStep; + + if(bShiftKeyDown){ + moveStep = 10.0f; + }else{ + moveStep = 0.5f; + } + + switch(key){ + case OF_KEY_LEFT: + moveSelection(ofVec2f(-moveStep, 0.0f)); + break; + + case OF_KEY_RIGHT: + moveSelection(ofVec2f(moveStep, 0.0f)); + break; + + case OF_KEY_UP: + moveSelection(ofVec2f(0.0f, -moveStep)); + break; + + case OF_KEY_DOWN: + moveSelection(ofVec2f(0.0f, moveStep)); + break; + + case OF_KEY_SHIFT: + bShiftKeyDown = true; + break; + } +} + +void ProjectionEditor::keyReleased(ofKeyEventArgs & args){ + int key = args.key; + switch(key){ + case OF_KEY_SHIFT: + bShiftKeyDown = false; + break; + } +} + +void ProjectionEditor::gotMessage(ofMessage & msg){ + if(msg.message == "surfaceSelected"){ + // refresh gui + clearJoints(); + createJoints(); + } +} + +void ProjectionEditor::setSurfaceManager(SurfaceManager * newSurfaceManager){ + surfaceManager = newSurfaceManager; +} + +void ProjectionEditor::clearJoints(){ + while(joints.size()){ + delete joints.back(); + joints.pop_back(); + } +} + +void ProjectionEditor::createJoints(){ + if(surfaceManager == NULL){ + return; + } + clearJoints(); + + if(surfaceManager->getSelectedSurface() == NULL){ + ofLog(OF_LOG_WARNING, "Trying to create joints while no surface selected."); + return; + } + + vector & vertices = + surfaceManager->getSelectedSurface()->getVertices(); + + for(int i = 0; i < vertices.size(); i++){ + joints.push_back(new CircleJoint()); + joints.back()->position = ofVec2f(vertices[i].x, vertices[i].y); + } +} + +void ProjectionEditor::updateJoints(){ + if(surfaceManager->getSelectedSurface()){ + vector & vertices = + surfaceManager->getSelectedSurface()->getVertices(); + for(int i = 0; i < vertices.size(); i++){ + joints[i]->position = ofVec2f(vertices[i].x, vertices[i].y); + } + } + +} + +void ProjectionEditor::unselectAllJoints(){ + for(int i = 0; i < joints.size(); i++){ + joints[i]->unselect(); + } +} + +void ProjectionEditor::moveSelectedSurface(ofVec2f by){ + if(surfaceManager == NULL){ + return; + } + if(surfaceManager->getSelectedSurface() == NULL){ + return; + } + surfaceManager->getSelectedSurface()->moveBy(by); + /*vector& vertices = + surfaceManager->getSelectedSurface()->getVertices(); + for (int i=0; istopDrag(); + } +} + +void ProjectionEditor::moveSelection(ofVec2f by){ + // check if joints selected + bool bJointSelected = false; + BaseJoint * selectedJoint; + for(int i = 0; i < joints.size(); i++){ + if(joints[i]->isSelected()){ + bJointSelected = true; + selectedJoint = joints[i]; + break; + } + } + + if(bJointSelected){ + selectedJoint->position += by; + }else{ + moveSelectedSurface(by); + } +} + +void ProjectionEditor::setSnapDistance(float newSnapDistance){ + fSnapDistance = newSnapDistance; +} + +CircleJoint * ProjectionEditor::hitTestJoints(ofVec2f pos){ + for(int i = 0; i < joints.size(); i++){ + if(joints[i]->hitTest(pos)){ + return joints[i]; + } + } + return NULL; +} + +vector * ProjectionEditor::getJoints(){ + return &joints; +} + +void ProjectionEditor::drawJoints(){ + for(int i = 0; i < joints.size(); i++){ + joints[i]->draw(); + } +} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/ProjectionEditor.h b/src/UserInterface/ProjectionEditor.h old mode 100755 new mode 100644 index ec59cef..8031415 --- a/src/UserInterface/ProjectionEditor.h +++ b/src/UserInterface/ProjectionEditor.h @@ -4,48 +4,52 @@ #include "CircleJoint.h" namespace ofx { - namespace piMapper { - class ProjectionEditor { - public: - ProjectionEditor(); - ~ProjectionEditor(); - - void registerAppEvents(); - void unregisterAppEvents(); - void registerMouseEvents(); - void unregisterMouseEvents(); - void registerKeyEvents(); - void unregisterKeyEvents(); - - void enable(); - void disable(); - - void update(ofEventArgs& args); - void draw(); - void mouseDragged(ofMouseEventArgs& args); - void keyPressed(ofKeyEventArgs& args); - void keyReleased(ofKeyEventArgs& args); - void gotMessage(ofMessage& msg); - void setSurfaceManager(SurfaceManager* newSurfaceManager); - void clearJoints(); - void createJoints(); - void updateJoints(); - void unselectAllJoints(); - void moveSelectedSurface(ofVec2f by); - void stopDragJoints(); - void updateVertices(); - void moveSelection(ofVec2f by); - void setSnapDistance(float newSnapDistance); - CircleJoint* hitTestJoints(ofVec2f pos); - vector * getJoints(); - - private: - SurfaceManager* surfaceManager; - vector joints; - bool bShiftKeyDown; - float fSnapDistance; - - void drawJoints(); - }; - } -} \ No newline at end of file +namespace piMapper { + +class ProjectionEditor { + + public: + ProjectionEditor(); + ~ProjectionEditor(); + + void registerAppEvents(); + void unregisterAppEvents(); + void registerMouseEvents(); + void unregisterMouseEvents(); + void registerKeyEvents(); + void unregisterKeyEvents(); + + void enable(); + void disable(); + + void update(ofEventArgs & args); + void draw(); + void mouseDragged(ofMouseEventArgs & args); + void keyPressed(ofKeyEventArgs & args); + void keyReleased(ofKeyEventArgs & args); + void gotMessage(ofMessage & msg); + void setSurfaceManager(SurfaceManager * newSurfaceManager); + void clearJoints(); + void createJoints(); + void updateJoints(); + void unselectAllJoints(); + void moveSelectedSurface(ofVec2f by); + void stopDragJoints(); + void updateVertices(); + void moveSelection(ofVec2f by); + void setSnapDistance(float newSnapDistance); + CircleJoint * hitTestJoints(ofVec2f pos); + vector * getJoints(); + + private: + SurfaceManager * surfaceManager; + vector joints; + bool bShiftKeyDown; + float fSnapDistance; + + void drawJoints(); + +}; + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/RadioList.cpp b/src/UserInterface/RadioList.cpp index 3a3ed0d..2b51af2 100644 --- a/src/UserInterface/RadioList.cpp +++ b/src/UserInterface/RadioList.cpp @@ -1,199 +1,201 @@ #include "RadioList.h" -namespace ofx{ - namespace piMapper{ - RadioList::RadioList(){ - storedTitle = ""; - storedSelectedItem = 0; - } - - RadioList::RadioList(vector & labels, vector & values){ - RadioList(); - setup(labels, values); - } - - RadioList::RadioList(string title, vector & labels, vector & values){ - RadioList(); - setup(title, labels, values); - } - - RadioList::~RadioList(){ - clear(); - } - - void RadioList::setup(vector & labels, vector & values){ - - // Copy incomming labels for later use - storedLabels = labels; - storedValues = values; - - // Create toggles with labels from the labels arg - int i; - for(i = 0; i < labels.size(); i++){ - ofxToggle * toggle = new ofxToggle(); - toggle->setup(false); - toggle->setName(labels[i]); - toggle->addListener(this, &RadioList::onToggleClicked); - guiGroup.add(toggle); -#if OF_VERSION_MAJOR == 0 && (OF_VERSION_MINOR >= 8 && OF_VERSION_PATCH >= 2) || (OF_VERSION_MINOR >= 9 && OF_VERSION_PATCH >= 0) - toggle->registerMouseEvents(); -#endif - } - } - - void RadioList::setup(string title, vector & labels, vector & values){ - - // Store title for later use - storedTitle = title; - guiGroup.setName(title); - setup(labels, values); - } - - void RadioList::draw(){ - guiGroup.draw(); - } - - void RadioList::setTitle(string title){ - storedTitle = title; - guiGroup.setName(title); - } - - void RadioList::setPosition(ofPoint p){ - guiGroup.setPosition(p); - } - - void RadioList::setPosition(float x, float y){ - guiGroup.setPosition(x, y); - } - - void RadioList::selectItem(int index){ - if(index >= guiGroup.getNumControls()){ - return; - } - - unselectAll(); - - ofxToggle * toggle = static_cast(guiGroup.getControl(index)); - toggle->removeListener(this, &RadioList::onToggleClicked); - *toggle = true; // Select the specific radio button - toggle->addListener(this, &RadioList::onToggleClicked); - //string name = toggle->getName(); - // Throw event with value that is image path instead of name - string value = storedValues[index]; - ofNotifyEvent(onRadioSelected, value, this); - storedSelectedItem = index; - } - - bool RadioList::selectItemByValue(std::string itemValue){ - if(itemValue == ""){ - ofLogNotice("RadioList") << "Item value empty"; - return false; - } - unselectAll(); - int itemIndex = -1; - for(int i = 0; i < storedValues.size(); i++){ - if(itemValue == storedValues[i]){ - itemIndex = i; - break; - } - } - if(itemIndex >= 0){ - ofxToggle * toggle = static_cast(guiGroup.getControl(itemIndex)); - toggle->removeListener(this, &RadioList::onToggleClicked); - *toggle = true; // Select the specific radio button - toggle->addListener(this, &RadioList::onToggleClicked); - return true; - } - ofLogNotice("RadioList") << "Item with value " << itemValue << " not found"; - return false; - } - - void RadioList::enable(){ - if(guiGroup.getNumControls() > 0){ - clear(); - } - - // Rebuild everyting - setup(storedTitle, storedLabels, storedValues); - - // Select the stored selected item without throwing an event - ofxToggle * toggle = static_cast(guiGroup.getControl(storedSelectedItem)); - toggle->removeListener(this, &RadioList::onToggleClicked); - *toggle = true; - toggle->addListener(this, &RadioList::onToggleClicked); - - cout << "num items after enable: " << guiGroup.getNumControls() << endl; - } - - void RadioList::disable(){ - // Just remove everything - clear(); - } - - void RadioList::clear(){ - int i; - for(i = 0; i < guiGroup.getNumControls(); i++){ - ofxToggle * toggle = static_cast(guiGroup.getControl(i)); - toggle->removeListener(this, &RadioList::onToggleClicked); - delete toggle; - } - guiGroup.clear(); - } - - void RadioList::unselectAll(){ - int i; - for(i = 0; i < guiGroup.getNumControls(); i++){ - ofxToggle * toggle = static_cast(guiGroup.getControl(i)); - ofParameter * paramPtr = static_cast *>(&toggle->getParameter()); - toggle->removeListener(this, &RadioList::onToggleClicked); - *toggle = false; - toggle->addListener(this, &RadioList::onToggleClicked); - } - } - - ofPoint RadioList::getPosition(){ - return guiGroup.getPosition(); - } - - float RadioList::getWidth(){ - return guiGroup.getWidth(); - } - - float RadioList::getHeight(){ - return guiGroup.getHeight(); - } - - string RadioList::getTitle(){ - return guiGroup.getName(); - } - - string RadioList::getItemName(int index){ - if(index >= guiGroup.getNumControls()){ - return ""; - } - - ofxToggle * toggle = static_cast(guiGroup.getControl(index)); - return toggle->getName(); - } - - int RadioList::size(){ - return storedValues.size(); - } - - void RadioList::onToggleClicked(bool & toggleValue){ - unselectAll(); - - // Search for the actual toggle triggering the event - int i; - for(i = 0; i < guiGroup.getNumControls(); i++){ - ofxToggle * toggle = static_cast(guiGroup.getControl(i)); - ofParameter * paramPtr = static_cast *>(&toggle->getParameter()); - - if(&(paramPtr->get()) == &toggleValue){ - selectItem(i); - break; - } - } - } - } // namespace piMapper +namespace ofx { +namespace piMapper { + +RadioList::RadioList(){ + storedTitle = ""; + storedSelectedItem = 0; +} + +RadioList::RadioList(vector & labels, vector & values){ + RadioList(); + setup(labels, values); +} + +RadioList::RadioList(string title, vector & labels, vector & values){ + RadioList(); + setup(title, labels, values); +} + +RadioList::~RadioList(){ + clear(); +} + +void RadioList::setup(vector & labels, vector & values){ + + // Copy incomming labels for later use + storedLabels = labels; + storedValues = values; + + // Create toggles with labels from the labels arg + int i; + for(i = 0; i < labels.size(); i++){ + ofxToggle * toggle = new ofxToggle(); + toggle->setup(false); + toggle->setName(labels[i]); + toggle->addListener(this, &RadioList::onToggleClicked); + guiGroup.add(toggle); + #if OF_VERSION_MAJOR == 0 && (OF_VERSION_MINOR >= 8 && OF_VERSION_PATCH >= 2) || (OF_VERSION_MINOR >= 9 && OF_VERSION_PATCH >= 0) + toggle->registerMouseEvents(); + #endif + } +} + +void RadioList::setup(string title, vector & labels, vector & values){ + + // Store title for later use + storedTitle = title; + guiGroup.setName(title); + setup(labels, values); +} + +void RadioList::draw(){ + guiGroup.draw(); +} + +void RadioList::setTitle(string title){ + storedTitle = title; + guiGroup.setName(title); +} + +void RadioList::setPosition(ofPoint p){ + guiGroup.setPosition(p); +} + +void RadioList::setPosition(float x, float y){ + guiGroup.setPosition(x, y); +} + +void RadioList::selectItem(int index){ + if(index >= guiGroup.getNumControls()){ + return; + } + + unselectAll(); + + ofxToggle * toggle = static_cast (guiGroup.getControl(index)); + toggle->removeListener(this, &RadioList::onToggleClicked); + *toggle = true; // Select the specific radio button + toggle->addListener(this, &RadioList::onToggleClicked); + //string name = toggle->getName(); + // Throw event with value that is image path instead of name + string value = storedValues[index]; + ofNotifyEvent(onRadioSelected, value, this); + storedSelectedItem = index; +} + +bool RadioList::selectItemByValue(std::string itemValue){ + if(itemValue == ""){ + ofLogNotice("RadioList") << "Item value empty"; + return false; + } + unselectAll(); + int itemIndex = -1; + for(int i = 0; i < storedValues.size(); i++){ + if(itemValue == storedValues[i]){ + itemIndex = i; + break; + } + } + if(itemIndex >= 0){ + ofxToggle * toggle = static_cast (guiGroup.getControl(itemIndex)); + toggle->removeListener(this, &RadioList::onToggleClicked); + *toggle = true; // Select the specific radio button + toggle->addListener(this, &RadioList::onToggleClicked); + return true; + } + ofLogNotice("RadioList") << "Item with value " << itemValue << " not found"; + return false; +} + +void RadioList::enable(){ + if(guiGroup.getNumControls() > 0){ + clear(); + } + + // Rebuild everyting + setup(storedTitle, storedLabels, storedValues); + + // Select the stored selected item without throwing an event + ofxToggle * toggle = static_cast (guiGroup.getControl(storedSelectedItem)); + toggle->removeListener(this, &RadioList::onToggleClicked); + *toggle = true; + toggle->addListener(this, &RadioList::onToggleClicked); + + cout << "num items after enable: " << guiGroup.getNumControls() << endl; +} + +void RadioList::disable(){ + // Just remove everything + clear(); +} + +void RadioList::clear(){ + int i; + for(i = 0; i < guiGroup.getNumControls(); i++){ + ofxToggle * toggle = static_cast (guiGroup.getControl(i)); + toggle->removeListener(this, &RadioList::onToggleClicked); + delete toggle; + } + guiGroup.clear(); +} + +void RadioList::unselectAll(){ + int i; + for(i = 0; i < guiGroup.getNumControls(); i++){ + ofxToggle * toggle = static_cast (guiGroup.getControl(i)); + ofParameter * paramPtr = static_cast *>(&toggle->getParameter()); + toggle->removeListener(this, &RadioList::onToggleClicked); + *toggle = false; + toggle->addListener(this, &RadioList::onToggleClicked); + } +} + +ofPoint RadioList::getPosition(){ + return guiGroup.getPosition(); +} + +float RadioList::getWidth(){ + return guiGroup.getWidth(); +} + +float RadioList::getHeight(){ + return guiGroup.getHeight(); +} + +string RadioList::getTitle(){ + return guiGroup.getName(); +} + +string RadioList::getItemName(int index){ + if(index >= guiGroup.getNumControls()){ + return ""; + } + + ofxToggle * toggle = static_cast (guiGroup.getControl(index)); + return toggle->getName(); +} + +int RadioList::size(){ + return storedValues.size(); +} + +void RadioList::onToggleClicked(bool & toggleValue){ + unselectAll(); + + // Search for the actual toggle triggering the event + int i; + for(i = 0; i < guiGroup.getNumControls(); i++){ + ofxToggle * toggle = static_cast (guiGroup.getControl(i)); + ofParameter * paramPtr = static_cast *>(&toggle->getParameter()); + + if(&(paramPtr->get()) == &toggleValue){ + selectItem(i); + break; + } + } +} + +} // namespace piMapper } // namespace ofx diff --git a/src/UserInterface/RadioList.h b/src/UserInterface/RadioList.h index 82dfaa1..826dee4 100644 --- a/src/UserInterface/RadioList.h +++ b/src/UserInterface/RadioList.h @@ -5,50 +5,52 @@ #include "ofxToggle.h" #include "ofxLabel.h" -namespace ofx{ - namespace piMapper{ - class RadioList{ - public: - RadioList(); - RadioList(vector & labels, vector & values); - RadioList(string title, vector & labels, vector & values); - ~RadioList(); - - void setup(vector & labels, vector & values); - void setup(string title, vector & labels, vector & values); - void draw(); - void setTitle(string title); - void setPosition(ofPoint p); - void setPosition(float x, float y); - void selectItem(int index); - bool selectItemByValue(std::string itemValue); - void enable(); - void disable(); - void clear(); - void unselectAll(); - ofPoint getPosition(); - float getWidth(); - float getHeight(); - string getTitle(); - string getItemName(int index); - int size(); - - // This event notifies about a toggle being selected and passes it's name to - // the listeners. - // Use ofAddListener(RadioListInstance.radioSelectedEvent, listenerClassPtr, - // &listenerClass::listenerMethod) - // to listen to this. Listner method void listenerMethod(string & radioName) - ofEvent onRadioSelected; - - private: - vector storedLabels; - vector storedValues; - string storedTitle; - ofxGuiGroup guiGroup; - int storedSelectedItem; - - void onToggleClicked(bool & toggleValue); - - }; - } // namespace piMapper +namespace ofx { +namespace piMapper { + +class RadioList { + public: + RadioList(); + RadioList(vector & labels, vector & values); + RadioList(string title, vector & labels, vector & values); + ~RadioList(); + + void setup(vector & labels, vector & values); + void setup(string title, vector & labels, vector & values); + void draw(); + void setTitle(string title); + void setPosition(ofPoint p); + void setPosition(float x, float y); + void selectItem(int index); + bool selectItemByValue(std::string itemValue); + void enable(); + void disable(); + void clear(); + void unselectAll(); + ofPoint getPosition(); + float getWidth(); + float getHeight(); + string getTitle(); + string getItemName(int index); + int size(); + + // This event notifies about a toggle being selected and passes it's name to + // the listeners. + // Use ofAddListener(RadioListInstance.radioSelectedEvent, listenerClassPtr, + // &listenerClass::listenerMethod) + // to listen to this. Listner method void listenerMethod(string & radioName) + ofEvent onRadioSelected; + + private: + vector storedLabels; + vector storedValues; + string storedTitle; + ofxGuiGroup guiGroup; + int storedSelectedItem; + + void onToggleClicked(bool & toggleValue); + +}; + +} // namespace piMapper } // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/SourcesEditor.cpp b/src/UserInterface/SourcesEditor.cpp index bbbd846..65dbe0b 100644 --- a/src/UserInterface/SourcesEditor.cpp +++ b/src/UserInterface/SourcesEditor.cpp @@ -2,371 +2,372 @@ namespace ofx { namespace piMapper { - SourcesEditor::SourcesEditor() { - init(); - // Create new MediaServer instance, - // we will need to clear this in the deconstr - mediaServer = new MediaServer(); - isMediaServerExternal = false; - addMediaServerListeners(); - } - - void SourcesEditor::init() { - mediaServer = NULL; // Pointers to NULL pointer so we can check later - isMediaServerExternal = false; - registerAppEvents(); - } - - SourcesEditor::SourcesEditor(MediaServer* externalMediaServer) { - init(); - // Assign external MediaServer instance pointer - mediaServer = externalMediaServer; - isMediaServerExternal = true; - addMediaServerListeners(); - } - - SourcesEditor::~SourcesEditor() { - unregisterAppEvents(); - delete imageSelector; - delete videoSelector; - delete fboSelector; - removeMediaServerListeners(); - clearMediaServer(); - } - - void SourcesEditor::registerAppEvents() { - ofAddListener(ofEvents().setup, this, &SourcesEditor::setup); - } - - void SourcesEditor::unregisterAppEvents() { - ofRemoveListener(ofEvents().setup, this, &SourcesEditor::setup); - } - - void SourcesEditor::setup(ofEventArgs& args) { - imageSelector = new RadioList(); - videoSelector = new RadioList(); - fboSelector = new RadioList(); - - // Get media count - int numImages = mediaServer->getNumImages(); - int numVideos = mediaServer->getNumVideos(); - int numFbos = mediaServer->getNumFboSources(); - - // Depending on media count, decide what to load and initialize - if (numImages) { - // Get image names from media server - vector imageNames = mediaServer->getImageNames(); - imageSelector->setup("Images", imageNames, mediaServer->getImagePaths()); - ofAddListener(imageSelector->onRadioSelected, this, &SourcesEditor::handleImageSelected); - } - if (numVideos) { - vector videoNames = mediaServer->getVideoNames(); - videoSelector->setup("Videos", videoNames, mediaServer->getVideoPaths()); - ofAddListener(videoSelector->onRadioSelected, this, &SourcesEditor::handleVideoSelected); - } - if (numFbos) { - std::vector fboNames = mediaServer->getFboSourceNames(); - fboSelector->setup("FBOs", fboNames, fboNames); - ofAddListener(fboSelector->onRadioSelected, this, &SourcesEditor::handleFboSelected); - } - - // Align menus - int menuPosX = 20; - int distX = 230; - if (numImages) { - imageSelector->setPosition(menuPosX, 20); - menuPosX += distX; - } - if (numVideos) { - videoSelector->setPosition(menuPosX, 20); - menuPosX += distX; - } - if (numFbos) { - fboSelector->setPosition(menuPosX, 20); - } - - } - - void SourcesEditor::draw() { - // Don't draw if there is no source selected - if (surfaceManager->getSelectedSurface() == NULL) { - //ofLogNotice("SourcesEditor") << "No surface selected"; - return; - } - if (imageSelector->size()) { - imageSelector->draw(); - } - if (videoSelector->size()) { - videoSelector->draw(); - } - if (fboSelector->size()) { - fboSelector->draw(); - } - - } - - void SourcesEditor::disable() { - if (imageSelector->size()) { - imageSelector->disable(); - } - if (videoSelector->size()) { - videoSelector->disable(); - } - if (fboSelector->size()) { - fboSelector->disable(); - } - } - - void SourcesEditor::enable() { - // Don't enable if there is no surface selected - if (surfaceManager->getSelectedSurface() == NULL) { - ofLogNotice("SourcesEditor") << "No surface selected. Not enabling and not showing source list."; - return; - } - if (imageSelector->size()) { - imageSelector->enable(); - } - if (videoSelector->size()) { - videoSelector->enable(); - } - if (fboSelector->size()) { - fboSelector->enable(); - } - BaseSource* source = surfaceManager->getSelectedSurface()->getSource(); - - // TODO: getPath should be replaced with something like getId() as now we - // use paths for loadable sources and names for FBOs - if (source->getType() == SourceType::SOURCE_TYPE_FBO) { - selectSourceRadioButton(source->getName()); - } else { - selectSourceRadioButton(source->getPath()); - } - } - - void SourcesEditor::setSurfaceManager(SurfaceManager* newSurfaceManager) { - surfaceManager = newSurfaceManager; - } - - void SourcesEditor::setCmdManager(CmdManager * cmdManager){ - _cmdManager = cmdManager; - } - - void SourcesEditor::setMediaServer(MediaServer* newMediaServer) { - // If the new media server is not valid - if (newMediaServer == NULL) { - // Log an error and return from the routine - ofLogFatalError("SourcesEditor") << "New media server is NULL"; - std::exit(EXIT_FAILURE); - } - // Attempt to clear existing media server and assign new one - clearMediaServer(); - //cout << "old ms addr: " << mediaServer << endl; - //cout << "new ms addr: " << newMediaServer << endl; - mediaServer = newMediaServer; - isMediaServerExternal = true; - } - - void SourcesEditor::selectSourceRadioButton(std::string& sourcePath) { - if (sourcePath == "") { - ofLogNotice("SourcesEditor") << "Path is empty"; - if (imageSelector->size()) { - imageSelector->unselectAll(); - } - if (videoSelector->size()) { - videoSelector->unselectAll(); - } - if (fboSelector->size()) { - fboSelector->unselectAll(); - } - return; - } else { - // Check image selector first - bool imageRadioSelected = false; - bool videoRadioSelected = false; - bool fboRadioSelected = false; - if (imageSelector->size()) { - imageRadioSelected = imageSelector->selectItemByValue(sourcePath); - } - if (videoSelector->size()) { - videoRadioSelected = videoSelector->selectItemByValue(sourcePath); - } - if (fboSelector->size()) { - fboRadioSelected = fboSelector->selectItemByValue(sourcePath); - } - if (imageRadioSelected || videoRadioSelected || fboRadioSelected) { - return; - } - // Log warning if we are still here - ofLogWarning("SourcesEditor") << "Could not find option in any of the source lists"; - } - } - - void SourcesEditor::addMediaServerListeners() { - // Check if the media server is valid - if (mediaServer == NULL) { - ofLogError("SourcesEditor::addMediaServerListeners", "Media server not set"); - return; - } - // Add listeners to custom events of the media server - ofAddListener(mediaServer->onImageAdded, this, &SourcesEditor::handleImageAdded); - ofAddListener(mediaServer->onImageRemoved, this, &SourcesEditor::handleImageRemoved); - ofAddListener(mediaServer->onVideoAdded, this, &SourcesEditor::handleVideoAdded); - ofAddListener(mediaServer->onVideoRemoved, this, &SourcesEditor::handleVideoRemoved); - ofAddListener(mediaServer->onImageLoaded, this, &SourcesEditor::handleImageLoaded); - ofAddListener(mediaServer->onImageUnloaded, this, &SourcesEditor::handleImageUnloaded); - - ofAddListener(mediaServer->onFboSourceAdded, this, &SourcesEditor::handleFboSourceAdded); - ofAddListener(mediaServer->onFboSourceRemoved, this, &SourcesEditor::handleFboSourceRemoved); - ofAddListener(mediaServer->onFboSourceLoaded, this, &SourcesEditor::handleFboSourceLoaded); - ofAddListener(mediaServer->onFboSourceUnloaded, this, &SourcesEditor::handleFboSourceUnloaded); - - } - - void SourcesEditor::removeMediaServerListeners() { - // Check if the media server is valid - if (mediaServer == NULL) { - ofLogError("SourcesEditor::addMediaServerListeners", "Media server not set"); - return; - } - // Remove listeners to custom events of the media server - ofRemoveListener(mediaServer->onImageAdded, this, &SourcesEditor::handleImageAdded); - ofRemoveListener(mediaServer->onImageRemoved, this, &SourcesEditor::handleImageRemoved); - ofRemoveListener(mediaServer->onVideoAdded, this, &SourcesEditor::handleVideoAdded); - ofRemoveListener(mediaServer->onVideoRemoved, this, &SourcesEditor::handleVideoRemoved); - ofRemoveListener(mediaServer->onImageLoaded, this, &SourcesEditor::handleImageLoaded); - ofRemoveListener(mediaServer->onImageUnloaded, this, &SourcesEditor::handleImageUnloaded); - ofRemoveListener(mediaServer->onFboSourceAdded, this, &SourcesEditor::handleFboSourceAdded); - ofRemoveListener(mediaServer->onFboSourceRemoved, this, &SourcesEditor::handleFboSourceRemoved); - ofRemoveListener(mediaServer->onFboSourceLoaded, this, &SourcesEditor::handleFboSourceLoaded); - ofRemoveListener(mediaServer->onFboSourceUnloaded, this, &SourcesEditor::handleFboSourceUnloaded); - } - - void SourcesEditor::handleImageSelected(string & imagePath){ - _cmdManager->exec(new SetSourceCmd(SourceType::SOURCE_TYPE_IMAGE, - imagePath, - surfaceManager->getSelectedSurface(), - (SourcesEditor *)this)); - } - - void SourcesEditor::setImageSource(string & imagePath){ - // Unselect selected items - videoSelector->unselectAll(); - fboSelector->unselectAll(); - - BaseSurface* surface = surfaceManager->getSelectedSurface(); - if (surface == NULL) { - ofLogWarning("SourcesEditor") << "No surface selected"; - return; - } - - // Unload old media - BaseSource* source = surface->getSource(); - if (source->isLoadable()) { - mediaServer->unloadMedia(source->getPath()); - } else { - mediaServer->unloadMedia(source->getName()); - } - - // Load new image - surface->setSource(mediaServer->loadImage(imagePath)); - } - - void SourcesEditor::handleVideoSelected(string & videoPath){ - _cmdManager->exec(new SetSourceCmd(SourceType::SOURCE_TYPE_VIDEO, - videoPath, - surfaceManager->getSelectedSurface(), - (SourcesEditor *)this)); - } - - void SourcesEditor::setVideoSource(string & videoPath){ - // Unselect any selected items - fboSelector->unselectAll(); - imageSelector->unselectAll(); - - BaseSurface* surface = surfaceManager->getSelectedSurface(); - if (surface == NULL) { - ofLogWarning("SourcesEditor") << "No surface selected"; - return; - } - - // Unload old media - BaseSource* source = surface->getSource(); - if (source->isLoadable()) { - mediaServer->unloadMedia(source->getPath()); - } else { - mediaServer->unloadMedia(source->getName()); - } - - // Load new video - surface->setSource(mediaServer->loadVideo(videoPath)); - } - - void SourcesEditor::handleFboSelected(string & fboName){ - _cmdManager->exec(new SetSourceCmd(SourceType::SOURCE_TYPE_FBO, - fboName, - surfaceManager->getSelectedSurface(), - (SourcesEditor *)this)); - } - - void SourcesEditor::setFboSource(string & fboName) { - videoSelector->unselectAll(); - imageSelector->unselectAll(); - - // Get selected surface - BaseSurface* surface = surfaceManager->getSelectedSurface(); - if (surface == NULL) { - ofLogWarning("SourcesEditor") << "No surface selected"; - return; - } - - // Unload old media - BaseSource* source = surface->getSource(); - if (source->isLoadable()) { - mediaServer->unloadMedia(source->getPath()); - } else { - mediaServer->unloadMedia(source->getName()); - } - - // Load new FBO - surface->setSource(mediaServer->loadFboSource(fboName)); - } - - void SourcesEditor::clearSource(){ - BaseSurface* surface = surfaceManager->getSelectedSurface(); - - // Unload old media - BaseSource* source = surface->getSource(); - if (source->isLoadable()) { - mediaServer->unloadMedia(source->getPath()); - } else { - mediaServer->unloadMedia(source->getName()); - } - - // Reset default source - surface->setSource(surface->getDefaultSource()); - } - - void SourcesEditor::clearMediaServer() { - // If mediaServer is local, clear it - if (!isMediaServerExternal) { - // Clear all loaded sources - mediaServer->clear(); - // Destroy the pointer and set it to NULL pointer - delete mediaServer; - mediaServer = NULL; - } - } - - void SourcesEditor::handleImageAdded(std::string& path) {} - void SourcesEditor::handleImageRemoved(std::string& path) {} - void SourcesEditor::handleVideoAdded(std::string& path) {} - void SourcesEditor::handleVideoRemoved(std::string& path) {} - void SourcesEditor::handleImageLoaded(std::string& path) {} - void SourcesEditor::handleImageUnloaded(std::string& path) {} - void SourcesEditor::handleFboSourceAdded(std::string& name) {} - void SourcesEditor::handleFboSourceRemoved(std::string& name) {} - void SourcesEditor::handleFboSourceLoaded(std::string& name) {} - void SourcesEditor::handleFboSourceUnloaded(std::string& name) {} - + +SourcesEditor::SourcesEditor(){ + init(); + // Create new MediaServer instance, + // we will need to clear this in the deconstr + mediaServer = new MediaServer(); + isMediaServerExternal = false; + addMediaServerListeners(); +} + +void SourcesEditor::init(){ + mediaServer = NULL; // Pointers to NULL pointer so we can check later + isMediaServerExternal = false; + registerAppEvents(); +} + +SourcesEditor::SourcesEditor(MediaServer * externalMediaServer){ + init(); + // Assign external MediaServer instance pointer + mediaServer = externalMediaServer; + isMediaServerExternal = true; + addMediaServerListeners(); +} + +SourcesEditor::~SourcesEditor(){ + unregisterAppEvents(); + delete imageSelector; + delete videoSelector; + delete fboSelector; + removeMediaServerListeners(); + clearMediaServer(); +} + +void SourcesEditor::registerAppEvents(){ + ofAddListener(ofEvents().setup, this, &SourcesEditor::setup); +} + +void SourcesEditor::unregisterAppEvents(){ + ofRemoveListener(ofEvents().setup, this, &SourcesEditor::setup); +} + +void SourcesEditor::setup(ofEventArgs & args){ + imageSelector = new RadioList(); + videoSelector = new RadioList(); + fboSelector = new RadioList(); + + // Get media count + int numImages = mediaServer->getNumImages(); + int numVideos = mediaServer->getNumVideos(); + int numFbos = mediaServer->getNumFboSources(); + + // Depending on media count, decide what to load and initialize + if(numImages){ + // Get image names from media server + vector imageNames = mediaServer->getImageNames(); + imageSelector->setup("Images", imageNames, mediaServer->getImagePaths()); + ofAddListener(imageSelector->onRadioSelected, this, &SourcesEditor::handleImageSelected); + } + if(numVideos){ + vector videoNames = mediaServer->getVideoNames(); + videoSelector->setup("Videos", videoNames, mediaServer->getVideoPaths()); + ofAddListener(videoSelector->onRadioSelected, this, &SourcesEditor::handleVideoSelected); + } + if(numFbos){ + std::vector fboNames = mediaServer->getFboSourceNames(); + fboSelector->setup("FBOs", fboNames, fboNames); + ofAddListener(fboSelector->onRadioSelected, this, &SourcesEditor::handleFboSelected); + } + + // Align menus + int menuPosX = 20; + int distX = 230; + if(numImages){ + imageSelector->setPosition(menuPosX, 20); + menuPosX += distX; + } + if(numVideos){ + videoSelector->setPosition(menuPosX, 20); + menuPosX += distX; + } + if(numFbos){ + fboSelector->setPosition(menuPosX, 20); + } + +} + +void SourcesEditor::draw(){ + // Don't draw if there is no source selected + if(surfaceManager->getSelectedSurface() == NULL){ + //ofLogNotice("SourcesEditor") << "No surface selected"; + return; + } + if(imageSelector->size()){ + imageSelector->draw(); + } + if(videoSelector->size()){ + videoSelector->draw(); + } + if(fboSelector->size()){ + fboSelector->draw(); + } + +} + +void SourcesEditor::disable(){ + if(imageSelector->size()){ + imageSelector->disable(); + } + if(videoSelector->size()){ + videoSelector->disable(); + } + if(fboSelector->size()){ + fboSelector->disable(); + } +} + +void SourcesEditor::enable(){ + // Don't enable if there is no surface selected + if(surfaceManager->getSelectedSurface() == NULL){ + ofLogNotice("SourcesEditor") << "No surface selected. Not enabling and not showing source list."; + return; + } + if(imageSelector->size()){ + imageSelector->enable(); + } + if(videoSelector->size()){ + videoSelector->enable(); + } + if(fboSelector->size()){ + fboSelector->enable(); + } + BaseSource * source = surfaceManager->getSelectedSurface()->getSource(); + + // TODO: getPath should be replaced with something like getId() as now we + // use paths for loadable sources and names for FBOs + if(source->getType() == SourceType::SOURCE_TYPE_FBO){ + selectSourceRadioButton(source->getName()); + }else{ + selectSourceRadioButton(source->getPath()); + } +} + +void SourcesEditor::setSurfaceManager(SurfaceManager * newSurfaceManager){ + surfaceManager = newSurfaceManager; +} + +void SourcesEditor::setCmdManager(CmdManager * cmdManager){ + _cmdManager = cmdManager; +} + +void SourcesEditor::setMediaServer(MediaServer * newMediaServer){ + // If the new media server is not valid + if(newMediaServer == NULL){ + // Log an error and return from the routine + ofLogFatalError("SourcesEditor") << "New media server is NULL"; + std::exit(EXIT_FAILURE); + } + // Attempt to clear existing media server and assign new one + clearMediaServer(); + //cout << "old ms addr: " << mediaServer << endl; + //cout << "new ms addr: " << newMediaServer << endl; + mediaServer = newMediaServer; + isMediaServerExternal = true; +} + +void SourcesEditor::selectSourceRadioButton(std::string & sourcePath){ + if(sourcePath == ""){ + ofLogNotice("SourcesEditor") << "Path is empty"; + if(imageSelector->size()){ + imageSelector->unselectAll(); + } + if(videoSelector->size()){ + videoSelector->unselectAll(); + } + if(fboSelector->size()){ + fboSelector->unselectAll(); + } + return; + }else{ + // Check image selector first + bool imageRadioSelected = false; + bool videoRadioSelected = false; + bool fboRadioSelected = false; + if(imageSelector->size()){ + imageRadioSelected = imageSelector->selectItemByValue(sourcePath); + } + if(videoSelector->size()){ + videoRadioSelected = videoSelector->selectItemByValue(sourcePath); + } + if(fboSelector->size()){ + fboRadioSelected = fboSelector->selectItemByValue(sourcePath); + } + if(imageRadioSelected || videoRadioSelected || fboRadioSelected){ + return; + } + // Log warning if we are still here + ofLogWarning("SourcesEditor") << "Could not find option in any of the source lists"; + } +} + +void SourcesEditor::addMediaServerListeners(){ + // Check if the media server is valid + if(mediaServer == NULL){ + ofLogError("SourcesEditor::addMediaServerListeners", "Media server not set"); + return; + } + // Add listeners to custom events of the media server + ofAddListener(mediaServer->onImageAdded, this, &SourcesEditor::handleImageAdded); + ofAddListener(mediaServer->onImageRemoved, this, &SourcesEditor::handleImageRemoved); + ofAddListener(mediaServer->onVideoAdded, this, &SourcesEditor::handleVideoAdded); + ofAddListener(mediaServer->onVideoRemoved, this, &SourcesEditor::handleVideoRemoved); + ofAddListener(mediaServer->onImageLoaded, this, &SourcesEditor::handleImageLoaded); + ofAddListener(mediaServer->onImageUnloaded, this, &SourcesEditor::handleImageUnloaded); + + ofAddListener(mediaServer->onFboSourceAdded, this, &SourcesEditor::handleFboSourceAdded); + ofAddListener(mediaServer->onFboSourceRemoved, this, &SourcesEditor::handleFboSourceRemoved); + ofAddListener(mediaServer->onFboSourceLoaded, this, &SourcesEditor::handleFboSourceLoaded); + ofAddListener(mediaServer->onFboSourceUnloaded, this, &SourcesEditor::handleFboSourceUnloaded); + +} + +void SourcesEditor::removeMediaServerListeners(){ + // Check if the media server is valid + if(mediaServer == NULL){ + ofLogError("SourcesEditor::addMediaServerListeners", "Media server not set"); + return; + } + // Remove listeners to custom events of the media server + ofRemoveListener(mediaServer->onImageAdded, this, &SourcesEditor::handleImageAdded); + ofRemoveListener(mediaServer->onImageRemoved, this, &SourcesEditor::handleImageRemoved); + ofRemoveListener(mediaServer->onVideoAdded, this, &SourcesEditor::handleVideoAdded); + ofRemoveListener(mediaServer->onVideoRemoved, this, &SourcesEditor::handleVideoRemoved); + ofRemoveListener(mediaServer->onImageLoaded, this, &SourcesEditor::handleImageLoaded); + ofRemoveListener(mediaServer->onImageUnloaded, this, &SourcesEditor::handleImageUnloaded); + ofRemoveListener(mediaServer->onFboSourceAdded, this, &SourcesEditor::handleFboSourceAdded); + ofRemoveListener(mediaServer->onFboSourceRemoved, this, &SourcesEditor::handleFboSourceRemoved); + ofRemoveListener(mediaServer->onFboSourceLoaded, this, &SourcesEditor::handleFboSourceLoaded); + ofRemoveListener(mediaServer->onFboSourceUnloaded, this, &SourcesEditor::handleFboSourceUnloaded); +} + +void SourcesEditor::handleImageSelected(string & imagePath){ + _cmdManager->exec(new SetSourceCmd(SourceType::SOURCE_TYPE_IMAGE, + imagePath, + surfaceManager->getSelectedSurface(), + (SourcesEditor *)this)); +} + +void SourcesEditor::setImageSource(string & imagePath){ + // Unselect selected items + videoSelector->unselectAll(); + fboSelector->unselectAll(); + + BaseSurface * surface = surfaceManager->getSelectedSurface(); + if(surface == NULL){ + ofLogWarning("SourcesEditor") << "No surface selected"; + return; + } + + // Unload old media + BaseSource * source = surface->getSource(); + if(source->isLoadable()){ + mediaServer->unloadMedia(source->getPath()); + }else{ + mediaServer->unloadMedia(source->getName()); + } + + // Load new image + surface->setSource(mediaServer->loadImage(imagePath)); +} + +void SourcesEditor::handleVideoSelected(string & videoPath){ + _cmdManager->exec(new SetSourceCmd(SourceType::SOURCE_TYPE_VIDEO, + videoPath, + surfaceManager->getSelectedSurface(), + (SourcesEditor *)this)); +} + +void SourcesEditor::setVideoSource(string & videoPath){ + // Unselect any selected items + fboSelector->unselectAll(); + imageSelector->unselectAll(); + + BaseSurface * surface = surfaceManager->getSelectedSurface(); + if(surface == NULL){ + ofLogWarning("SourcesEditor") << "No surface selected"; + return; + } + + // Unload old media + BaseSource * source = surface->getSource(); + if(source->isLoadable()){ + mediaServer->unloadMedia(source->getPath()); + }else{ + mediaServer->unloadMedia(source->getName()); + } + + // Load new video + surface->setSource(mediaServer->loadVideo(videoPath)); +} + +void SourcesEditor::handleFboSelected(string & fboName){ + _cmdManager->exec(new SetSourceCmd(SourceType::SOURCE_TYPE_FBO, + fboName, + surfaceManager->getSelectedSurface(), + (SourcesEditor *)this)); +} + +void SourcesEditor::setFboSource(string & fboName){ + videoSelector->unselectAll(); + imageSelector->unselectAll(); + + // Get selected surface + BaseSurface * surface = surfaceManager->getSelectedSurface(); + if(surface == NULL){ + ofLogWarning("SourcesEditor") << "No surface selected"; + return; + } + + // Unload old media + BaseSource * source = surface->getSource(); + if(source->isLoadable()){ + mediaServer->unloadMedia(source->getPath()); + }else{ + mediaServer->unloadMedia(source->getName()); + } + + // Load new FBO + surface->setSource(mediaServer->loadFboSource(fboName)); } -} \ No newline at end of file + +void SourcesEditor::clearSource(){ + BaseSurface * surface = surfaceManager->getSelectedSurface(); + + // Unload old media + BaseSource * source = surface->getSource(); + if(source->isLoadable()){ + mediaServer->unloadMedia(source->getPath()); + }else{ + mediaServer->unloadMedia(source->getName()); + } + + // Reset default source + surface->setSource(surface->getDefaultSource()); +} + +void SourcesEditor::clearMediaServer(){ + // If mediaServer is local, clear it + if(!isMediaServerExternal){ + // Clear all loaded sources + mediaServer->clear(); + // Destroy the pointer and set it to NULL pointer + delete mediaServer; + mediaServer = NULL; + } +} + +void SourcesEditor::handleImageAdded(std::string & path){} +void SourcesEditor::handleImageRemoved(std::string & path){} +void SourcesEditor::handleVideoAdded(std::string & path){} +void SourcesEditor::handleVideoRemoved(std::string & path){} +void SourcesEditor::handleImageLoaded(std::string & path){} +void SourcesEditor::handleImageUnloaded(std::string & path){} +void SourcesEditor::handleFboSourceAdded(std::string & name){} +void SourcesEditor::handleFboSourceRemoved(std::string & name){} +void SourcesEditor::handleFboSourceLoaded(std::string & name){} +void SourcesEditor::handleFboSourceUnloaded(std::string & name){} + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/SourcesEditor.h b/src/UserInterface/SourcesEditor.h index b56d304..c4e2f14 100644 --- a/src/UserInterface/SourcesEditor.h +++ b/src/UserInterface/SourcesEditor.h @@ -10,80 +10,82 @@ namespace ofx { namespace piMapper { + class SourcesEditor { - public: - // Default contructor that initializes media server locally, - // thus requiring to delete the media server from memory on deconstr - SourcesEditor(); - - // Alternative constructor that allows to assign external media server - SourcesEditor(MediaServer* externalMediaServer); - ~SourcesEditor(); - - void registerAppEvents(); - void unregisterAppEvents(); - - void setup(ofEventArgs& args); - void draw(); - void loadImage(string name, string path); - void disable(); - void enable(); - void setSurfaceManager(SurfaceManager* newSurfaceManager); - void setCmdManager(CmdManager * cmdManager); - - // Sets external MediaServer - void setMediaServer(MediaServer* newMediaServer); - //void selectImageSourceRadioButton(string name); - void selectSourceRadioButton(std::string& sourcePath); - - int getLoadedTexCount(); - ofTexture* getTexture(int index); - - void setImageSource(string & imagePath); - void setVideoSource(string & videoPath); - void setFboSource(string & fboName); - void clearSource(); - - private: - MediaServer* mediaServer; - SurfaceManager* surfaceManager; - RadioList* imageSelector; - RadioList* videoSelector; - RadioList* fboSelector; - CmdManager * _cmdManager; - - // Is the media server pointer local or from somewhere else? - // We use this to determine if we are allowed to clear media server locally. - bool isMediaServerExternal; - - // Init handles variable initialization in all constructors - void init(); - - // Methods for adding and removing listeners to the media server - void addMediaServerListeners(); - void removeMediaServerListeners(); - - // Handles GUI event, whenever someone has clicked on a radio button - void handleImageSelected(string & imagePath); - void handleVideoSelected(string & videoPath); - void handleFboSelected(string & fboName); - - // Careful clearing of the media server, - // clears only if the media server has been initialized locally - void clearMediaServer(); - - // MediaServer event handlers - void handleImageAdded(std::string& path); - void handleImageRemoved(std::string& path); - void handleVideoAdded(std::string& path); - void handleVideoRemoved(std::string& path); - void handleImageLoaded(std::string& path); - void handleImageUnloaded(std::string& path); - void handleFboSourceAdded(std::string& name); - void handleFboSourceRemoved(std::string& name); - void handleFboSourceLoaded(std::string& name); - void handleFboSourceUnloaded(std::string& name); - + public: + // Default contructor that initializes media server locally, + // thus requiring to delete the media server from memory on deconstr + SourcesEditor(); + + // Alternative constructor that allows to assign external media server + SourcesEditor(MediaServer * externalMediaServer); + ~SourcesEditor(); + + void registerAppEvents(); + void unregisterAppEvents(); + + void setup(ofEventArgs & args); + void draw(); + void loadImage(string name, string path); + void disable(); + void enable(); + void setSurfaceManager(SurfaceManager * newSurfaceManager); + void setCmdManager(CmdManager * cmdManager); + + // Sets external MediaServer + void setMediaServer(MediaServer * newMediaServer); + //void selectImageSourceRadioButton(string name); + void selectSourceRadioButton(std::string & sourcePath); + + int getLoadedTexCount(); + ofTexture * getTexture(int index); + + void setImageSource(string & imagePath); + void setVideoSource(string & videoPath); + void setFboSource(string & fboName); + void clearSource(); + + private: + MediaServer * mediaServer; + SurfaceManager * surfaceManager; + RadioList * imageSelector; + RadioList * videoSelector; + RadioList * fboSelector; + CmdManager * _cmdManager; + + // Is the media server pointer local or from somewhere else? + // We use this to determine if we are allowed to clear media server locally. + bool isMediaServerExternal; + + // Init handles variable initialization in all constructors + void init(); + + // Methods for adding and removing listeners to the media server + void addMediaServerListeners(); + void removeMediaServerListeners(); + + // Handles GUI event, whenever someone has clicked on a radio button + void handleImageSelected(string & imagePath); + void handleVideoSelected(string & videoPath); + void handleFboSelected(string & fboName); + + // Careful clearing of the media server, + // clears only if the media server has been initialized locally + void clearMediaServer(); + + // MediaServer event handlers + void handleImageAdded(std::string & path); + void handleImageRemoved(std::string & path); + void handleVideoAdded(std::string & path); + void handleVideoRemoved(std::string & path); + void handleImageLoaded(std::string & path); + void handleImageUnloaded(std::string & path); + void handleFboSourceAdded(std::string & name); + void handleFboSourceRemoved(std::string & name); + void handleFboSourceLoaded(std::string & name); + void handleFboSourceUnloaded(std::string & name); + }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/TextureEditor.cpp b/src/UserInterface/TextureEditor.cpp old mode 100755 new mode 100644 index 7420399..0767209 --- a/src/UserInterface/TextureEditor.cpp +++ b/src/UserInterface/TextureEditor.cpp @@ -2,240 +2,256 @@ namespace ofx { namespace piMapper { -TextureEditor::TextureEditor() { - clear(); - enable(); -} - -TextureEditor::~TextureEditor() { - clear(); - disable(); -} - -void TextureEditor::registerAppEvents() { - ofAddListener(ofEvents().update, this, &TextureEditor::update); -} - -void TextureEditor::unregisterAppEvents() { - ofRemoveListener(ofEvents().update, this, &TextureEditor::update); -} - -void TextureEditor::registerKeyEvents() { - ofAddListener(ofEvents().keyPressed, this, &TextureEditor::keyPressed); - ofAddListener(ofEvents().keyReleased, this, &TextureEditor::keyReleased); -} - -void TextureEditor::unregisterKeyEvents() { - ofRemoveListener(ofEvents().keyPressed, this, &TextureEditor::keyPressed); - ofRemoveListener(ofEvents().keyReleased, this, &TextureEditor::keyReleased); -} - -void TextureEditor::enable() { - registerAppEvents(); - registerKeyEvents(); - bShiftKeyDown = false; -} -void TextureEditor::disable() { - unregisterAppEvents(); - unregisterKeyEvents(); -} - -void TextureEditor::update(ofEventArgs& args) { - if (surface == NULL) return; - - // update surface if one of the joints is being dragged - ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(), - surface->getSource()->getTexture()->getHeight()); - - // Get selected joint index - int selectedJointIndex = 0; - bool bJointSelected = false; - for (int i = 0; i < joints.size(); i++) { - if (joints[i]->isDragged() || joints[i]->isSelected()) { - selectedJointIndex = i; - bJointSelected = true; - break; - } - } // for - - // Constrain quad texture selection - if (joints.size() == 4) { - if (bJointSelected) { - constrainJointsToQuad(selectedJointIndex); - - for (int i = 0; i < joints.size(); i++) { - surface->setTexCoord(i, joints[i]->position / textureSize); - } - } // if - } else { - if (bJointSelected) { - surface->setTexCoord(selectedJointIndex, joints[selectedJointIndex]->position / textureSize); - } - } // else -} - -void TextureEditor::keyPressed(ofKeyEventArgs& args) { - int key = args.key; - float moveStep; +TextureEditor::TextureEditor(){ + clear(); + enable(); +} + +TextureEditor::~TextureEditor(){ + clear(); + disable(); +} + +void TextureEditor::registerAppEvents(){ + ofAddListener(ofEvents().update, this, &TextureEditor::update); +} + +void TextureEditor::unregisterAppEvents(){ + ofRemoveListener(ofEvents().update, this, &TextureEditor::update); +} + +void TextureEditor::registerKeyEvents(){ + ofAddListener(ofEvents().keyPressed, this, &TextureEditor::keyPressed); + ofAddListener(ofEvents().keyReleased, this, &TextureEditor::keyReleased); +} + +void TextureEditor::unregisterKeyEvents(){ + ofRemoveListener(ofEvents().keyPressed, this, &TextureEditor::keyPressed); + ofRemoveListener(ofEvents().keyReleased, this, &TextureEditor::keyReleased); +} + +void TextureEditor::enable(){ + registerAppEvents(); + registerKeyEvents(); + bShiftKeyDown = false; +} + +void TextureEditor::disable(){ + unregisterAppEvents(); + unregisterKeyEvents(); +} + +void TextureEditor::update(ofEventArgs & args){ + if(surface == NULL){ + return; + } + + // update surface if one of the joints is being dragged + ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(), + surface->getSource()->getTexture()->getHeight()); + + // Get selected joint index + int selectedJointIndex = 0; + bool bJointSelected = false; + for(int i = 0; i < joints.size(); i++){ + if(joints[i]->isDragged() || joints[i]->isSelected()){ + selectedJointIndex = i; + bJointSelected = true; + break; + } + } // for + + // Constrain quad texture selection + if(joints.size() == 4){ + if(bJointSelected){ + constrainJointsToQuad(selectedJointIndex); + + for(int i = 0; i < joints.size(); i++){ + surface->setTexCoord(i, joints[i]->position / textureSize); + } + } // if + }else{ + if(bJointSelected){ + surface->setTexCoord(selectedJointIndex, joints[selectedJointIndex]->position / textureSize); + } + } // else +} + +void TextureEditor::keyPressed(ofKeyEventArgs & args){ + int key = args.key; + float moveStep; + + if(bShiftKeyDown){ + moveStep = 10.0f; + }else{ + moveStep = 0.5f; + } + + switch(key){ + case OF_KEY_LEFT: + moveSelection(ofVec2f(-moveStep, 0.0f)); + break; + + case OF_KEY_RIGHT: + moveSelection(ofVec2f(moveStep, 0.0f)); + break; + + case OF_KEY_UP: + moveSelection(ofVec2f(0.0f, -moveStep)); + break; + + case OF_KEY_DOWN: + moveSelection(ofVec2f(0.0f, moveStep)); + break; + + case OF_KEY_SHIFT: + bShiftKeyDown = true; + break; + } +} + +void TextureEditor::keyReleased(ofKeyEventArgs & args){ + int key = args.key; + switch(key){ + case OF_KEY_SHIFT: + bShiftKeyDown = false; + break; + } +} + +void TextureEditor::draw(){ + if(surface == NULL){ + return; + } + + // Reset default color to white + ofSetColor(255, 255, 255, 255); + drawJoints(); +} + +void TextureEditor::drawJoints(){ + for(int i = 0; i < joints.size(); i++){ + joints[i]->draw(); + } +} + +void TextureEditor::setSurface(BaseSurface * newSurface){ + surface = newSurface; + createJoints(); +} + +void TextureEditor::clear(){ + surface = NULL; + clearJoints(); +} + +void TextureEditor::createJoints(){ + if(surface == NULL){ + return; + } + clearJoints(); + vector & texCoords = surface->getTexCoords(); + ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(), + surface->getSource()->getTexture()->getHeight()); + + for(int i = 0; i < texCoords.size(); i++){ + joints.push_back(new CircleJoint()); + joints.back()->position = texCoords[i] * textureSize; + } +} + +void TextureEditor::clearJoints(){ + while(joints.size()){ + delete joints.back(); + joints.pop_back(); + } +} + +void TextureEditor::unselectAllJoints(){ + for(int i = 0; i < joints.size(); i++){ + joints[i]->unselect(); + } +} + +void TextureEditor::moveTexCoords(ofVec2f by){ + if(surface == NULL){ + return; + } + vector & texCoords = surface->getTexCoords(); + ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(), + surface->getSource()->getTexture()->getHeight()); + for(int i = 0; i < texCoords.size(); i++){ + joints[i]->position += by; + surface->setTexCoord(i, joints[i]->position / textureSize); + } +} + +void TextureEditor::stopDragJoints(){ + for(int i = 0; i < joints.size(); i++){ + joints[i]->stopDrag(); + } +} + +void TextureEditor::moveSelection(ofVec2f by){ + // check if joints selected + bool bJointSelected = false; + BaseJoint * selectedJoint; + for(int i = 0; i < joints.size(); i++){ + if(joints[i]->isSelected()){ + bJointSelected = true; + selectedJoint = joints[i]; + break; + } + } + + if(bJointSelected){ + selectedJoint->position += by; + }else{ + moveTexCoords(by); + } +} + +void TextureEditor::constrainJointsToQuad(int selectedJointIndex){ + switch(selectedJointIndex){ + case 0: + joints[1]->position = ofVec2f(joints[1]->position.x, joints[0]->position.y); + joints[2]->position = ofVec2f(joints[1]->position.x, joints[3]->position.y); + joints[3]->position = ofVec2f(joints[0]->position.x, joints[3]->position.y); + break; + + case 1: + joints[0]->position = ofVec2f(joints[0]->position.x, joints[1]->position.y); + joints[2]->position = ofVec2f(joints[1]->position.x, joints[2]->position.y); + joints[3]->position = ofVec2f(joints[0]->position.x, joints[2]->position.y); + break; + + case 2: + joints[1]->position = ofVec2f(joints[2]->position.x, joints[1]->position.y); + joints[3]->position = ofVec2f(joints[3]->position.x, joints[2]->position.y); + joints[0]->position = ofVec2f(joints[3]->position.x, joints[1]->position.y); + break; + + case 3: + joints[0]->position = ofVec2f(joints[3]->position.x, joints[0]->position.y); + joints[2]->position = ofVec2f(joints[2]->position.x, joints[3]->position.y); + joints[1]->position = ofVec2f(joints[2]->position.x, joints[0]->position.y); + break; + } // switch +} + +CircleJoint * TextureEditor::hitTestJoints(ofVec2f pos){ + for(int i = 0; i < joints.size(); i++){ + if(joints[i]->hitTest(pos)){ + return joints[i]; + } + } + return NULL; +} + +vector & TextureEditor::getJoints(){ + return joints; +} - if (bShiftKeyDown) - moveStep = 10.0f; - else - moveStep = 0.5f; - - switch (key) { - case OF_KEY_LEFT: - moveSelection(ofVec2f(-moveStep, 0.0f)); - break; - case OF_KEY_RIGHT: - moveSelection(ofVec2f(moveStep, 0.0f)); - break; - case OF_KEY_UP: - moveSelection(ofVec2f(0.0f, -moveStep)); - break; - case OF_KEY_DOWN: - moveSelection(ofVec2f(0.0f, moveStep)); - break; - case OF_KEY_SHIFT: - bShiftKeyDown = true; - break; - } -} - -void TextureEditor::keyReleased(ofKeyEventArgs& args) { - int key = args.key; - switch (key) { - case OF_KEY_SHIFT: - bShiftKeyDown = false; - break; - } -} - -void TextureEditor::draw() { - if (surface == NULL) return; - - // Reset default color to white - ofSetColor(255, 255, 255, 255); - drawJoints(); -} - -void TextureEditor::drawJoints() { - for (int i = 0; i < joints.size(); i++) { - joints[i]->draw(); - } -} - -void TextureEditor::setSurface(BaseSurface* newSurface) { - surface = newSurface; - createJoints(); -} - -void TextureEditor::clear() { - surface = NULL; - clearJoints(); -} - -void TextureEditor::createJoints() { - if (surface == NULL) return; - clearJoints(); - vector& texCoords = surface->getTexCoords(); - ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(), - surface->getSource()->getTexture()->getHeight()); - - for (int i = 0; i < texCoords.size(); i++) { - joints.push_back(new CircleJoint()); - joints.back()->position = texCoords[i] * textureSize; - } -} - -void TextureEditor::clearJoints() { - while (joints.size()) { - delete joints.back(); - joints.pop_back(); - } -} - -void TextureEditor::unselectAllJoints() { - for (int i = 0; i < joints.size(); i++) { - joints[i]->unselect(); - } -} - -void TextureEditor::moveTexCoords(ofVec2f by) { - if (surface == NULL) return; - vector& texCoords = surface->getTexCoords(); - ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(), - surface->getSource()->getTexture()->getHeight()); - for (int i = 0; i < texCoords.size(); i++) { - joints[i]->position += by; - surface->setTexCoord(i, joints[i]->position / textureSize); - } -} - -void TextureEditor::stopDragJoints() { - for (int i = 0; i < joints.size(); i++) { - joints[i]->stopDrag(); - } -} - -void TextureEditor::moveSelection(ofVec2f by) { - // check if joints selected - bool bJointSelected = false; - BaseJoint* selectedJoint; - for (int i = 0; i < joints.size(); i++) { - if (joints[i]->isSelected()) { - bJointSelected = true; - selectedJoint = joints[i]; - break; - } - } - - if (bJointSelected) { - selectedJoint->position += by; - } else { - moveTexCoords(by); - } -} - -void TextureEditor::constrainJointsToQuad(int selectedJointIndex) -{ - switch (selectedJointIndex) { - case 0: - joints[1]->position = ofVec2f(joints[1]->position.x, joints[0]->position.y); - joints[2]->position = ofVec2f(joints[1]->position.x, joints[3]->position.y); - joints[3]->position = ofVec2f(joints[0]->position.x, joints[3]->position.y); - break; - case 1: - joints[0]->position = ofVec2f(joints[0]->position.x, joints[1]->position.y); - joints[2]->position = ofVec2f(joints[1]->position.x, joints[2]->position.y); - joints[3]->position = ofVec2f(joints[0]->position.x, joints[2]->position.y); - break; - case 2: - joints[1]->position = ofVec2f(joints[2]->position.x, joints[1]->position.y); - joints[3]->position = ofVec2f(joints[3]->position.x, joints[2]->position.y); - joints[0]->position = ofVec2f(joints[3]->position.x, joints[1]->position.y); - break; - case 3: - joints[0]->position = ofVec2f(joints[3]->position.x, joints[0]->position.y); - joints[2]->position = ofVec2f(joints[2]->position.x, joints[3]->position.y); - joints[1]->position = ofVec2f(joints[2]->position.x, joints[0]->position.y); - break; - } // switch -} - -CircleJoint* TextureEditor::hitTestJoints(ofVec2f pos) { - for (int i = 0; i < joints.size(); i++) { - if (joints[i]->hitTest(pos)) { - return joints[i]; - } - } - return NULL; -} - - vector & TextureEditor::getJoints(){ - return joints; - } - -} -} \ No newline at end of file +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/UserInterface/TextureEditor.h b/src/UserInterface/TextureEditor.h index e09bfdf..6fc3098 100644 --- a/src/UserInterface/TextureEditor.h +++ b/src/UserInterface/TextureEditor.h @@ -7,39 +7,43 @@ namespace ofx { namespace piMapper { + class TextureEditor { - public: - TextureEditor(); - ~TextureEditor(); - - void registerAppEvents(); - void unregisterAppEvents(); - void registerKeyEvents(); - void unregisterKeyEvents(); - void enable(); - void disable(); - - void update(ofEventArgs& args); - void keyPressed(ofKeyEventArgs& args); - void keyReleased(ofKeyEventArgs& args); - void draw(); - void drawJoints(); - void setSurface(BaseSurface* newSurface); - void clear(); - void createJoints(); - void clearJoints(); - void unselectAllJoints(); - void moveTexCoords(ofVec2f by); - void stopDragJoints(); - void moveSelection(ofVec2f by); - void constrainJointsToQuad(int selectedJointIndex); - CircleJoint* hitTestJoints(ofVec2f pos); - vector & getJoints(); - - private: - BaseSurface* surface; - vector joints; - bool bShiftKeyDown; + + public: + TextureEditor(); + ~TextureEditor(); + + void registerAppEvents(); + void unregisterAppEvents(); + void registerKeyEvents(); + void unregisterKeyEvents(); + void enable(); + void disable(); + + void update(ofEventArgs & args); + void keyPressed(ofKeyEventArgs & args); + void keyReleased(ofKeyEventArgs & args); + void draw(); + void drawJoints(); + void setSurface(BaseSurface * newSurface); + void clear(); + void createJoints(); + void clearJoints(); + void unselectAllJoints(); + void moveTexCoords(ofVec2f by); + void stopDragJoints(); + void moveSelection(ofVec2f by); + void constrainJointsToQuad(int selectedJointIndex); + CircleJoint * hitTestJoints(ofVec2f pos); + vector & getJoints(); + + private: + BaseSurface * surface; + vector joints; + bool bShiftKeyDown; + }; -} -} \ No newline at end of file + +} // namespace piMapper +} // namespace ofx \ No newline at end of file diff --git a/src/ofxPiMapper.cpp b/src/ofxPiMapper.cpp index d046dc4..c9a1b3c 100644 --- a/src/ofxPiMapper.cpp +++ b/src/ofxPiMapper.cpp @@ -1,117 +1,117 @@ #include "ofxPiMapper.h" -ofxPiMapper::ofxPiMapper() { - bShowInfo = false; - isSetUp = false; +ofxPiMapper::ofxPiMapper(){ + bShowInfo = false; + isSetUp = false; } -void ofxPiMapper::setup() { - ofLogNotice("ofxPiMapper") << "Setting up..."; - - surfaceManager.setMediaServer(&mediaServer); - gui.setMediaServer(&mediaServer); - gui.setCmdManager(&cmdManager); - - if (ofFile::doesFileExist(PIMAPPER_USER_SURFACES_XML_FILE)){ - ofLogNotice("ofxPiMapper") << "Loading user surfaces from " << PIMAPPER_USER_SURFACES_XML_FILE; - surfaceManager.loadXmlSettings(PIMAPPER_USER_SURFACES_XML_FILE); - } else { - ofLogNotice("ofxPiMapper") << "Loading default surfaces from " << PIMAPPER_DEF_SURFACES_XML_FILE; - surfaceManager.loadXmlSettings(PIMAPPER_DEF_SURFACES_XML_FILE); - } - - gui.setSurfaceManager(&surfaceManager); - isSetUp = true; - ofLogNotice("ofxPiMapper") << "Done setting up"; - _application = new ofx::piMapper::Application(this); +void ofxPiMapper::setup(){ + ofLogNotice("ofxPiMapper") << "Setting up..."; + + surfaceManager.setMediaServer(&mediaServer); + gui.setMediaServer(&mediaServer); + gui.setCmdManager(&cmdManager); + + if(ofFile::doesFileExist(PIMAPPER_USER_SURFACES_XML_FILE)){ + ofLogNotice("ofxPiMapper") << "Loading user surfaces from " << PIMAPPER_USER_SURFACES_XML_FILE; + surfaceManager.loadXmlSettings(PIMAPPER_USER_SURFACES_XML_FILE); + }else{ + ofLogNotice("ofxPiMapper") << "Loading default surfaces from " << PIMAPPER_DEF_SURFACES_XML_FILE; + surfaceManager.loadXmlSettings(PIMAPPER_DEF_SURFACES_XML_FILE); + } + + gui.setSurfaceManager(&surfaceManager); + isSetUp = true; + ofLogNotice("ofxPiMapper") << "Done setting up"; + _application = new ofx::piMapper::Application(this); } -void ofxPiMapper::draw() { - if (!isSetUp) { - return; - } - - gui.draw(); - - if (bShowInfo){ - stringstream ss; - ss << "There are 4 modes:\n\n"; - ss << " 1. Presentation mode\n"; - ss << " 2. Texture mapping mode\n"; - ss << " 3. Projection mapping mode\n"; - ss << " 4. Source selection mode\n\n"; - ss << "You can switch between the modes by using <1>, <2>, <3> and <4> " - "keys on the keyboard.\n\n"; - ss << "Press to add new triangle surface\n"; - ss << "Press to add new quad surface\n"; - ss << "Press to save the composition\n"; - ss << "Press to toggle fullscreen\n"; - ss << "Press to hide this message"; - ofDrawBitmapStringHighlight(ss.str(), 10, 20, - ofColor(0, 0, 0, 100), - ofColor(255, 255, 255, 200)); - } - - _application->draw(); +void ofxPiMapper::draw(){ + if(!isSetUp){ + return; + } + + gui.draw(); + + if(bShowInfo){ + stringstream ss; + ss << "There are 4 modes:\n\n"; + ss << " 1. Presentation mode\n"; + ss << " 2. Texture mapping mode\n"; + ss << " 3. Projection mapping mode\n"; + ss << " 4. Source selection mode\n\n"; + ss << "You can switch between the modes by using <1>, <2>, <3> and <4> " + "keys on the keyboard.\n\n"; + ss << "Press to add new triangle surface\n"; + ss << "Press to add new quad surface\n"; + ss << "Press to save the composition\n"; + ss << "Press to toggle fullscreen\n"; + ss << "Press to hide this message"; + ofDrawBitmapStringHighlight(ss.str(), 10, 20, + ofColor(0, 0, 0, 100), + ofColor(255, 255, 255, 200)); + } + + _application->draw(); } // draw -void ofxPiMapper::registerFboSource(ofx::piMapper::FboSource & fboSource) { - mediaServer.addFboSource(fboSource); +void ofxPiMapper::registerFboSource(ofx::piMapper::FboSource & fboSource){ + mediaServer.addFboSource(fboSource); } -void ofxPiMapper::addTriangleSurface() { - int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; - - vector vertices; - float margin = 50.0f; - vertices.push_back(ofVec2f((float)ofGetWidth() / 2.0f, margin)); - vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); - vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); - - vector texCoords; - texCoords.push_back(ofVec2f(0.5f, 0.0f)); - texCoords.push_back(ofVec2f(1.0f, 1.0f)); - texCoords.push_back(ofVec2f(0.0f, 1.0f)); - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // Select this surface right away - surfaceManager.selectSurface(surfaceManager.size() - 1); +void ofxPiMapper::addTriangleSurface(){ + int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; + + vector vertices; + float margin = 50.0f; + vertices.push_back(ofVec2f((float)ofGetWidth() / 2.0f, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); + vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); + + vector texCoords; + texCoords.push_back(ofVec2f(0.5f, 0.0f)); + texCoords.push_back(ofVec2f(1.0f, 1.0f)); + texCoords.push_back(ofVec2f(0.0f, 1.0f)); + surfaceManager.addSurface(surfaceType, vertices, texCoords); + + // Select this surface right away + surfaceManager.selectSurface(surfaceManager.size() - 1); } // addTriangleSurface -void ofxPiMapper::addQuadSurface() { - int surfaceType = ofx::piMapper::SurfaceType::QUAD_SURFACE; - - vector vertices; - float margin = 50.0f; - vertices.push_back(ofVec2f(margin, margin)); - vertices.push_back(ofVec2f((float)ofGetWidth() - margin, margin)); - vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); - vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); - - vector texCoords; - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); - - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // select this surface right away - surfaceManager.selectSurface(surfaceManager.size() - 1); +void ofxPiMapper::addQuadSurface(){ + int surfaceType = ofx::piMapper::SurfaceType::QUAD_SURFACE; + + vector vertices; + float margin = 50.0f; + vertices.push_back(ofVec2f(margin, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); + vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); + + vector texCoords; + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); + + surfaceManager.addSurface(surfaceType, vertices, texCoords); + + // select this surface right away + surfaceManager.selectSurface(surfaceManager.size() - 1); } // addQuadSurface -ofx::piMapper::CmdManager & ofxPiMapper::getCmdManager() { - return cmdManager; +ofx::piMapper::CmdManager & ofxPiMapper::getCmdManager(){ + return cmdManager; } -ofx::piMapper::SurfaceManagerGui & ofxPiMapper::getGui() { - return gui; +ofx::piMapper::SurfaceManagerGui & ofxPiMapper::getGui(){ + return gui; } -ofx::piMapper::MediaServer & ofxPiMapper::getMediaServer() { - return mediaServer; +ofx::piMapper::MediaServer & ofxPiMapper::getMediaServer(){ + return mediaServer; } -ofx::piMapper::SurfaceManager & ofxPiMapper::getSurfaceManager() { - return surfaceManager; +ofx::piMapper::SurfaceManager & ofxPiMapper::getSurfaceManager(){ + return surfaceManager; } \ No newline at end of file diff --git a/src/ofxPiMapper.h b/src/ofxPiMapper.h index ead239a..dd5a431 100644 --- a/src/ofxPiMapper.h +++ b/src/ofxPiMapper.h @@ -8,41 +8,49 @@ #include "BaseCmd.h" #include "CmdManager.h" #include "RmSurfaceCmd.h" -#include "Application.h" +#include "Application.h" #define PIMAPPER_DEF_SURFACES_XML_FILE "defaultSurfaces.xml" #define PIMAPPER_USER_SURFACES_XML_FILE "surfaces.xml" namespace ofx { - namespace piMapper { - class Application; - } +namespace piMapper { +class Application; +} } class ofxPiMapper { - public: - ofxPiMapper(); - - void setup(); - void draw(); - void registerFboSource(ofx::piMapper::FboSource & fboSource); - void addTriangleSurface(); - void addQuadSurface(); - void showInfo() { bShowInfo = true; }; - void hideInfo() { bShowInfo = false; }; - void toggleInfo() { bShowInfo = !bShowInfo; } - - ofx::piMapper::CmdManager & getCmdManager(); - ofx::piMapper::SurfaceManagerGui & getGui(); - ofx::piMapper::MediaServer & getMediaServer(); - ofx::piMapper::SurfaceManager & getSurfaceManager(); - ofx::piMapper::CmdManager cmdManager; - ofx::piMapper::SurfaceManager surfaceManager; - - private: - bool isSetUp; - bool bShowInfo; - ofx::piMapper::MediaServer mediaServer; - ofx::piMapper::SurfaceManagerGui gui; - ofx::piMapper::Application * _application; + + public: + ofxPiMapper(); + + void setup(); + void draw(); + void registerFboSource(ofx::piMapper::FboSource & fboSource); + void addTriangleSurface(); + void addQuadSurface(); + void showInfo(){ + bShowInfo = true; + } + void hideInfo(){ + bShowInfo = false; + } + void toggleInfo(){ + bShowInfo = !bShowInfo; + } + + ofx::piMapper::CmdManager & getCmdManager(); + ofx::piMapper::SurfaceManagerGui & getGui(); + ofx::piMapper::MediaServer & getMediaServer(); + ofx::piMapper::SurfaceManager & getSurfaceManager(); + ofx::piMapper::CmdManager cmdManager; + ofx::piMapper::SurfaceManager surfaceManager; + + private: + bool isSetUp; + bool bShowInfo; + ofx::piMapper::MediaServer mediaServer; + ofx::piMapper::SurfaceManagerGui gui; + ofx::piMapper::Application * _application; + }; \ No newline at end of file