├── .gitignore ├── README.md ├── example-ofxMtlMapping2D ├── addons.make ├── bin │ └── data │ │ ├── .gitkeep │ │ ├── GUI │ │ ├── NewMedia Fett.ttf │ │ ├── contract.png │ │ ├── edit.png │ │ ├── expand.png │ │ ├── file-down.png │ │ ├── file-up.png │ │ ├── grid.png │ │ ├── mask.png │ │ ├── projo.png │ │ ├── quad.png │ │ ├── texture.png │ │ └── triangle.png │ │ └── mapping │ │ ├── controls │ │ ├── ReplicaBold.ttf │ │ └── mapping.xml │ │ └── xml │ │ └── shapes.xml └── src │ ├── main.cpp │ ├── testApp.cpp │ └── testApp.h ├── license.md ├── ofxaddons_thumbnail.png └── src ├── controls ├── ofxMtlMapping2DControls.cpp └── ofxMtlMapping2DControls.h ├── ofxMtlMapping2D.cpp ├── ofxMtlMapping2D.h ├── ofxMtlMapping2DMode.h ├── ofxMtlMapping2DShapeType.h ├── ofxMtlMapping2DShapes.cpp ├── ofxMtlMapping2DShapes.h ├── settings ├── ofxMtlMapping2DSettings.cpp └── ofxMtlMapping2DSettings.h ├── shapes ├── ofxMtlMapping2DGrid.cpp ├── ofxMtlMapping2DGrid.h ├── ofxMtlMapping2DInput.cpp ├── ofxMtlMapping2DInput.h ├── ofxMtlMapping2DMask.cpp ├── ofxMtlMapping2DMask.h ├── ofxMtlMapping2DPolygon.cpp ├── ofxMtlMapping2DPolygon.h ├── ofxMtlMapping2DQuad.cpp ├── ofxMtlMapping2DQuad.h ├── ofxMtlMapping2DShape.cpp ├── ofxMtlMapping2DShape.h ├── ofxMtlMapping2DTriangle.cpp ├── ofxMtlMapping2DTriangle.h ├── ofxMtlMapping2DVertex.cpp └── ofxMtlMapping2DVertex.h └── utils ├── homography └── homography.h └── mtlUtils.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Some general ignore patterns 2 | 3 | */bin/* 4 | !*/bin/data/ 5 | # for bin folder in root 6 | /bin/* 7 | !/bin/data/ 8 | 9 | build/ 10 | obj/ 11 | *.o 12 | Debug*/ 13 | Release*/ 14 | *.mode* 15 | *.app/ 16 | *.pyc 17 | .svn/ 18 | 19 | # IDE-specific ignore patterns (e.g. user-specific files) 20 | 21 | #XCode 22 | *.pbxuser 23 | *.perspective 24 | *.perspectivev3 25 | *.mode1v3 26 | *.mode2v3 27 | #XCode 4 28 | xcuserdata 29 | *.xcworkspace 30 | 31 | #Code::Blocks 32 | *.depend 33 | *.layout 34 | *.cbTemp 35 | 36 | #Visual Studio 37 | *.sdf 38 | *.opensdf 39 | *.suo 40 | ipch/ 41 | 42 | #Eclipse 43 | .metadata 44 | local.properties 45 | .externalToolBuilders 46 | 47 | # OS-specific ignore patterns 48 | 49 | #Linux 50 | *~ 51 | # KDE 52 | .directory 53 | 54 | #OSX 55 | .DS_Store 56 | *.swp 57 | *~.nib 58 | # Thumbnails 59 | ._* 60 | 61 | #Windows 62 | # Windows image file caches 63 | Thumbs.db 64 | # Folder config file 65 | Desktop.ini 66 | 67 | #Android 68 | .csettings 69 | 70 | # Packages 71 | # it's better to unpack these files and commit the raw source 72 | # git has its own built in compression methods 73 | *.7z 74 | *.dmg 75 | *.gz 76 | *.iso 77 | *.jar 78 | *.rar 79 | *.tar 80 | *.zip 81 | 82 | # Logs and databases 83 | *.log 84 | *.sql 85 | *.sqlite 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ofxMtlMapping2D 2 | ===================================== 3 | 4 | Introduction 5 | ------------ 6 | C++ openFrameworks addon to achieve 2D projection-mapping of textures to physical objects. Each instance of ofxMtlMapping2D has its own FBO to draw content into. Each created shape has an output polygon used for mapping, and an input polygon defining the texture coordinates to be used. 7 | 8 | **Output mode** 9 | ![output mode](http://www.morethanlogic.com/ofxMtl/ofxMtlMapping2D/ofxMtlMapping2D_output.png) 10 | 11 | **Input mode** 12 | ![input mode](http://www.morethanlogic.com/ofxMtl/ofxMtlMapping2D/ofxMtlMapping2D_input.png) 13 | 14 | Some projects using this addon... 15 | ------------ 16 | ... or variations of it. 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
EchosBarcode
Open houseSam Robert's Band
27 | 28 | Licence 29 | ------- 30 | The code in this repository is available under the [MIT License](https://en.wikipedia.org/wiki/MIT_License) 31 | Copyright (c) 2013 Hugues Bruyère, Elie Zananiri, [www.morethanlogic.com](http://www.morethanlogic.com) | [www.departement.ca](http://www.departement.ca) 32 | More Than Logic 33 | 34 | Installation 35 | ------------ 36 | Copy to your openFrameworks/addons folder. 37 | 38 | Dependencies 39 | ------------ 40 | * [ofxMSAInteractiveObject](https://github.com/memo/ofxMSAInteractiveObject) 41 | * [ofxUI](https://github.com/rezaali/ofxUI) 42 | * ofxXmlSettings 43 | * homography.h by Arturo Castro (included in this repo) 44 | 45 | Compatibility 46 | ------------ 47 | OF080 -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/addons.make: -------------------------------------------------------------------------------- 1 | ofxXmlSettings 2 | ofxUI 3 | ofxMSAInteractiveObject 4 | -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/.gitkeep -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/NewMedia Fett.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/NewMedia Fett.ttf -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/contract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/contract.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/edit.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/expand.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/file-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/file-down.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/file-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/file-up.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/grid.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/mask.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/projo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/projo.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/quad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/quad.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/texture.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/GUI/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/GUI/triangle.png -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/mapping/controls/ReplicaBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/example-ofxMtlMapping2D/bin/data/mapping/controls/ReplicaBold.ttf -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/mapping/controls/mapping.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 3 | MAPPING:EDIT_SHAPES 4 | 1 5 | 6 | 7 | 20 8 | MAPPING:SAVE 9 | 0 10 | 11 | 12 | 20 13 | MAPPING_MODE:OUTPUT 14 | 1 15 | 16 | 17 | 20 18 | MAPPING_MODE:INPUT 19 | 0 20 | 21 | 22 | 20 23 | MAPPING:CREATE_NEW_QUAD 24 | 0 25 | 26 | 27 | 20 28 | MAPPING:CREATE_NEW_TRAINGLE 29 | 0 30 | 31 | -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/bin/data/mapping/xml/shapes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | quad 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | quad 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | quad 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ofMain.h" 2 | #include "testApp.h" 3 | #include "ofAppGlutWindow.h" 4 | 5 | //======================================================================== 6 | int main( ){ 7 | 8 | ofAppGlutWindow window; 9 | window.setGlutDisplayString("rgba double samples>=4"); 10 | ofSetupOpenGL(&window, 1024, 500, OF_WINDOW); // <-------- setup the GL context 11 | 12 | // this kicks off the running of my app 13 | // can be OF_WINDOW or OF_FULLSCREEN 14 | // pass in width and height too: 15 | ofRunApp( new testApp()); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/src/testApp.cpp: -------------------------------------------------------------------------------- 1 | #include "testApp.h" 2 | 3 | //-------------------------------------------------------------- 4 | void testApp::setup(){ 5 | ofSetFrameRate(30); 6 | ofBackground(50); 7 | 8 | // ---- 9 | _mapping = new ofxMtlMapping2D(); 10 | _mapping->init(ofGetWidth(), ofGetHeight(), "mapping/xml/shapes.xml", "mapping/controls/mapping.xml"); 11 | } 12 | 13 | //-------------------------------------------------------------- 14 | void testApp::update(){ 15 | 16 | _mapping->update(); 17 | 18 | } 19 | 20 | //-------------------------------------------------------------- 21 | void testApp::draw(){ 22 | // ---- 23 | _mapping->bind(); 24 | 25 | // draw a test pattern 26 | _mapping->chessBoard(); 27 | 28 | _mapping->unbind(); 29 | 30 | 31 | //-------- mapping of the towers/shapes 32 | _mapping->draw(); 33 | //_mapping->drawFbo(); 34 | 35 | 36 | // ofBeginShape(); 37 | // ofFill(); 38 | // ofSetColor(0, 255, 0); 39 | // for (int i = 0; i < _mapping->getMaskShapes()[0]->size(); i++) { 40 | // ofVertex(_mapping->getMaskShapes()[0]->getVertices()[i].x, _mapping->getMaskShapes()[0]->getVertices()[i].y); 41 | // } 42 | // ofEndShape(true); 43 | 44 | 45 | // Draw some instructions. 46 | /* 47 | ofSetColor(0); 48 | ofDrawBitmapString("'m' open the mapping controls.\n", 20, 20); 49 | */ 50 | } 51 | 52 | //-------------------------------------------------------------- 53 | void testApp::keyPressed(int key){ 54 | } 55 | 56 | //-------------------------------------------------------------- 57 | void testApp::keyReleased(int key){ 58 | 59 | } 60 | 61 | //-------------------------------------------------------------- 62 | void testApp::mouseMoved(int x, int y ){ 63 | 64 | } 65 | 66 | //-------------------------------------------------------------- 67 | void testApp::mouseDragged(int x, int y, int button){ 68 | 69 | } 70 | 71 | //-------------------------------------------------------------- 72 | void testApp::mousePressed(int x, int y, int button){ 73 | } 74 | 75 | //-------------------------------------------------------------- 76 | void testApp::mouseReleased(int x, int y, int button){ 77 | 78 | } 79 | 80 | //-------------------------------------------------------------- 81 | void testApp::windowResized(int w, int h){ 82 | 83 | } 84 | 85 | //-------------------------------------------------------------- 86 | void testApp::gotMessage(ofMessage msg){ 87 | 88 | } 89 | 90 | //-------------------------------------------------------------- 91 | void testApp::dragEvent(ofDragInfo dragInfo){ 92 | 93 | } -------------------------------------------------------------------------------- /example-ofxMtlMapping2D/src/testApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxMtlMapping2D.h" 5 | 6 | class testApp : public ofBaseApp{ 7 | 8 | public: 9 | void setup(); 10 | void update(); 11 | void draw(); 12 | 13 | void keyPressed (int key); 14 | void keyReleased(int key); 15 | void mouseMoved(int x, int y ); 16 | void mouseDragged(int x, int y, int button); 17 | void mousePressed(int x, int y, int button); 18 | void mouseReleased(int x, int y, int button); 19 | void windowResized(int w, int h); 20 | void dragEvent(ofDragInfo dragInfo); 21 | void gotMessage(ofMessage msg); 22 | 23 | private: 24 | ofxMtlMapping2D* _mapping; 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The code in this repository is available under the [MIT License](https://secure.wikimedia.org/wikipedia/en/wiki/Mit_license). 2 | 3 | Copyright (c) 2012 Hugues Bruyère, Elie Zananiri, [www.morethanlogic.com](http://www.morethanlogic.com) | [www.departement.ca](http://www.departement.ca) 4 | More Than Logic 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 7 | 8 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /ofxaddons_thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morethanlogic/ofxMtlMapping2D/2eebd22eb1d115b5c78186c7c3b4921f79ddc134/ofxaddons_thumbnail.png -------------------------------------------------------------------------------- /src/controls/ofxMtlMapping2DControls.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DControls.h" 2 | #include "ofxMtlMapping2DSettings.h" 3 | #include "ofxMtlMapping2DShape.h" 4 | #include "ofxMtlMapping2DShapes.h" 5 | #include "ofxMtlMapping2DGrid.h" 6 | 7 | #include "ofMain.h" 8 | 9 | //-------------------------------------------------------------- 10 | ofxMtlMapping2DControls * ofxMtlMapping2DControls::_mapping2DControls = NULL; 11 | 12 | //-------------------------------------------------------------- 13 | ofxMtlMapping2DControls * ofxMtlMapping2DControls::mapping2DControls(string xmlFilePath) 14 | { 15 | if (_mapping2DControls == NULL) { 16 | _mapping2DControls = new ofxMtlMapping2DControls(kControlsMappingToolsPanelWidth, xmlFilePath); 17 | } 18 | return _mapping2DControls; 19 | } 20 | 21 | //-------------------------------------------------------------- 22 | ofxMtlMapping2DControls * ofxMtlMapping2DControls::mapping2DControls() 23 | { 24 | if (_mapping2DControls == NULL) { 25 | ofLog(OF_LOG_WARNING, "ofxMtlMapping2DControls uses a default path to an xml file for saving and loading settings!"); 26 | _mapping2DControls = new ofxMtlMapping2DControls(kControlsMappingToolsPanelWidth, "mapping/controls/mapping.xml"); 27 | } 28 | return _mapping2DControls; 29 | } 30 | 31 | //-------------------------------------------------------------- 32 | ofxMtlMapping2DControls::ofxMtlMapping2DControls(int width, const string& file) 33 | { 34 | // ---- Shapes list 35 | // set default values 36 | _selectedShapeId = -1; 37 | _selectedShapeChanged = false; 38 | shapeCounter = 0; 39 | 40 | _shapesListCanvas = new ofxUIScrollableCanvas(width, 0, width, ofGetHeight()); 41 | _shapesListCanvas->setScrollArea(width, 0, kControlsMappingShapesListPanelWidth, ofGetHeight()); 42 | _shapesListCanvas->setScrollableDirections(false, true); 43 | _shapesListCanvas->setColorBack(ofColor(0, 210, 255, 90)); 44 | _shapesListCanvas->autoSizeToFitWidgets(); 45 | 46 | ofAddListener(_shapesListCanvas->newGUIEvent, this, &ofxMtlMapping2DControls::shapesListUiEvent); 47 | 48 | 49 | // --- Grid settings 50 | int gridSettingCanvasWidth = 200.0f; 51 | _gridSettingsCanvas = new ofxUICanvas(); 52 | _gridSettingsCanvas->setPosition(width, ofGetHeight() - 90); 53 | _gridSettingsCanvas->setWidth(gridSettingCanvasWidth); 54 | _gridSettingsCanvas->setColorFill(ofxUIColor(200)); 55 | _gridSettingsCanvas->setColorFillHighlight(ofxUIColor(255)); 56 | _gridSettingsCanvas->setColorBack(ofColor(0, 210, 255, 90)); 57 | 58 | ofxUISlider *nSlider; 59 | _gridSettingsCanvas->addLabel("GRID SETTINGS"); 60 | nSlider = _gridSettingsCanvas->addSlider("NB COLS", 1.0, 20.0, &ofxMtlMapping2DSettings::gridDefaultNbCols); 61 | nSlider->setIncrement(1.0f); 62 | nSlider = _gridSettingsCanvas->addSlider("NB ROWS", 1.0, 20.0, &ofxMtlMapping2DSettings::gridDefaultNbRows); 63 | nSlider->setIncrement(1.0f); 64 | 65 | _gridSettingsCanvas->autoSizeToFitWidgets(); 66 | ofAddListener(_gridSettingsCanvas->newGUIEvent, this, &ofxMtlMapping2DControls::gridSettingsListUiEvent); 67 | _gridSettingsCanvas->disable(); 68 | 69 | // ---- Tool box 70 | shapeTypesAsString[MAPPING_2D_SHAPE_QUAD] = "quad"; 71 | shapeTypesAsString[MAPPING_2D_SHAPE_GRID] = "grid"; 72 | shapeTypesAsString[MAPPING_2D_SHAPE_TRIANGLE] = "triangle"; 73 | shapeTypesAsString[MAPPING_2D_SHAPE_MASK] = "mask"; 74 | 75 | // set default values 76 | _saveMapping = false; 77 | _loadMapping = false; 78 | _editShapes = false; 79 | _createNewQuad = false; 80 | _createNewGrid = false; 81 | _createNewTriangle = false; 82 | _createNewMask = false; 83 | _showShapesId = true; 84 | _mappingModeChanged = true; // initialized to true so that when the app launch the 'shapes' are correctly setted. 85 | _mappingMode = MAPPING_MODE_OUTPUT; 86 | 87 | 88 | static const int kWidgetWidth = width - 16; 89 | 90 | 91 | _toolsCanvas = new ofxUIScrollableCanvas(0, 0, width, ofGetHeight()); 92 | //must have modified ofxUI 93 | //_toolsCanvas->setStickyDistance(30.0f); 94 | _toolsCanvas->setScrollableDirections(false, true); 95 | _toolsCanvas->setColorBack(ofColor(0, 210, 255, 130)); 96 | 97 | _file = file; 98 | 99 | 100 | // --- Fullscreen 101 | _fullscreenExpandIcon.loadImage("GUI/expand.png"); 102 | _fullscreenContractIcon.loadImage("GUI/contract.png"); 103 | 104 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, false, "GUI/expand.png", kSettingMappingFullscreen)); 105 | 106 | // Edit 107 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, false, "GUI/edit.png", kSettingMappingEditShapes)); 108 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, false, "GUI/file-down.png", kSettingMappingSave)); 109 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, false, "GUI/file-up.png", kSettingMappingLoad)); 110 | 111 | 112 | // add mapping controls Output / Input 113 | ofxUISpacer *spacer = new ofxUISpacer(kWidgetWidth, kSpacerHeight); 114 | spacer->setDrawFill(false); 115 | 116 | _toolsCanvas->addWidgetDown(spacer); 117 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, false, "GUI/projo.png", kSettingMappingModeOutput)); 118 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, false, "GUI/texture.png", kSettingMappingModeInput)); 119 | 120 | 121 | // add mapping shape controls 122 | if (ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled) { 123 | _toolsCanvas->addWidgetDown(spacer); 124 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, _createNewQuad, "GUI/quad.png", kSettingMappingCreateNewQuad)); 125 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, _createNewGrid, "GUI/grid.png", kSettingMappingCreateNewGrid)); 126 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, _createNewTriangle, "GUI/triangle.png", kSettingMappingCreateNewTriangle)); 127 | _toolsCanvas->addWidgetDown(new ofxUIImageToggle(kToggleSize, kToggleSize, _createNewMask, "GUI/mask.png", kSettingMappingCreateNewMask)); 128 | } 129 | 130 | // add mapping shape's details 131 | // _toolsCanvas->addWidgetDown(spacer); 132 | // _toolsCanvas->addWidgetDown(new ofxUILabel("SHAPE DATA", OFX_UI_FONT_MEDIUM)); 133 | // _toolsCanvas->addWidgetDown(new ofxUIToggle(kToggleSize, kToggleSize, _editShapes, kSettingMappingShowShapesId)); 134 | 135 | 136 | // ---- 137 | ofAddListener(_toolsCanvas->newGUIEvent, this, &ofxMtlMapping2DControls::toolsUiEvent); 138 | 139 | load(); 140 | 141 | if (getToggleValue(kSettingMappingModeOutput)) { 142 | _mappingMode = MAPPING_MODE_OUTPUT; 143 | } else if (getToggleValue(kSettingMappingModeInput)) { 144 | _mappingMode = MAPPING_MODE_INPUT; 145 | } 146 | 147 | // --- 148 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingEditShapes))->setValue(false); 149 | setUIShapeEditingState(false); 150 | } 151 | 152 | 153 | #pragma mark - 154 | #pragma mark Tool Box 155 | 156 | //-------------------------------------------------------------- 157 | void ofxMtlMapping2DControls::toolsUiEvent(ofxUIEventArgs &event) 158 | { 159 | string name = event.widget->getName(); 160 | 161 | if (name == kSettingMappingFullscreen) { 162 | ofSetFullscreen(getToggleValue(name)); 163 | } 164 | 165 | 166 | // ---- 167 | else if (name == kSettingMappingSave) { 168 | _saveMapping = getToggleValue(name); 169 | } 170 | else if (name == kSettingMappingLoad) { 171 | _loadMapping = getToggleValue(name); 172 | } 173 | 174 | // ---- Editing 175 | else if (name == kSettingMappingEditShapes) { 176 | setUIShapeEditingState(getToggleValue(name)); 177 | 178 | } 179 | // else if (name == kSettingMappingShowShapesId) { 180 | // _showShapesId = getToggleValue(name); 181 | // } 182 | 183 | // ---- Creating a new shape 184 | else if (name == kSettingMappingCreateNewQuad) { 185 | // will happen only if ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled is true 186 | if(getToggleValue(name)) { 187 | _createNewQuad = true; 188 | } 189 | } 190 | else if (name == kSettingMappingCreateNewGrid) { 191 | // will happen only if ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled is true 192 | if(getToggleValue(name)) { 193 | _createNewGrid = true; 194 | } 195 | } 196 | else if (name == kSettingMappingCreateNewTriangle) { 197 | // will happen only if ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled is true 198 | if(getToggleValue(name)) { 199 | _createNewTriangle = true; 200 | } 201 | } 202 | else if (name == kSettingMappingCreateNewMask) { 203 | // will happen only if ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled is true 204 | if(getToggleValue(name)) { 205 | _createNewMask = true; 206 | } 207 | } 208 | 209 | // ---- 210 | if (getToggleValue(name)) { 211 | unselectShapesToggles(); 212 | ofxMtlMapping2DShape::resetActiveShapeVars(); 213 | ofxMtlMapping2DPolygon::resetActivePolygonVars(); 214 | 215 | _mappingModeChanged = true; 216 | 217 | if (name == kSettingMappingModeOutput) { 218 | _mappingMode = MAPPING_MODE_OUTPUT; 219 | 220 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingModeInput))->setValue(false); 221 | 222 | // --- 223 | if (ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled) { 224 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewQuad))->setVisible(true); 225 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewGrid))->setVisible(true); 226 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewTriangle))->setVisible(true); 227 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewMask))->setVisible(true); 228 | } 229 | 230 | // --- 231 | showGridSettingsCanvas(); 232 | } 233 | else if (name == kSettingMappingModeInput) { 234 | _mappingMode = MAPPING_MODE_INPUT; 235 | 236 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingModeOutput))->setValue(false); 237 | 238 | // --- 239 | if (ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled) { 240 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewQuad))->setVisible(false); 241 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewGrid))->setVisible(false); 242 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewTriangle))->setVisible(false); 243 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewMask))->setVisible(false); 244 | } 245 | 246 | // --- 247 | hideGridSettingsCanvas(); 248 | } 249 | 250 | refreshShapesListForMappingMode(_mappingMode); 251 | 252 | } 253 | } 254 | 255 | //-------------------------------------------------------------- 256 | void ofxMtlMapping2DControls::setUIShapeEditingState(bool isOn) 257 | { 258 | _editShapes = isOn; 259 | 260 | if (!_editShapes) { 261 | // Set all Shapes and their InteractiveObj 262 | list::iterator it; 263 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 264 | ofxMtlMapping2DShape* shape = *it; 265 | shape->setAsIdle(); 266 | } 267 | 268 | // --- 269 | ofxMtlMapping2DShape::resetActiveShapeVars(); 270 | ofxMtlMapping2DShape::resetActivePolygonVars(); 271 | 272 | // --- 273 | _shapesListCanvas->disable(); 274 | hideGridSettingsCanvas(); 275 | 276 | } else { 277 | 278 | // --- 279 | _shapesListCanvas->enable(); 280 | showGridSettingsCanvas(); 281 | } 282 | 283 | // ---- 284 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingSave))->setVisible(_editShapes); 285 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingLoad))->setVisible(_editShapes); 286 | 287 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingModeInput))->setVisible(_editShapes); 288 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingModeOutput))->setVisible(_editShapes); 289 | 290 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewQuad))->setVisible(_editShapes); 291 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewGrid))->setVisible(_editShapes); 292 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewTriangle))->setVisible(_editShapes); 293 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewMask))->setVisible(_editShapes); 294 | } 295 | 296 | 297 | #pragma mark - 298 | #pragma mark Shapes List Related 299 | 300 | //-------------------------------------------------------------- 301 | void ofxMtlMapping2DControls::shapesListUiEvent(ofxUIEventArgs &event) 302 | { 303 | string name = event.widget->getName(); 304 | 305 | vector result = ofSplitString(name, " "); 306 | int shapeId = ofToInt(result[1]); 307 | string shapeTypeAsString = result[2]; 308 | int shapeType = -1; 309 | 310 | map::iterator it; 311 | for ( it = shapeTypesAsString.begin() ; it != shapeTypesAsString.end(); it++ ) { 312 | if (it->second == shapeTypeAsString) 313 | { 314 | shapeType = it->first; 315 | break; 316 | } 317 | } 318 | 319 | setAsActiveShapeWithId(shapeId, shapeType); 320 | 321 | _selectedShapeId = shapeId; 322 | _selectedShapeChanged = true; 323 | } 324 | 325 | 326 | //-------------------------------------------------------------- 327 | void ofxMtlMapping2DControls::addShapeToList(int shapeID, int shapeType) 328 | { 329 | shapeCounter++; 330 | _shapesListCanvas->addWidgetDown(new ofxUIToggle(("Shape " + ofToString(shapeID) + " " + shapeTypesAsString.find((ofxMtlMapping2DShapeType)shapeType)->second), false, kToggleSize, kToggleSize)); 331 | 332 | resizeShapeList(); 333 | } 334 | 335 | //-------------------------------------------------------------- 336 | void ofxMtlMapping2DControls::clearShapesList() 337 | { 338 | _shapesListCanvas->removeWidgets(); 339 | _shapesListCanvas->resetPlacer(); 340 | resizeShapeList(); 341 | } 342 | 343 | //-------------------------------------------------------------- 344 | void ofxMtlMapping2DControls::refreshShapesListForMappingMode(ofxMtlMapping2DMode mappingMode) 345 | { 346 | clearShapesList(); 347 | 348 | // Re populate the UI List 349 | ofxMtlMapping2DShapes::pmShapes.sort(Comparator()); 350 | 351 | list::reverse_iterator it; 352 | for (it=ofxMtlMapping2DShapes::pmShapes.rbegin(); it!=ofxMtlMapping2DShapes::pmShapes.rend(); it++) { 353 | ofxMtlMapping2DShape* shape = *it; 354 | 355 | if (mappingMode == MAPPING_MODE_OUTPUT || (mappingMode == MAPPING_MODE_INPUT && shape->shapeType != MAPPING_2D_SHAPE_MASK)) { 356 | ofxMtlMapping2DControls::mapping2DControls()->addShapeToList(shape->shapeId, shape->shapeType); 357 | } 358 | } 359 | } 360 | 361 | //-------------------------------------------------------------- 362 | void ofxMtlMapping2DControls::resizeShapeList() 363 | { 364 | _shapesListCanvas->autoSizeToFitWidgets(); 365 | _shapesListCanvas->getRect()->setY(.0f); 366 | _shapesListCanvas->getRect()->setWidth(kControlsMappingShapesListPanelWidth); 367 | 368 | float listHeight = _shapesListCanvas->getRect()->height; 369 | if(listHeight < ofGetHeight()) { 370 | _shapesListCanvas->getRect()->setHeight(ofGetHeight()); 371 | } else { 372 | _shapesListCanvas->getRect()->setHeight(listHeight + kBottomSpacerHeight); 373 | } 374 | } 375 | 376 | //-------------------------------------------------------------- 377 | void ofxMtlMapping2DControls::setAsActiveShapeWithId(int shapeID, int shapeType) 378 | { 379 | // ---- 380 | for (int i=0; i < _shapesListCanvas->getWidgetsOfType(OFX_UI_WIDGET_TOGGLE).size(); i++) { 381 | ofxUIToggle * shapeToggle = (ofxUIToggle *)_shapesListCanvas->getWidgetsOfType(OFX_UI_WIDGET_TOGGLE)[i]; 382 | if ( shapeToggle->getName() == ("Shape " + ofToString(shapeID) + " " + shapeTypesAsString.find((ofxMtlMapping2DShapeType)shapeType)->second) ) { 383 | shapeToggle->setValue(true); 384 | } else { 385 | shapeToggle->setValue(false); 386 | } 387 | } 388 | } 389 | 390 | //-------------------------------------------------------------- 391 | void ofxMtlMapping2DControls::unselectShapesToggles() 392 | { 393 | for (int i=0; i < _shapesListCanvas->getWidgetsOfType(OFX_UI_WIDGET_TOGGLE).size(); i++) { 394 | ofxUIToggle * shapeToggle = (ofxUIToggle *)_shapesListCanvas->getWidgetsOfType(OFX_UI_WIDGET_TOGGLE)[i]; 395 | shapeToggle->setValue(false); 396 | } 397 | } 398 | 399 | //-------------------------------------------------------------- 400 | void ofxMtlMapping2DControls::windowResized() 401 | { 402 | if (ofGetWindowMode() == OF_FULLSCREEN) { 403 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingFullscreen))->setImage(&_fullscreenContractIcon); 404 | } else { 405 | ((ofxUIImageToggle *)_toolsCanvas->getWidget(kSettingMappingFullscreen))->setImage(&_fullscreenExpandIcon); 406 | } 407 | 408 | _toolsCanvas->setHeight(ofGetHeight()); 409 | _gridSettingsCanvas->setPosition(_toolsCanvas->getRect()->width, ofGetHeight() - 90); 410 | } 411 | 412 | 413 | #pragma mark - 414 | #pragma mark Grid settings 415 | 416 | //-------------------------------------------------------------- 417 | void ofxMtlMapping2DControls::gridSettingsListUiEvent(ofxUIEventArgs &event) 418 | { 419 | if(ofxMtlMapping2DShape::activeShape) { 420 | if (ofxMtlMapping2DShape::activeShape->shapeType == MAPPING_2D_SHAPE_GRID) { 421 | ((ofxMtlMapping2DGrid*)ofxMtlMapping2DShape::activeShape)->updateGrid(); 422 | } 423 | } 424 | } 425 | 426 | //-------------------------------------------------------------- 427 | void ofxMtlMapping2DControls::showGridSettingsCanvas() 428 | { 429 | if(isEnabled() && ofxMtlMapping2DShape::activeShape) { 430 | if (ofxMtlMapping2DShape::activeShape->shapeType == MAPPING_2D_SHAPE_GRID) { 431 | _gridSettingsCanvas->removeWidgets(); 432 | _gridSettingsCanvas->resetPlacer(); 433 | 434 | ofxUISlider *nSlider; 435 | _gridSettingsCanvas->addLabel("GRID SETTINGS"); 436 | nSlider = _gridSettingsCanvas->addSlider("NB COLS", 1.0, 20.0, &(((ofxMtlMapping2DGrid*)ofxMtlMapping2DShape::activeShape)->gridNbCols)); 437 | nSlider->setIncrement(1.0f); 438 | nSlider = _gridSettingsCanvas->addSlider("NB ROWS", 1.0, 20.0, &(((ofxMtlMapping2DGrid*)ofxMtlMapping2DShape::activeShape)->gridNbRows)); 439 | nSlider->setIncrement(1.0f); 440 | 441 | _shapesListCanvas->autoSizeToFitWidgets(); 442 | 443 | _gridSettingsCanvas->enable(); 444 | } 445 | } 446 | } 447 | 448 | //-------------------------------------------------------------- 449 | void ofxMtlMapping2DControls::hideGridSettingsCanvas() 450 | { 451 | _gridSettingsCanvas->disable(); 452 | } 453 | 454 | 455 | #pragma mark - 456 | #pragma mark Reset widgets 457 | //-------------------------------------------------------------- 458 | void ofxMtlMapping2DControls::resetSaveMapping() 459 | { 460 | _saveMapping = false; 461 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingSave))->setValue(false); 462 | } 463 | 464 | //-------------------------------------------------------------- 465 | void ofxMtlMapping2DControls::resetLoadMapping() 466 | { 467 | _loadMapping = false; 468 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingLoad))->setValue(false); 469 | } 470 | 471 | //-------------------------------------------------------------- 472 | void ofxMtlMapping2DControls::resetCreateNewShape() 473 | { 474 | _createNewQuad = false; 475 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewQuad))->setValue(false); 476 | 477 | _createNewGrid = false; 478 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewGrid))->setValue(false); 479 | 480 | _createNewTriangle = false; 481 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewTriangle))->setValue(false); 482 | 483 | _createNewMask = false; 484 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingCreateNewMask))->setValue(false); 485 | } 486 | 487 | //-------------------------------------------------------------- 488 | void ofxMtlMapping2DControls::resetMappingChangedFlag() 489 | { 490 | _mappingModeChanged = false; 491 | } 492 | 493 | //-------------------------------------------------------------- 494 | void ofxMtlMapping2DControls::resetSelectedShapeChangedFlag() 495 | { 496 | _selectedShapeChanged = false; 497 | } 498 | 499 | #pragma mark - 500 | #pragma mark Set avalaible options 501 | //-------------------------------------------------------------- 502 | void ofxMtlMapping2DControls::showInputModeToggle() 503 | { 504 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingModeInput))->setVisible(true); 505 | } 506 | 507 | //-------------------------------------------------------------- 508 | void ofxMtlMapping2DControls::hideInputModeToggle() 509 | { 510 | ((ofxUIToggle *)_toolsCanvas->getWidget(kSettingMappingModeInput))->setVisible(false); 511 | } 512 | 513 | #pragma mark - 514 | #pragma mark Interface Methods 515 | //-------------------------------------------------------------- 516 | bool ofxMtlMapping2DControls::getToggleValue(const string& name) 517 | { 518 | return ((ofxUIToggle *)_toolsCanvas->getWidget(name))->getValue(); 519 | } 520 | 521 | //-------------------------------------------------------------- 522 | float ofxMtlMapping2DControls::getSliderValue(const string& name) 523 | { 524 | return ((ofxUISlider *)_toolsCanvas->getWidget(name))->getScaledValue(); 525 | } 526 | 527 | //-------------------------------------------------------------- 528 | ofPoint ofxMtlMapping2DControls::get2DPadValue(const string& name) 529 | { 530 | return ((ofxUI2DPad *)_toolsCanvas->getWidget(name))->getScaledValue(); 531 | } 532 | 533 | //-------------------------------------------------------------- 534 | void ofxMtlMapping2DControls::save() 535 | { 536 | _toolsCanvas->saveSettings(_file); 537 | } 538 | 539 | //-------------------------------------------------------------- 540 | void ofxMtlMapping2DControls::load() 541 | { 542 | _toolsCanvas->loadSettings(_file); 543 | } 544 | 545 | //-------------------------------------------------------------- 546 | void ofxMtlMapping2DControls::enable() 547 | { 548 | _toolsCanvas->enable(); 549 | _shapesListCanvas->enable(); 550 | } 551 | 552 | //-------------------------------------------------------------- 553 | void ofxMtlMapping2DControls::disable() 554 | { 555 | _toolsCanvas->disable(); 556 | _shapesListCanvas->disable(); 557 | _gridSettingsCanvas->disable(); 558 | } 559 | 560 | //-------------------------------------------------------------- 561 | void ofxMtlMapping2DControls::toggle() 562 | { 563 | _toolsCanvas->toggleVisible(); 564 | 565 | if (_toolsCanvas->isVisible() && _editShapes) { 566 | _shapesListCanvas->enable(); 567 | showGridSettingsCanvas(); 568 | } else { 569 | _shapesListCanvas->disable(); 570 | hideGridSettingsCanvas(); 571 | } 572 | } 573 | 574 | //-------------------------------------------------------------- 575 | bool ofxMtlMapping2DControls::isEnabled() 576 | { 577 | return _toolsCanvas->isEnabled(); 578 | } 579 | 580 | //-------------------------------------------------------------- 581 | bool ofxMtlMapping2DControls::isHit(int x, int y) { 582 | if (_toolsCanvas->isHit(x, y) || _shapesListCanvas->isHit(x, y) || _gridSettingsCanvas->isHit(x, y)) { 583 | return true; 584 | } else { 585 | return false; 586 | } 587 | } 588 | 589 | 590 | -------------------------------------------------------------------------------- /src/controls/ofxMtlMapping2DControls.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofEvents.h" 4 | 5 | #include "ofxMtlMapping2DMode.h" 6 | #include "ofxUI.h" 7 | #include "ofxMtlMapping2DShapeType.h" 8 | 9 | #define kControlsMappingToolsPanelWidth 39 10 | #define kControlsMappingShapesListPanelWidth 150 11 | 12 | #define kSettingMappingSave "MAPPING:SAVE" 13 | #define kSettingMappingLoad "MAPPING:LOAD" 14 | 15 | #define kSettingMappingFullscreen "MAPPING:FULLSCREEN" 16 | #define kSettingMappingEditShapes "MAPPING:EDIT_SHAPES" 17 | #define kSettingMappingCreateNewQuad "MAPPING:CREATE_NEW_QUAD" 18 | #define kSettingMappingCreateNewGrid "MAPPING:CREATE_NEW_GRID" 19 | #define kSettingMappingCreateNewTriangle "MAPPING:CREATE_NEW_TRIANGLE" 20 | #define kSettingMappingCreateNewMask "MAPPING:CREATE_NEW_MASK" 21 | 22 | #define kSettingMappingShowShapesId "MAPPING:SHOW_SHAPES_ID" 23 | 24 | #define kSettingMappingModeOutput "MAPPING_MODE:OUTPUT" 25 | #define kSettingMappingModeInput "MAPPING_MODE:INPUT" 26 | 27 | 28 | //-------------------------------------------------------------- 29 | //-------------------------------------------------------------- 30 | class ofxMtlMapping2DControls 31 | { 32 | 33 | public: 34 | static ofxMtlMapping2DControls * mapping2DControls(string xmlFilePath); 35 | static ofxMtlMapping2DControls * mapping2DControls(); 36 | 37 | 38 | void toolsUiEvent(ofxUIEventArgs &event); 39 | void shapesListUiEvent(ofxUIEventArgs &event); 40 | void gridSettingsListUiEvent(ofxUIEventArgs &event); 41 | 42 | 43 | const bool& saveMapping() { return _saveMapping; } 44 | void resetSaveMapping(); 45 | const bool& loadMapping() { return _loadMapping; } 46 | void resetLoadMapping(); 47 | 48 | const bool& editShapes() { return _editShapes; } 49 | const bool& createNewQuad() { return _createNewQuad; } 50 | const bool& createNewGrid() { return _createNewGrid; } 51 | const bool& createNewTriangle() { return _createNewTriangle; } 52 | const bool& createNewMask() { return _createNewMask; } 53 | void resetCreateNewShape(); 54 | const bool& showShapesId() { return _showShapesId; } 55 | 56 | const bool& mappingModeChanged() { return _mappingModeChanged; } 57 | ofxMtlMapping2DMode mappingMode() { return _mappingMode; } 58 | void resetMappingChangedFlag(); 59 | 60 | void showGridSettingsCanvas(); 61 | void hideGridSettingsCanvas(); 62 | 63 | int shapeCounter; 64 | 65 | void save(); 66 | void load(); 67 | 68 | void showInputModeToggle(); 69 | void hideInputModeToggle(); 70 | 71 | void enable(); 72 | void disable(); 73 | void toggle(); 74 | bool isEnabled(); 75 | bool isHit(int x, int y); 76 | 77 | void addShapeToList(int shapeID, int shapeType); 78 | void clearShapesList(); 79 | const bool& selectedShapeChanged() { return _selectedShapeChanged; } 80 | void resetSelectedShapeChangedFlag(); 81 | const int& selectedShapeId() { return _selectedShapeId; } 82 | void setAsActiveShapeWithId(int shapeID, int shapeType); 83 | 84 | void unselectShapesToggles(); 85 | void windowResized(); 86 | 87 | protected: 88 | ofxUIScrollableCanvas *_toolsCanvas; 89 | string _file; 90 | 91 | static const int kSliderHeight = 16; 92 | static const int kSpacerHeight = 20; 93 | static const int kToggleSize = 24; 94 | static const int kBottomSpacerHeight = 100; // padding to be able to scroll until the end/bottom of the UI canvas 95 | 96 | bool getToggleValue(const string& name); 97 | float getSliderValue(const string& name); 98 | ofPoint get2DPadValue(const string& name); 99 | 100 | private: 101 | ofxMtlMapping2DControls(int width, const string& file); 102 | 103 | static ofxMtlMapping2DControls *_mapping2DControls; 104 | map shapeTypesAsString; 105 | 106 | void setUIShapeEditingState(bool isOn); 107 | bool _saveMapping; 108 | bool _loadMapping; 109 | 110 | bool _editShapes; 111 | bool _createNewQuad; 112 | bool _createNewGrid; 113 | bool _createNewTriangle; 114 | bool _createNewMask; 115 | bool _showShapesId; 116 | bool _selectedShapeChanged; 117 | int _selectedShapeId; 118 | 119 | bool _mappingModeChanged; 120 | ofxMtlMapping2DMode _mappingMode; 121 | 122 | ofxUIScrollableCanvas *_shapesListCanvas; 123 | void resizeShapeList(); 124 | void refreshShapesListForMappingMode(ofxMtlMapping2DMode mappingMode); 125 | 126 | ofxUICanvas *_gridSettingsCanvas; 127 | 128 | ofImage _fullscreenExpandIcon; 129 | ofImage _fullscreenContractIcon; 130 | 131 | }; 132 | -------------------------------------------------------------------------------- /src/ofxMtlMapping2D.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2D.h" 2 | #include "ofxMtlMapping2DSettings.h" 3 | #include "ofxMtlMapping2DControls.h" 4 | #include "ofxMtlMapping2DInput.h" 5 | #include "ofxMtlMapping2DShapeType.h" 6 | #include "ofxMtlMapping2DShapes.h" 7 | 8 | //-------------------------------------------------------------- 9 | //-------------------------------------------------------------- 10 | list::iterator ofxMtlMapping2D::iteratorForShapeWithId(int shapeId) 11 | { 12 | list::iterator it; 13 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 14 | ofxMtlMapping2DShape* shape = *it; 15 | if(shape->shapeId == shapeId) { 16 | return it; 17 | } 18 | } 19 | 20 | return ofxMtlMapping2DShapes::pmShapes.end(); 21 | } 22 | 23 | //-------------------------------------------------------------- 24 | //-------------------------------------------------------------- 25 | ofxMtlMapping2D::ofxMtlMapping2D() 26 | { 27 | } 28 | 29 | //-------------------------------------------------------------- 30 | ofxMtlMapping2D::~ofxMtlMapping2D() 31 | { 32 | // ---- 33 | while(!ofxMtlMapping2DShapes::pmShapes.empty()) delete ofxMtlMapping2DShapes::pmShapes.back(), ofxMtlMapping2DShapes::pmShapes.pop_back(); 34 | ofxMtlMapping2DShapes::pmShapes.clear(); 35 | } 36 | 37 | //-------------------------------------------------------------- 38 | void ofxMtlMapping2D::init(int width, int height, string mappingXmlFilePath, string uiXmlFilePath, int numSample) 39 | { 40 | // The first we call ofxMtlMapping2DControls::mapping2DControls() we pass the xml file to use as param. 41 | ofxMtlMapping2DControls::mapping2DControls(uiXmlFilePath)->disable(); 42 | 43 | // ---- 44 | _fbo.allocate(width, height, GL_RGBA, numSample); 45 | 46 | // ---- 47 | ofxMtlMapping2DSettings::infoFont.loadFont("mapping/controls/ReplicaBold.ttf", 10); 48 | 49 | // ---- 50 | _mappingXmlFilePath = mappingXmlFilePath; 51 | loadShapesList(); 52 | 53 | // --- 54 | addListeners(); 55 | 56 | } 57 | 58 | //-------------------------------------------------------------- 59 | void ofxMtlMapping2D::update() 60 | { 61 | // ---- save mapping to xml 62 | if(ofxMtlMapping2DControls::mapping2DControls()->saveMapping()) { 63 | ofxMtlMapping2DControls::mapping2DControls()->resetSaveMapping(); 64 | saveShapesList(); 65 | } 66 | 67 | 68 | // ---- load mapping from xml 69 | if(ofxMtlMapping2DControls::mapping2DControls()->loadMapping()) { 70 | ofxMtlMapping2DControls::mapping2DControls()->resetLoadMapping(); 71 | loadShapesList(); 72 | } 73 | 74 | 75 | 76 | // ---- 77 | // Editing or not !? 78 | if(!ofxMtlMapping2DControls::mapping2DControls()->editShapes()) 79 | return; 80 | 81 | 82 | // ---- 83 | // Create a new shape 84 | if(ofxMtlMapping2DControls::mapping2DControls()->createNewQuad()) { 85 | ofxMtlMapping2DControls::mapping2DControls()->resetCreateNewShape(); 86 | createQuad(ofGetWidth()/2, ofGetHeight()/2); 87 | return; 88 | } 89 | 90 | if(ofxMtlMapping2DControls::mapping2DControls()->createNewGrid()) { 91 | ofxMtlMapping2DControls::mapping2DControls()->resetCreateNewShape(); 92 | createGrid(ofGetWidth()/2, ofGetHeight()/2); 93 | return; 94 | } 95 | 96 | if(ofxMtlMapping2DControls::mapping2DControls()->createNewTriangle()) { 97 | ofxMtlMapping2DControls::mapping2DControls()->resetCreateNewShape(); 98 | createTriangle(ofGetWidth()/2, ofGetHeight()/2); 99 | return; 100 | } 101 | 102 | if(ofxMtlMapping2DControls::mapping2DControls()->createNewMask()) { 103 | ofxMtlMapping2DControls::mapping2DControls()->resetCreateNewShape(); 104 | createMask(ofGetWidth()/2, ofGetHeight()/2); 105 | return; 106 | } 107 | 108 | // ---- 109 | // Selected shape with UI 110 | if(ofxMtlMapping2DControls::mapping2DControls()->selectedShapeChanged()) { 111 | ofxMtlMapping2DControls::mapping2DControls()->resetSelectedShapeChangedFlag(); 112 | 113 | list::iterator it = iteratorForShapeWithId(ofxMtlMapping2DControls::mapping2DControls()->selectedShapeId()); 114 | if(it != ofxMtlMapping2DShapes::pmShapes.end()) { 115 | ofxMtlMapping2DShape* shape = *it; 116 | shape->setAsActiveShape(true); 117 | 118 | // Put active shape at the top of the list 119 | ofxMtlMapping2DShapes::pmShapes.push_front(shape); 120 | ofxMtlMapping2DShapes::pmShapes.erase(it); 121 | } 122 | } 123 | 124 | 125 | // ---- 126 | // We changed of mode - Output / Input 127 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingModeChanged()) { 128 | ofxMtlMapping2DControls::mapping2DControls()->resetMappingChangedFlag(); 129 | 130 | // ---- OUTPUT MODE 131 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 132 | list::iterator it; 133 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 134 | ofxMtlMapping2DShape* shape = *it; 135 | shape->enable(); 136 | 137 | if(shape->inputPolygon) { 138 | // If this Shape is textured and has an 'inputPolygon' 139 | shape->inputPolygon->setAsIdle(); 140 | } 141 | } 142 | // ---- INPUT MODE 143 | } else if (ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_INPUT) { 144 | list::iterator it; 145 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 146 | ofxMtlMapping2DShape* shape = *it; 147 | shape->setAsIdle(); 148 | shape->inputPolygon->enable(); 149 | } 150 | } 151 | 152 | } 153 | 154 | // ---- 155 | // Update the Shapes 156 | list::iterator it; 157 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 158 | ofxMtlMapping2DShape* shape = *it; 159 | shape->update(); 160 | } 161 | } 162 | 163 | #pragma mark - 164 | #pragma mark Draw / Edit Mode 165 | //-------------------------------------------------------------- 166 | void ofxMtlMapping2D::draw() 167 | { 168 | 169 | if(ofxMtlMapping2DControls::mapping2DControls()->editShapes()) { 170 | // ---- OUTPUT MODE 171 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 172 | render(); 173 | 174 | 175 | // ---- INPUT MODE 176 | } else if (ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_INPUT) { 177 | // ---- 178 | drawFbo(); 179 | } 180 | 181 | 182 | // ---- 183 | list::iterator it; 184 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 185 | ofxMtlMapping2DShape* shape = *it; 186 | 187 | if(shape != ofxMtlMapping2DShape::activeShape) { 188 | shape->draw(); 189 | } 190 | } 191 | 192 | if(ofxMtlMapping2DShape::activeShape) { 193 | //Draw active shape on top 194 | ofxMtlMapping2DShape::activeShape->draw(); 195 | } 196 | } 197 | else { 198 | render(); 199 | } 200 | } 201 | 202 | #pragma mark - 203 | #pragma mark FBO 204 | //-------------------------------------------------------------- 205 | void ofxMtlMapping2D::bind() 206 | { 207 | _fbo.begin(); 208 | ofClear(.0f, .0f, .0f, .0f); 209 | ofClearAlpha(); 210 | } 211 | 212 | //-------------------------------------------------------------- 213 | void ofxMtlMapping2D::unbind() 214 | { 215 | _fbo.end(); 216 | } 217 | 218 | //-------------------------------------------------------------- 219 | void ofxMtlMapping2D::drawFbo() 220 | { 221 | glColor3f(1.0f, 1.0f, 1.0f); 222 | _fbo.draw(0, 0); 223 | } 224 | 225 | #pragma mark - 226 | #pragma mark Render - Mapping Mode 227 | //-------------------------------------------------------------- 228 | void ofxMtlMapping2D::render() 229 | { 230 | list::iterator it; 231 | 232 | // Textured shapes 233 | _fbo.getTextureReference().bind(); 234 | ofSetColor(255, 255, 255, 255); 235 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 236 | ofxMtlMapping2DShape* shape = *it; 237 | 238 | if (shape->shapeType != MAPPING_2D_SHAPE_MASK) { 239 | shape->render(); 240 | } 241 | } 242 | _fbo.getTextureReference().unbind(); 243 | 244 | // Masks - non textured shapes 245 | ofSetColor(0, 0, 0, 255); 246 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 247 | ofxMtlMapping2DShape* shape = *it; 248 | 249 | if (shape->shapeType == MAPPING_2D_SHAPE_MASK) { 250 | shape->render(); 251 | } 252 | } 253 | } 254 | 255 | 256 | #pragma mark - 257 | #pragma mark Shapes Related 258 | //-------------------------------------------------------------- 259 | void ofxMtlMapping2D::createQuad(float _x, float _y) 260 | { 261 | ofxMtlMapping2DShape::nextShapeId++; 262 | 263 | ofxMtlMapping2DShape* newShape = new ofxMtlMapping2DQuad(); 264 | newShape->shapeType = MAPPING_2D_SHAPE_QUAD; 265 | newShape->init(ofxMtlMapping2DShape::nextShapeId, true); 266 | ofxMtlMapping2DShapes::pmShapes.push_front(newShape); 267 | 268 | ofxMtlMapping2DControls::mapping2DControls()->addShapeToList(ofxMtlMapping2DShape::nextShapeId, MAPPING_2D_SHAPE_QUAD); 269 | } 270 | 271 | //-------------------------------------------------------------- 272 | void ofxMtlMapping2D::createGrid(float _x, float _y) 273 | { 274 | ofxMtlMapping2DShape::nextShapeId++; 275 | 276 | ofxMtlMapping2DShape* newShape = new ofxMtlMapping2DGrid(); 277 | newShape->shapeType = MAPPING_2D_SHAPE_GRID; 278 | newShape->init(ofxMtlMapping2DShape::nextShapeId, true); 279 | ofxMtlMapping2DShapes::pmShapes.push_front(newShape); 280 | 281 | ofxMtlMapping2DControls::mapping2DControls()->addShapeToList(ofxMtlMapping2DShape::nextShapeId, MAPPING_2D_SHAPE_GRID); 282 | } 283 | 284 | //-------------------------------------------------------------- 285 | void ofxMtlMapping2D::createTriangle(float _x, float _y) 286 | { 287 | ofxMtlMapping2DShape::nextShapeId++; 288 | 289 | ofxMtlMapping2DShape* newShape = new ofxMtlMapping2DTriangle(); 290 | newShape->shapeType = MAPPING_2D_SHAPE_TRIANGLE; 291 | newShape->init(ofxMtlMapping2DShape::nextShapeId, true); 292 | ofxMtlMapping2DShapes::pmShapes.push_front(newShape); 293 | 294 | ofxMtlMapping2DControls::mapping2DControls()->addShapeToList(ofxMtlMapping2DShape::nextShapeId, MAPPING_2D_SHAPE_TRIANGLE); 295 | } 296 | 297 | //-------------------------------------------------------------- 298 | void ofxMtlMapping2D::createMask(float _x, float _y) 299 | { 300 | ofxMtlMapping2DShape::nextShapeId++; 301 | 302 | ofxMtlMapping2DShape* newShape = new ofxMtlMapping2DMask(); 303 | newShape->shapeType = MAPPING_2D_SHAPE_MASK; 304 | newShape->init(ofxMtlMapping2DShape::nextShapeId, true); 305 | ofxMtlMapping2DShapes::pmShapes.push_front(newShape); 306 | 307 | ofxMtlMapping2DControls::mapping2DControls()->addShapeToList(ofxMtlMapping2DShape::nextShapeId, MAPPING_2D_SHAPE_MASK); 308 | } 309 | 310 | //-------------------------------------------------------------- 311 | void ofxMtlMapping2D::deleteShape() 312 | { 313 | if (ofxMtlMapping2DShape::activeShape) { 314 | ofxMtlMapping2DControls::mapping2DControls()->clearShapesList(); 315 | ofxMtlMapping2DShapes::pmShapes.remove(ofxMtlMapping2DShape::activeShape); 316 | delete ofxMtlMapping2DShape::activeShape; 317 | ofxMtlMapping2DShape::resetActiveShapeVars(); 318 | 319 | // Re populate the UI List 320 | list::reverse_iterator it; 321 | for (it=ofxMtlMapping2DShapes::pmShapes.rbegin(); it!=ofxMtlMapping2DShapes::pmShapes.rend(); it++) { 322 | ofxMtlMapping2DShape* shape = *it; 323 | ofxMtlMapping2DControls::mapping2DControls()->addShapeToList(shape->shapeId, shape->shapeType); 324 | 325 | } 326 | } 327 | } 328 | 329 | //-------------------------------------------------------------- 330 | //void ofxMtlMapping2D::disableAllShapes() 331 | //{ 332 | // // Disable all the shapes. 333 | // list::iterator it; 334 | // for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 335 | // ofxMtlMapping2DShape* shape = *it; 336 | // shape->disable(); 337 | // } 338 | //} 339 | 340 | #pragma mark - 341 | 342 | //-------------------------------------------------------------- 343 | void ofxMtlMapping2D::addListeners() { 344 | ofAddListener(ofEvents().mousePressed, this, &ofxMtlMapping2D::mousePressed); 345 | ofAddListener(ofEvents().keyPressed, this, &ofxMtlMapping2D::keyPressed); 346 | ofAddListener(ofEvents().windowResized, this, &ofxMtlMapping2D::windowResized); 347 | } 348 | 349 | //-------------------------------------------------------------- 350 | void ofxMtlMapping2D::removeListeners() { 351 | ofRemoveListener(ofEvents().mousePressed, this, &ofxMtlMapping2D::mousePressed); 352 | ofRemoveListener(ofEvents().keyPressed, this, &ofxMtlMapping2D::keyPressed); 353 | ofRemoveListener(ofEvents().windowResized, this, &ofxMtlMapping2D::windowResized); 354 | 355 | } 356 | 357 | #pragma mark - 358 | #pragma mark Events 359 | 360 | void mousePressed(ofMouseEventArgs &e); 361 | void keyPressed(ofKeyEventArgs &e); 362 | //-------------------------------------------------------------- 363 | void ofxMtlMapping2D::windowResized(ofResizeEventArgs &e) 364 | { 365 | ofxMtlMapping2DControls::mapping2DControls()->windowResized(); 366 | } 367 | 368 | 369 | //-------------------------------------------------------------- 370 | void ofxMtlMapping2D::mousePressed(ofMouseEventArgs &e) 371 | { 372 | int eX = e.x; 373 | int eY = e.y; 374 | int eButton = e.button; 375 | 376 | if (ofxMtlMapping2DControls::mapping2DControls()->isHit(eX, eY)) 377 | return; 378 | 379 | if(!ofxMtlMapping2DControls::mapping2DControls()->editShapes()) 380 | return; 381 | 382 | 383 | // ---- 384 | // A vertex has been selected 385 | if (ofxMtlMapping2DVertex::activeVertex || eButton == 2) { 386 | return; 387 | } 388 | 389 | // ---- 390 | // Select an existing shape 391 | list::iterator it; 392 | for (it=ofxMtlMapping2DShapes::pmShapes.begin(); it!=ofxMtlMapping2DShapes::pmShapes.end(); it++) { 393 | ofxMtlMapping2DShape* shape = *it; 394 | bool grabbedOne = false; 395 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 396 | if(shape->hitTest(eX, eY)) { 397 | grabbedOne = true; 398 | shape->select(eX, eY); 399 | shape->enable(); 400 | } 401 | } else if (ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_INPUT) { 402 | if (shape->inputPolygon || shape->shapeType != MAPPING_2D_SHAPE_MASK) { 403 | if(shape->inputPolygon->hitTest(eX, eY)) { 404 | grabbedOne = true; 405 | shape->inputPolygon->select(eX, eY); 406 | shape->inputPolygon->enable(); 407 | } 408 | } 409 | } 410 | 411 | if(grabbedOne) { 412 | // Put active shape at the top of the list 413 | ofxMtlMapping2DShapes::pmShapes.push_front(shape); 414 | ofxMtlMapping2DShapes::pmShapes.erase(it); 415 | 416 | return; 417 | } 418 | } 419 | 420 | // ---- 421 | if(ofxMtlMapping2DSettings::kIsManuallyAddingDeletingVertexEnabled && ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 422 | // Add vertex to the selected shape 423 | if(ofxMtlMapping2DShape::activeShape) { 424 | // Only if the shape is a Mask 425 | if (ofxMtlMapping2DShape::activeShape->shapeType == MAPPING_2D_SHAPE_MASK) { 426 | ofxMtlMapping2DShape* shape = ofxMtlMapping2DShape::activeShape; 427 | if (shape) { 428 | ofLog(OF_LOG_NOTICE, "Add vertex to shape %i", shape->shapeId); 429 | shape->addPoint(eX, eY); 430 | } else { 431 | ofLog(OF_LOG_NOTICE, "No shape has been selected, can not add a vertex"); 432 | } 433 | } 434 | } 435 | } 436 | 437 | } 438 | 439 | #pragma mark - 440 | #pragma mark Keyboard event 441 | //-------------------------------------------------------------- 442 | void ofxMtlMapping2D::keyPressed(ofKeyEventArgs &e) 443 | { 444 | // ---- 445 | switch (e.key) { 446 | case 9: // TAB 447 | ofToggleFullscreen(); 448 | break; 449 | 450 | case 'l': 451 | loadShapesList(); 452 | break; 453 | 454 | case 'm': 455 | ofxMtlMapping2DControls::mapping2DControls()->toggle(); 456 | break; 457 | 458 | case 's': 459 | ofxMtlMapping2DControls::mapping2DControls()->save(); 460 | saveShapesList(); 461 | break; 462 | 463 | case 356: 464 | //left 465 | if (ofxMtlMapping2DControls::mapping2DControls()->editShapes()) { 466 | if(ofxMtlMapping2DShape::activeShape && ofxMtlMapping2DShape::activeVertexId >=0) { 467 | ofxMtlMapping2DVertex::activeVertex->left(); 468 | } 469 | } 470 | break; 471 | 472 | case 357: //up 473 | if (ofxMtlMapping2DControls::mapping2DControls()->editShapes()) { 474 | if(ofxMtlMapping2DShape::activeShape && ofxMtlMapping2DShape::activeVertexId >=0) { 475 | ofxMtlMapping2DVertex::activeVertex->up(); 476 | } 477 | } 478 | break; 479 | 480 | case 358: //right 481 | if (ofxMtlMapping2DControls::mapping2DControls()->editShapes()) { 482 | if(ofxMtlMapping2DShape::activeShape && ofxMtlMapping2DShape::activeVertexId >=0) { 483 | ofxMtlMapping2DVertex::activeVertex->right(); 484 | } 485 | } 486 | break; 487 | 488 | case 359: //down 489 | if (ofxMtlMapping2DControls::mapping2DControls()->editShapes()) { 490 | if(ofxMtlMapping2DShape::activeShape && ofxMtlMapping2DShape::activeVertexId >=0) { 491 | ofxMtlMapping2DVertex::activeVertex->down(); 492 | } 493 | } 494 | break; 495 | 496 | case 127: 497 | deleteShape(); 498 | break; 499 | 500 | case 8: 501 | deleteShape(); 502 | break; 503 | 504 | // case 'b': 505 | // if ((ofxMtlMapping2DShape::activeShapeId + 1) >= ofxMtlMapping2DShapes::pmShapes.size()) { 506 | // ofxMtlMapping2DShapes::pmShapes[0]->setAsActiveShape(); 507 | // } else { 508 | // ofxMtlMapping2DShapes::pmShapes[(ofxMtlMapping2DShape::activeShapeId + 1)]->setAsActiveShape(); 509 | // } 510 | // break; 511 | 512 | 513 | case 'n': 514 | if (ofxMtlMapping2DControls::mapping2DControls()->editShapes()) { 515 | if(ofxMtlMapping2DShape::activeShape) { 516 | ofxMtlMapping2DShape::activeVertexId++; 517 | ofxMtlMapping2DShape::activeVertexId %= ofxMtlMapping2DShape::activeShape->vertices.size(); 518 | 519 | //----- 520 | if (ofxMtlMapping2DShape::activeShape->vertices.size() > ofxMtlMapping2DShape::activeVertexId) 521 | { 522 | list::iterator it = ofxMtlMapping2DShape::activeShape->vertices.begin(); 523 | advance(it, ofxMtlMapping2DShape::activeVertexId); 524 | ofxMtlMapping2DVertex* vertex = *it; 525 | vertex->setAsActive(); 526 | } 527 | } 528 | } 529 | break; 530 | } 531 | } 532 | 533 | 534 | #pragma mark - 535 | #pragma mark Load and Save Shapes List 536 | //-------------------------------------------------------------- 537 | void ofxMtlMapping2D::loadShapesList() 538 | { 539 | // UI 540 | ofxMtlMapping2DControls::mapping2DControls()->clearShapesList(); 541 | 542 | // Delete everything 543 | while(!ofxMtlMapping2DShapes::pmShapes.empty()) delete ofxMtlMapping2DShapes::pmShapes.back(), ofxMtlMapping2DShapes::pmShapes.pop_back(); 544 | ofxMtlMapping2DShapes::pmShapes.clear(); 545 | ofxMtlMapping2DShape::resetActiveShapeVars(); 546 | 547 | 548 | //LOAD XML 549 | // ---- 550 | //the string is printed at the top of the app 551 | //to give the user some feedback 552 | string feedBackMessage = "loading " + _mappingXmlFilePath; 553 | ofLog(OF_LOG_NOTICE, "Status > " + feedBackMessage); 554 | 555 | //we load our settings file 556 | //if it doesn't exist we can still make one 557 | //by hitting the 's' key 558 | if( _shapesListXML.loadFile(_mappingXmlFilePath) ){ 559 | feedBackMessage = _mappingXmlFilePath + " loaded!"; 560 | }else{ 561 | feedBackMessage = "unable to load " + _mappingXmlFilePath + " check data/ folder"; 562 | } 563 | ofLog(OF_LOG_NOTICE, "Status > " + feedBackMessage); 564 | 565 | 566 | int shapeId = -1; 567 | 568 | // ---- 569 | //this is a more advanced use of ofXMLSettings 570 | //we are going to be reading multiple tags with the same name 571 | 572 | //lets see how many tags there are in the xml file 573 | int numRootTags = _shapesListXML.getNumTags("root"); 574 | int numShapeTags = 0; 575 | 576 | //if there is at least one tag we can read the list of cards 577 | //and then load their associated xml file 578 | if(numRootTags > 0){ 579 | //we push into the last tag 580 | //this temporarirly treats the tag as 581 | //the document root. 582 | _shapesListXML.pushTag("root", 0); 583 | 584 | //we see how many params/items we have stored in tags 585 | numShapeTags = _shapesListXML.getNumTags("shape"); 586 | ofLog(OF_LOG_NOTICE, "Status > numShapeTags :: " + ofToString(numShapeTags)); 587 | 588 | if(numShapeTags > 0){ 589 | for(int i = 0; i < numShapeTags; i++){ 590 | ofxMtlMapping2DShape* newShape; 591 | 592 | shapeId = _shapesListXML.getAttribute("shape", "id", 0, i); 593 | 594 | _shapesListXML.pushTag("shape", i); 595 | 596 | //SHAPES SETTINGS 597 | int numShapeSettingTags = _shapesListXML.getNumTags("setting"); 598 | 599 | for(int j = 0; j < numShapeSettingTags; j++){ 600 | string key = _shapesListXML.getAttribute("setting", "key", "nc", j); 601 | 602 | if (key == "type") { 603 | string shapeType = _shapesListXML.getValue("setting", "nan", j); 604 | 605 | if (shapeType == "quad") { 606 | newShape = new ofxMtlMapping2DQuad(); 607 | newShape->shapeType = MAPPING_2D_SHAPE_QUAD; 608 | } else if (shapeType == "grid") { 609 | newShape = new ofxMtlMapping2DGrid(); 610 | newShape->shapeType = MAPPING_2D_SHAPE_GRID; 611 | } else if (shapeType == "triangle") { 612 | newShape = new ofxMtlMapping2DTriangle(); 613 | newShape->shapeType = MAPPING_2D_SHAPE_TRIANGLE; 614 | } else if (shapeType == "mask") { 615 | newShape = new ofxMtlMapping2DMask(); 616 | newShape->shapeType = MAPPING_2D_SHAPE_MASK; 617 | } else { 618 | newShape = new ofxMtlMapping2DQuad(); 619 | newShape->shapeType = MAPPING_2D_SHAPE_QUAD; 620 | } 621 | } 622 | } 623 | 624 | if(numShapeSettingTags > 0) { 625 | for(int j = 0; j < numShapeSettingTags; j++){ 626 | string key = _shapesListXML.getAttribute("setting", "key", "nc", j); 627 | string value = _shapesListXML.getValue("setting", "", j); 628 | newShape->shapeSettings[key] = value; 629 | } 630 | } 631 | 632 | //OUTPUT VERTICES 633 | _shapesListXML.pushTag("outputVertices", 0); 634 | int numVertexItemTags = _shapesListXML.getNumTags("vertex"); 635 | for (int j = 0; j < numVertexItemTags; j++) { 636 | int x = _shapesListXML.getAttribute("vertex", "x", 0, j); 637 | int y = _shapesListXML.getAttribute("vertex", "y", 0, j); 638 | 639 | //Create a new vertex 640 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 641 | newVertex->init(x-newVertex->width/2, y-newVertex->height/2); 642 | newShape->vertices.push_back(newVertex); 643 | } 644 | _shapesListXML.popTag(); 645 | 646 | 647 | if(newShape->shapeType != MAPPING_2D_SHAPE_MASK) { 648 | //INPUT QUADS 649 | _shapesListXML.pushTag("inputPolygon", 0); 650 | 651 | //Create a new vertex 652 | newShape->inputPolygon = new ofxMtlMapping2DInput(); 653 | 654 | //INPUT VERTICES 655 | numVertexItemTags = _shapesListXML.getNumTags("vertex"); 656 | for (int k = 0; k < numVertexItemTags; k++) { 657 | int x = _shapesListXML.getAttribute("vertex", "x", 0, k); 658 | int y = _shapesListXML.getAttribute("vertex", "y", 0, k); 659 | 660 | //Create a new vertex 661 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 662 | newVertex->init(x-newVertex->width/2, y-newVertex->height/2); 663 | newVertex->isDefiningTectureCoord = true; 664 | newShape->inputPolygon->vertices.push_back(newVertex); 665 | } 666 | 667 | newShape->inputPolygon->init(shapeId); 668 | newShape->inputPolygon->disable(); 669 | 670 | _shapesListXML.popTag(); 671 | } 672 | 673 | newShape->init(shapeId); 674 | newShape->disable(); 675 | ofxMtlMapping2DShapes::pmShapes.push_front(newShape); 676 | 677 | ofxMtlMapping2DControls::mapping2DControls()->addShapeToList(shapeId, newShape->shapeType); 678 | 679 | _shapesListXML.popTag(); 680 | 681 | } 682 | } 683 | 684 | //this pops us out of the tag 685 | //sets the root back to the xml document 686 | _shapesListXML.popTag(); 687 | } 688 | 689 | ofxMtlMapping2DShape::nextShapeId = shapeId; 690 | } 691 | 692 | //-------------------------------------------------------------- 693 | void ofxMtlMapping2D::saveShapesList() 694 | { 695 | 696 | list pmShapesCopy; 697 | pmShapesCopy.resize (ofxMtlMapping2DShapes::pmShapes.size()); 698 | copy (ofxMtlMapping2DShapes::pmShapes.begin(), ofxMtlMapping2DShapes::pmShapes.end(), pmShapesCopy.begin()); 699 | pmShapesCopy.sort(Comparator()); 700 | 701 | ofxXmlSettings newShapesListXML; 702 | int shapeCounter = 0; 703 | 704 | newShapesListXML.addTag("root"); 705 | newShapesListXML.pushTag("root", 0); 706 | 707 | //Create/Update XML 708 | list::reverse_iterator it; 709 | for (it=pmShapesCopy.rbegin(); it!=pmShapesCopy.rend(); it++) { 710 | ofxMtlMapping2DShape* shape = *it; 711 | 712 | int tagNum = newShapesListXML.addTag("shape"); 713 | newShapesListXML.addAttribute("shape", "id", shape->shapeId, tagNum); 714 | newShapesListXML.pushTag("shape", tagNum); 715 | 716 | //Shape settings 717 | map::iterator itShape; 718 | for ( itShape=shape->shapeSettings.begin() ; itShape != shape->shapeSettings.end(); itShape++ ) { 719 | int tagNum = newShapesListXML.addTag("setting"); 720 | newShapesListXML.addAttribute("setting", "key", (*itShape).first, tagNum); 721 | newShapesListXML.setValue("setting", (*itShape).second, tagNum); 722 | } 723 | 724 | //Output Vertex/Vertices 725 | tagNum = newShapesListXML.addTag("outputVertices"); 726 | newShapesListXML.pushTag("outputVertices", tagNum); 727 | list::iterator itVertex; 728 | for (itVertex=shape->vertices.begin(); itVertex!=shape->vertices.end(); itVertex++) { 729 | ofxMtlMapping2DVertex* vertex = *itVertex; 730 | 731 | int tagNum = newShapesListXML.addTag("vertex"); 732 | newShapesListXML.addAttribute("vertex", "x", (int)vertex->center.x, tagNum); 733 | newShapesListXML.addAttribute("vertex", "y", (int)vertex->center.y, tagNum); 734 | } 735 | newShapesListXML.popTag(); 736 | 737 | if(shape->shapeType != MAPPING_2D_SHAPE_MASK) { 738 | //Input Quads 739 | tagNum = newShapesListXML.addTag("inputPolygon"); 740 | newShapesListXML.pushTag("inputPolygon", tagNum); 741 | //Vertices 742 | for (itVertex=shape->inputPolygon->vertices.begin(); itVertex!=shape->inputPolygon->vertices.end(); itVertex++) { 743 | ofxMtlMapping2DVertex* vertex = *itVertex; 744 | 745 | int tagNum = newShapesListXML.addTag("vertex"); 746 | newShapesListXML.addAttribute("vertex", "x", (int)vertex->center.x, tagNum); 747 | newShapesListXML.addAttribute("vertex", "y", (int)vertex->center.y, tagNum); 748 | } 749 | newShapesListXML.popTag(); 750 | } 751 | newShapesListXML.popTag(); 752 | 753 | shapeCounter++; 754 | } 755 | 756 | //Save to file 757 | newShapesListXML.saveFile(_mappingXmlFilePath); 758 | ofLog(OF_LOG_NOTICE, "Status > settings saved to xml!"); 759 | 760 | } 761 | 762 | #pragma mark - 763 | #pragma mark Getters 764 | //-------------------------------------------------------------- 765 | vector ofxMtlMapping2D::getMaskShapes() 766 | { 767 | return ofxMtlMapping2DShapes::getShapesOutputPolylineWithType(MAPPING_2D_SHAPE_MASK); 768 | } 769 | 770 | #pragma mark - 771 | //-------------------------------------------------------------- 772 | void ofxMtlMapping2D::chessBoard(int nbOfCol) 773 | { 774 | ofSetColor(ofColor::white); 775 | ofFill(); 776 | 777 | int boardWidth = ofGetWidth(); 778 | int boardHeight = ofGetHeight(); 779 | 780 | float squareSize = boardWidth / nbOfCol; 781 | int nbOfRow = ceil(boardHeight / squareSize); 782 | for (int colId = 0; colId < nbOfCol; colId++) { 783 | for (int rowId = 0; rowId < nbOfRow; rowId++) { 784 | if ((colId + rowId) % 2 == 0) { 785 | ofSetColor(ofColor::white); 786 | } else { 787 | ofSetColor(ofColor::black); 788 | } 789 | 790 | ofRect(colId * squareSize, rowId * squareSize, squareSize, squareSize); 791 | } 792 | } 793 | 794 | //Frame 795 | ofNoFill(); 796 | ofSetColor(ofColor::yellow); 797 | glLineWidth(8.0f); 798 | ofRect(.0f, .0f, boardWidth, boardHeight); 799 | glLineWidth(1.0f); 800 | 801 | ofFill(); 802 | ofSetColor(ofColor::red); 803 | ofRect(60.0f, .0f, 20.0f, 20.0f); 804 | ofSetColor(ofColor::green); 805 | ofRect(80.0f, .0f, 20.0f, 20.0f); 806 | ofSetColor(ofColor::blue); 807 | ofRect(100.0f, .0f, 20.0f, 20.0f); 808 | 809 | ofSetColor(ofColor::white); 810 | } 811 | 812 | 813 | -------------------------------------------------------------------------------- /src/ofxMtlMapping2D.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // OF 4 | #include "ofMain.h" 5 | 6 | // Addons 7 | #include "ofxXmlSettings.h" 8 | 9 | //Mapping 10 | #include "ofxMtlMapping2DVertex.h" 11 | #include "ofxMtlMapping2DQuad.h" 12 | #include "ofxMtlMapping2DGrid.h" 13 | #include "ofxMtlMapping2DTriangle.h" 14 | #include "ofxMtlMapping2DMask.h" 15 | #include "ofxMtlMapping2DShape.h" 16 | 17 | #include "mtlUtils.h" 18 | 19 | 20 | //======================================================================== 21 | class ofxMtlMapping2D { 22 | 23 | public: 24 | ofxMtlMapping2D(); 25 | virtual ~ofxMtlMapping2D(); 26 | 27 | void init(int width, int height, string mappingXmlFilePath = "mapping/xml/shapes.xml", string uiXmlFilePath = "mapping/controls/mapping.xml", int numSample = 0); 28 | void update(); 29 | 30 | void bind(); 31 | void unbind(); 32 | void drawFbo(); 33 | void draw(); 34 | 35 | void mousePressed(ofMouseEventArgs &e); 36 | void keyPressed(ofKeyEventArgs &e); 37 | void windowResized(ofResizeEventArgs &e); 38 | 39 | vector getMaskShapes(); 40 | void chessBoard(int nbOfCol = 10); 41 | 42 | private: 43 | string _mappingXmlFilePath; 44 | ofFbo _fbo; 45 | ofxXmlSettings _shapesListXML; 46 | list::iterator iteratorForShapeWithId(int shapeId); 47 | 48 | void render(); 49 | 50 | void createQuad(float _x, float _y); 51 | void createGrid(float _x, float _y); 52 | void createTriangle(float _x, float _y); 53 | void createMask(float _x, float _y); 54 | void deleteShape(); 55 | 56 | void loadShapesList(); 57 | void saveShapesList(); 58 | 59 | void addListeners(); 60 | void removeListeners(); 61 | }; -------------------------------------------------------------------------------- /src/ofxMtlMapping2DMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //-------------------------------------------------------------- 4 | //-------------------------------------------------------------- 5 | enum ofxMtlMapping2DMode 6 | { 7 | MAPPING_MODE_OUTPUT = 0, 8 | MAPPING_MODE_INPUT = 1, 9 | MAPPING_MODE_COUNT 10 | }; 11 | -------------------------------------------------------------------------------- /src/ofxMtlMapping2DShapeType.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //-------------------------------------------------------------- 4 | //-------------------------------------------------------------- 5 | enum ofxMtlMapping2DShapeType 6 | { 7 | MAPPING_2D_SHAPE_QUAD = 0, 8 | MAPPING_2D_SHAPE_GRID = 1, 9 | MAPPING_2D_SHAPE_TRIANGLE = 2, 10 | MAPPING_2D_SHAPE_MASK = 3, 11 | MAPPING_2D_SHAPE_COUNT 12 | }; 13 | -------------------------------------------------------------------------------- /src/ofxMtlMapping2DShapes.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DShapes.h" 2 | #include "ofxMtlMapping2DShapeType.h" 3 | 4 | //-------------------------------------------------------------- 5 | //-------------------------------------------------------------- 6 | list ofxMtlMapping2DShapes::pmShapes; 7 | 8 | //-------------------------------------------------------------- 9 | ofxMtlMapping2DShape* ofxMtlMapping2DShapes::shapeWithId(int shapeId) 10 | { 11 | list::iterator it; 12 | for (it=pmShapes.begin(); it!=pmShapes.end(); it++) { 13 | ofxMtlMapping2DShape* shape = *it; 14 | if(shape->shapeId == shapeId) { 15 | return shape; 16 | } 17 | } 18 | 19 | return NULL; 20 | } 21 | 22 | // TODO: Generate and fill those two vector only 'once' when we start the application or quit the Edit Mode 23 | //-------------------------------------------------------------- 24 | vector ofxMtlMapping2DShapes::getShapesOutputPolylineWithType(int shapeType) 25 | { 26 | vector polylinesToReturn; 27 | 28 | list::iterator it; 29 | for (it=pmShapes.begin(); it!=pmShapes.end(); it++) { 30 | ofxMtlMapping2DShape* shape = *it; 31 | if(shape->shapeType == shapeType) { 32 | polylinesToReturn.push_back(shape->polyline); 33 | } 34 | } 35 | 36 | return polylinesToReturn; 37 | } 38 | 39 | //-------------------------------------------------------------- 40 | vector ofxMtlMapping2DShapes::getShapesInputPolyline() 41 | { 42 | vector polylinesToReturn; 43 | 44 | list::iterator it; 45 | for (it=pmShapes.begin(); it!=pmShapes.end(); it++) { 46 | ofxMtlMapping2DShape* shape = *it; 47 | if(shape->inputPolygon->polyline) { 48 | polylinesToReturn.push_back(shape->inputPolygon->polyline); 49 | } 50 | } 51 | 52 | return polylinesToReturn; 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/ofxMtlMapping2DShapes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | 5 | #include "ofxMtlMapping2DShape.h" 6 | 7 | //-------------------------------------------------------------- 8 | //-------------------------------------------------------------- 9 | struct Comparator { 10 | bool operator()(ofxMtlMapping2DShape* first, ofxMtlMapping2DShape* second) const { 11 | return first->shapeId > second->shapeId; 12 | } 13 | }; 14 | 15 | //-------------------------------------------------------------- 16 | //-------------------------------------------------------------- 17 | class ofxMtlMapping2DShapes { 18 | 19 | public: 20 | 21 | static list pmShapes; 22 | static ofxMtlMapping2DShape* shapeWithId(int shapeId); 23 | static vector getShapesOutputPolylineWithType(int shapeType); 24 | static vector getShapesInputPolyline(); 25 | 26 | 27 | 28 | }; -------------------------------------------------------------------------------- /src/settings/ofxMtlMapping2DSettings.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DSettings.h" 2 | 3 | // --- available / activated options 4 | const bool ofxMtlMapping2DSettings::kIsManuallyCreatingShapeEnabled = true; 5 | const bool ofxMtlMapping2DSettings::kIsManuallyAddingDeletingVertexEnabled = true; 6 | 7 | // --- 8 | ofTrueTypeFont ofxMtlMapping2DSettings::infoFont; 9 | 10 | // --- 11 | float ofxMtlMapping2DSettings::gridDefaultNbCols = 2.0f; 12 | float ofxMtlMapping2DSettings::gridDefaultNbRows = 2.0f; 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/settings/ofxMtlMapping2DSettings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | 5 | //-------------------------------------------------------------- 6 | class ofxMtlMapping2DSettings { 7 | public: 8 | 9 | // --- available / activated options 10 | static const bool kIsManuallyCreatingShapeEnabled; 11 | static const bool kIsManuallyAddingDeletingVertexEnabled; 12 | 13 | // --- 14 | static ofTrueTypeFont infoFont; 15 | 16 | // --- 17 | static float gridDefaultNbCols; 18 | static float gridDefaultNbRows; 19 | }; -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DGrid.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DGrid.h" 2 | #include "ofxMtlMapping2DControls.h" 3 | 4 | 5 | //-------------------------------------------------------------- 6 | //-------------------------------------------------------------- 7 | ofxMtlMapping2DGrid::ofxMtlMapping2DGrid() 8 | { 9 | internalMesh.setMode(OF_PRIMITIVE_TRIANGLES); 10 | } 11 | 12 | //-------------------------------------------------------------- 13 | ofxMtlMapping2DGrid::~ofxMtlMapping2DGrid(){ 14 | 15 | } 16 | 17 | //-------------------------------------------------------------- 18 | void ofxMtlMapping2DGrid::update() 19 | { 20 | ofxMtlMapping2DShape::update(); 21 | 22 | if (activeShape == this) { 23 | updateVertices(); 24 | updateUVMap(); 25 | } 26 | } 27 | 28 | //-------------------------------------------------------------- 29 | void ofxMtlMapping2DGrid::updateVertices(){ 30 | // --- 31 | for (int y = 0; y < gridNbRows; y++) { 32 | int rowControlPointIndex = y * (gridNbCols + 1); 33 | 34 | for (int x = 0; x < gridNbCols; x++) { 35 | int controlPointIndex = rowControlPointIndex + x; 36 | 37 | // Quad 38 | int topLeft = controlPointIndex; 39 | int topRight = controlPointIndex + 1; 40 | int bottomRight = (controlPointIndex + 1) + (gridNbCols + 1); 41 | int bottomLeft = controlPointIndex + (gridNbCols + 1); 42 | 43 | // --- 44 | list::iterator it = vertices.begin(); 45 | advance(it, topLeft); 46 | ofxMtlMapping2DVertex* topLeftVertex = *it; 47 | 48 | it = vertices.begin(); 49 | advance(it, topRight); 50 | ofxMtlMapping2DVertex* topRightVertex = *it; 51 | 52 | it = vertices.begin(); 53 | advance(it, bottomRight); 54 | ofxMtlMapping2DVertex* bottonRightVertex = *it; 55 | 56 | it = vertices.begin(); 57 | advance(it, bottomLeft); 58 | ofxMtlMapping2DVertex* bottomLeftVertex = *it; 59 | 60 | // --- Interpolate the quad's vertical edges 61 | vector left, right; 62 | left.resize(gridVerticalResolution+1); 63 | right.resize(gridVerticalResolution+1); 64 | 65 | for (int i_y = 0; i_y <= gridVerticalResolution; i_y++) { 66 | left[i_y] = topLeftVertex->center + ((bottomLeftVertex->center - topLeftVertex->center) / gridVerticalResolution) * (float)i_y; 67 | right[i_y] = topRightVertex->center + ((bottonRightVertex->center - topRightVertex->center) / gridVerticalResolution) * (float)i_y; 68 | } 69 | 70 | // --- Interpolate all internal points 71 | vector >grid; 72 | grid.resize(gridHorizontalResolution+1); 73 | for (int i_x = 0; i_x <= gridHorizontalResolution; i_x++) { 74 | grid[i_x].resize(gridVerticalResolution+1); 75 | for (int i_y = 0; i_y <= gridVerticalResolution; i_y++) { 76 | ofVec2f l = left[i_y]; 77 | ofVec2f r = right[i_y]; 78 | 79 | grid[i_x][i_y].set(l + ((r - l) / gridHorizontalResolution) * (float)i_x); 80 | } 81 | } 82 | 83 | // --- Update Control Mesh 84 | controlMesh.setVertex(topLeft, topLeftVertex->center); 85 | controlMesh.setVertex(topRight, topRightVertex->center); 86 | controlMesh.setVertex(bottomRight, bottonRightVertex->center); 87 | controlMesh.setVertex(bottomLeft, bottomLeftVertex->center); 88 | 89 | // --- Update internal mesh 90 | int quadStartIndex = (y * ((gridNbCols * gridHorizontalResolution) + 1) * gridVerticalResolution) + (x * gridHorizontalResolution); 91 | 92 | for (int i_y = 0; i_y < gridVerticalResolution; i_y++) { 93 | for (int i_x = 0; i_x < gridHorizontalResolution; i_x++) { 94 | 95 | int vertexIndex = quadStartIndex + ( i_y * ((gridNbCols * gridHorizontalResolution) + 1) + i_x ); 96 | 97 | int i_topLeft = vertexIndex; 98 | int i_topRight = vertexIndex + 1; 99 | int i_bottomRight = (vertexIndex + 1) + ((gridNbCols * gridHorizontalResolution) + 1); 100 | int i_bottomLeft = vertexIndex + ((gridNbCols * gridHorizontalResolution) + 1); 101 | 102 | ofVec2f i_topLeftVertex = grid[i_x][i_y]; 103 | ofVec2f i_topRightVertex = grid[i_x+1][i_y]; 104 | ofVec2f i_bottomRightVertex = grid[i_x+1][i_y+1]; 105 | ofVec2f i_bottomLeftVertex = grid[i_x][i_y+1]; 106 | 107 | internalMesh.setVertex(i_topLeft, i_topLeftVertex); 108 | internalMesh.setVertex(i_topRight, i_topRightVertex); 109 | internalMesh.setVertex(i_bottomRight, i_bottomRightVertex); 110 | internalMesh.setVertex(i_bottomLeft, i_bottomLeftVertex); 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | //-------------------------------------------------------------- 118 | void ofxMtlMapping2DGrid::draw() 119 | { 120 | // ---- OUTPUT MODE 121 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 122 | ofSetColor(ofColor::white); 123 | controlMesh.drawWireframe(); 124 | } 125 | 126 | //drawInternalMesh(); 127 | 128 | ofxMtlMapping2DShape::draw(); 129 | } 130 | 131 | //-------------------------------------------------------------- 132 | void ofxMtlMapping2DGrid::drawInternalMesh() 133 | { 134 | ofSetColor(ofColor::red); 135 | internalMesh.drawWireframe(); 136 | } 137 | 138 | //-------------------------------------------------------------- 139 | void ofxMtlMapping2DGrid::render() 140 | { 141 | internalMesh.draw(); 142 | } 143 | 144 | //-------------------------------------------------------------- 145 | void ofxMtlMapping2DGrid::createDefaultShape() 146 | { 147 | shapeSettings["type"] = "grid"; 148 | shapeSettings["cols"] = ofToString(ofxMtlMapping2DSettings::gridDefaultNbCols); 149 | shapeSettings["rows"] = ofToString(ofxMtlMapping2DSettings::gridDefaultNbRows); 150 | 151 | // --- 152 | updateGridAndMesh(true); 153 | 154 | // --- 155 | //Create a new vertex 156 | int xOffset = .0f; //ofGetWidth()/2.0; 157 | int yOffset = .0f; //ofGetHeight()/2.0; 158 | 159 | int x = 0; 160 | int y = 0; 161 | 162 | // --- Input 163 | inputPolygon = new ofxMtlMapping2DInput(); 164 | 165 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 166 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 167 | newVertex->isDefiningTectureCoord = true; 168 | inputPolygon->vertices.push_back(newVertex); 169 | 170 | x = ofGetWidth(); 171 | y = 0; 172 | newVertex = new ofxMtlMapping2DVertex(); 173 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 174 | newVertex->isDefiningTectureCoord = true; 175 | inputPolygon->vertices.push_back(newVertex); 176 | 177 | x = ofGetWidth(); 178 | y = ofGetHeight(); 179 | newVertex = new ofxMtlMapping2DVertex(); 180 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 181 | newVertex->isDefiningTectureCoord = true; 182 | inputPolygon->vertices.push_back(newVertex); 183 | 184 | x = 0; 185 | y = ofGetHeight(); 186 | newVertex = new ofxMtlMapping2DVertex(); 187 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 188 | newVertex->isDefiningTectureCoord = true; 189 | inputPolygon->vertices.push_back(newVertex); 190 | 191 | // --- 192 | inputPolygon->init(shapeId); 193 | 194 | // --- Generate the texture coordinates; 195 | updateUVMap(); 196 | } 197 | 198 | //-------------------------------------------------------------- 199 | void ofxMtlMapping2DGrid::initShape() 200 | { 201 | updateGridAndMesh(); 202 | updateUVMap(); 203 | updateVertices(); 204 | } 205 | 206 | //-------------------------------------------------------------- 207 | void ofxMtlMapping2DGrid::updateGrid() 208 | { 209 | shapeSettings["cols"] = ofToString(gridNbCols); 210 | shapeSettings["rows"] = ofToString(gridNbRows); 211 | 212 | updateGridAndMesh(true); 213 | updateUVMap(); 214 | } 215 | 216 | //-------------------------------------------------------------- 217 | void ofxMtlMapping2DGrid::updateGridAndMesh(bool startFresh) 218 | { 219 | // --- 220 | gridWidth = ofGetWidth(); 221 | gridHeight = ofGetHeight(); 222 | gridNbCols = ofToInt(shapeSettings["cols"]); 223 | gridNbRows = ofToInt(shapeSettings["rows"]); 224 | gridHorizontalResolution = 12; 225 | gridVerticalResolution = 12; 226 | 227 | gridQuadWidth = gridWidth / gridNbCols; 228 | gridQuadHeight = gridHeight / gridNbRows; 229 | gridCellWidth = gridQuadWidth / gridHorizontalResolution; 230 | gridCellHeight = gridQuadHeight / gridVerticalResolution; 231 | 232 | // --- Controls 233 | if (startFresh) { 234 | ofxMtlMapping2DVertex* newVertex; 235 | 236 | if (vertices.size() != 0) { 237 | while(!vertices.empty()) delete vertices.back(), vertices.pop_back(); 238 | vertices.clear(); 239 | 240 | polyline->clear(); 241 | 242 | // ---- 243 | //ofxMtlMapping2DShape::resetActiveShapeVars(); 244 | //ofxMtlMapping2DPolygon::resetActivePolygonVars(); 245 | 246 | //ofxMtlMapping2DControls::mapping2DControls()->unselectShapesToggles(); 247 | } 248 | 249 | // --- new shape 250 | for (int y = 0; y <= gridNbRows; y++) { 251 | float controlPointY = y * gridQuadHeight; 252 | 253 | for (int x = 0; x <= gridNbCols; x++) { 254 | float controlPointX = x * gridQuadWidth; 255 | 256 | // --- 257 | newVertex = new ofxMtlMapping2DVertex(); 258 | if (y == 0) { 259 | newVertex->edgeIndex = 0; 260 | } else if(y == gridNbRows) { 261 | newVertex->edgeIndex = 2; 262 | } else if (x == 0) { 263 | newVertex->edgeIndex = 3; 264 | } else if (x == gridNbCols) { 265 | newVertex->edgeIndex = 1; 266 | } else { 267 | newVertex->edgeIndex = -1; 268 | newVertex->bIsOnAnEdge = false; 269 | } 270 | newVertex->init(controlPointX - newVertex->width/2, controlPointY - newVertex->height/2); 271 | vertices.push_back(newVertex); 272 | } 273 | } 274 | 275 | enableVertices(); 276 | } else { 277 | cout << "1." << endl; 278 | for (int y = 0; y <= gridNbRows; y++) { 279 | int rowControlPointIndex = y * (gridNbCols + 1); 280 | cout << "2." << endl; 281 | cout << "rowControlPointIndex :: " << rowControlPointIndex << endl; 282 | for (int x = 0; x <= gridNbCols; x++) { 283 | int controlPointIndex = rowControlPointIndex + x; 284 | cout << "3." << endl; 285 | cout << "controlPointIndex :: " << controlPointIndex << endl; 286 | 287 | list::iterator it = vertices.begin(); 288 | advance(it, controlPointIndex); 289 | ofxMtlMapping2DVertex* controlVertex = *it; 290 | 291 | // --- 292 | if (y == 0) { 293 | controlVertex->edgeIndex = 0; 294 | } else if(y == gridNbRows) { 295 | controlVertex->edgeIndex = 2; 296 | } else if (x == 0) { 297 | controlVertex->edgeIndex = 3; 298 | } else if (x == gridNbCols) { 299 | controlVertex->edgeIndex = 1; 300 | } else { 301 | controlVertex->edgeIndex = -1; 302 | controlVertex->bIsOnAnEdge = false; 303 | } 304 | } 305 | } 306 | } 307 | 308 | // --- 309 | controlMesh.clear(); 310 | 311 | list::iterator it; 312 | for (it=vertices.begin(); it!=vertices.end(); it++) { 313 | ofxMtlMapping2DVertex* vertex = *it; 314 | 315 | controlMesh.addVertex(ofVec3f(vertex->center.x, vertex->center.y, .0f)); 316 | 317 | } 318 | 319 | for (int y = 0; y < gridNbRows; y++) { 320 | for (int x = 0; x < gridNbCols; x++) { 321 | 322 | int vertexIndex = y * (gridNbCols + 1) + x; 323 | 324 | int topLeft = vertexIndex; 325 | int topRight = vertexIndex + 1; 326 | int bottomRight = (vertexIndex + 1) + (gridNbCols + 1); 327 | int bottomLeft = vertexIndex + (gridNbCols + 1); 328 | 329 | controlMesh.addIndex(topLeft); 330 | controlMesh.addIndex(topRight); 331 | controlMesh.addIndex(bottomLeft); 332 | 333 | controlMesh.addIndex(topRight); 334 | controlMesh.addIndex(bottomRight); 335 | controlMesh.addIndex(bottomLeft); 336 | } 337 | } 338 | 339 | // --- Internal mesh vertices 340 | internalMesh.clearVertices(); 341 | 342 | for (int y = 0; y <= (gridNbRows * gridVerticalResolution); y++) { 343 | float vertexY = y * gridCellHeight; 344 | 345 | for (int x = 0; x <= (gridNbCols * gridHorizontalResolution); x++) { 346 | float vertexX = x * gridCellWidth; 347 | 348 | internalMesh.addVertex(ofVec3f(vertexX, vertexY, .0f)); 349 | } 350 | } 351 | 352 | // --- Internal mesh indices 353 | internalMesh.clearIndices(); 354 | 355 | int nbOfVertices = (gridNbCols * gridHorizontalResolution) * (gridNbRows * gridVerticalResolution); 356 | 357 | for (int y = 0; y < (gridNbRows * gridVerticalResolution); y++) { 358 | for (int x = 0; x < (gridNbCols * gridHorizontalResolution); x++) { 359 | 360 | int vertexIndex = y * ((gridNbCols * gridHorizontalResolution) + 1) + x; 361 | 362 | int topLeft = vertexIndex; 363 | int topRight = vertexIndex + 1; 364 | int bottomRight = (vertexIndex + 1) + ((gridNbCols * gridHorizontalResolution) + 1); 365 | int bottomLeft = vertexIndex + ((gridNbCols * gridHorizontalResolution) + 1); 366 | 367 | internalMesh.addIndex(topLeft); 368 | internalMesh.addIndex(topRight); 369 | internalMesh.addIndex(bottomLeft); 370 | 371 | internalMesh.addIndex(topRight); 372 | internalMesh.addIndex(bottomRight); 373 | internalMesh.addIndex(bottomLeft); 374 | } 375 | } 376 | } 377 | 378 | //-------------------------------------------------------------- 379 | void ofxMtlMapping2DGrid::updateUVMap() 380 | { 381 | internalMesh.clearTexCoords(); 382 | 383 | ofVec2f coordinatesStart; 384 | ofVec2f coordinatesEnd; 385 | 386 | coordinatesStart.x = inputPolygon->polyline->getVertices()[0].x; 387 | coordinatesStart.y = inputPolygon->polyline->getVertices()[0].y; 388 | coordinatesEnd.x = inputPolygon->polyline->getVertices()[2].x; 389 | coordinatesEnd.y = inputPolygon->polyline->getVertices()[2].y; 390 | 391 | // --- 392 | ofVec2f uvSize = coordinatesEnd - coordinatesStart; 393 | float uvCellWidth = uvSize.x / (gridNbCols * gridHorizontalResolution); 394 | float uvCellHeight = uvSize.y / (gridNbRows * gridVerticalResolution); 395 | 396 | for (int y = 0; y <= (gridNbRows * gridVerticalResolution); y++) { 397 | float uvCellY = coordinatesStart.y + y * uvCellHeight; 398 | 399 | for (int x = 0; x <= (gridNbCols * gridHorizontalResolution); x++) { 400 | float uvCellX = coordinatesStart.x + x * uvCellWidth; 401 | 402 | internalMesh.addTexCoord(ofVec2f(uvCellX, uvCellY)); 403 | } 404 | } 405 | } -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DGrid.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMtlMapping2DShape.h" 4 | 5 | //-------------------------------------------------------------- 6 | //-------------------------------------------------------------- 7 | class ofxMtlMapping2DGrid: public ofxMtlMapping2DShape { 8 | 9 | public: 10 | 11 | ofxMtlMapping2DGrid(); 12 | ~ofxMtlMapping2DGrid(); 13 | 14 | void update(); 15 | void draw(); 16 | 17 | void updateGrid(); 18 | 19 | int getNbCols() { return gridNbCols; } 20 | int getNbRows() { return gridNbRows; } 21 | 22 | float gridNbCols; 23 | float gridNbRows; 24 | 25 | protected: 26 | virtual void createDefaultShape(); 27 | virtual void initShape(); 28 | virtual void render(); 29 | 30 | void updateVertices(); 31 | void updateGridAndMesh(bool startFresh = false); 32 | void updateUVMap(); 33 | void drawInternalMesh(); 34 | 35 | ofMesh controlMesh; 36 | ofVboMesh internalMesh; 37 | 38 | int gridWidth; 39 | int gridHeight; 40 | int gridHorizontalResolution; 41 | int gridVerticalResolution; 42 | 43 | float gridQuadWidth; 44 | float gridQuadHeight; 45 | float gridCellWidth; 46 | float gridCellHeight; 47 | }; 48 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DInput.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DInput.h" 2 | #include "homography.h" 3 | 4 | 5 | //-------------------------------------------------------------- 6 | //-------------------------------------------------------------- 7 | ofxMtlMapping2DInput::ofxMtlMapping2DInput() 8 | { 9 | } 10 | 11 | //-------------------------------------------------------------- 12 | ofxMtlMapping2DInput::~ofxMtlMapping2DInput() 13 | { 14 | } 15 | 16 | #pragma mark - 17 | #pragma mark Lifecycle 18 | 19 | //-------------------------------------------------------------- 20 | void ofxMtlMapping2DInput::update(bool isQuad) 21 | { 22 | 23 | if (activePolygon == this && isQuad) { 24 | list::iterator it; 25 | for (it=vertices.begin(); it!=vertices.end(); it++) { 26 | ofxMtlMapping2DVertex* vertex = *it; 27 | 28 | if(ofxMtlMapping2DVertex::activeVertex == vertex) { 29 | int i = distance(vertices.begin(), it); 30 | 31 | if (i == 0) { 32 | getVertex(1)->snapIt(getVertex(1)->x, vertex->y); 33 | getVertex(3)->snapIt(vertex->x, getVertex(3)->y); 34 | } else if (i == 1) { 35 | getVertex(0)->snapIt(getVertex(0)->x, vertex->y); 36 | getVertex(2)->snapIt(vertex->x, getVertex(2)->y); 37 | } else if (i == 2) { 38 | getVertex(1)->snapIt(vertex->x, getVertex(1)->y); 39 | getVertex(3)->snapIt(getVertex(3)->x, vertex->y); 40 | } else { 41 | getVertex(0)->snapIt(vertex->x, getVertex(0)->y); 42 | getVertex(2)->snapIt(getVertex(2)->x, vertex->y); 43 | } 44 | } 45 | } 46 | } 47 | 48 | // ---- 49 | _super::update(); 50 | 51 | } 52 | 53 | #pragma mark - 54 | #pragma mark Homography 55 | 56 | //-------------------------------------------------------------- 57 | void ofxMtlMapping2DInput::calcHomography(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) 58 | { 59 | ofPoint src[4]; 60 | ofPoint dst[4]; 61 | 62 | list::iterator it; 63 | it=vertices.begin(); 64 | ofxMtlMapping2DVertex* vertex = *it; 65 | src[0].set(vertex->x - (boundingBox.x -15), vertex->y - (boundingBox.y -15), 0); 66 | 67 | it++; 68 | vertex = *it; 69 | src[1].set(vertex->x - (boundingBox.x -15), vertex->y - (boundingBox.y -15), 0); 70 | 71 | it++; 72 | vertex = *it; 73 | src[2].set(vertex->x - (boundingBox.x -15), vertex->y - (boundingBox.y -15), 0); 74 | 75 | it++; 76 | vertex = *it; 77 | src[3].set(vertex->x - (boundingBox.x -15), vertex->y - (boundingBox.y -15), 0); 78 | 79 | dst[0].set(x0, y0, 0); 80 | dst[1].set(x1, y1, 0); 81 | dst[2].set(x2, y2, 0); 82 | dst[3].set(x3, y3, 0); 83 | 84 | findHomography(src, dst, homoMatrix); 85 | } 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DInput.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofMain.h" 4 | #include "ofxMtlMapping2DVertex.h" 5 | #include "ofxMtlMapping2DPolygon.h" 6 | 7 | 8 | //-------------------------------------------------------------- 9 | //-------------------------------------------------------------- 10 | class ofxMtlMapping2DInput : public ofxMtlMapping2DPolygon { 11 | 12 | public: 13 | ofxMtlMapping2DInput(); 14 | ~ofxMtlMapping2DInput(); 15 | 16 | void update(bool isQuad); 17 | 18 | void calcHomography(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3); 19 | 20 | GLfloat homoMatrix[16]; 21 | 22 | private: 23 | typedef ofxMtlMapping2DPolygon _super; 24 | }; 25 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DMask.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DMask.h" 2 | 3 | //-------------------------------------------------------------- 4 | //-------------------------------------------------------------- 5 | ofxMtlMapping2DMask::ofxMtlMapping2DMask() 6 | { 7 | 8 | } 9 | 10 | //-------------------------------------------------------------- 11 | ofxMtlMapping2DMask::~ofxMtlMapping2DMask(){ 12 | 13 | } 14 | 15 | //-------------------------------------------------------------- 16 | void ofxMtlMapping2DMask::render() 17 | { 18 | ofBeginShape(); 19 | ofFill(); 20 | for (int i = 0; i < polyline->size(); i++) { 21 | ofVertex(polyline->getVertices()[i].x, polyline->getVertices()[i].y); 22 | } 23 | ofEndShape(true); 24 | } 25 | 26 | //-------------------------------------------------------------- 27 | void ofxMtlMapping2DMask::createDefaultShape() 28 | { 29 | shapeSettings["type"] = "mask"; 30 | 31 | int xOffset = ofGetWidth()/2.0; 32 | int yOffset = ofGetHeight()/2.0; 33 | 34 | //Create a new vertex 35 | int x = 50; 36 | int y = 0; 37 | 38 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 39 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 40 | vertices.push_back(newVertex); 41 | 42 | //Create a new vertex 43 | x = 0; 44 | y = 100; 45 | 46 | newVertex = new ofxMtlMapping2DVertex(); 47 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 48 | vertices.push_back(newVertex); 49 | 50 | //Create a new vertex 51 | x = 100; 52 | y = 100; 53 | 54 | newVertex = new ofxMtlMapping2DVertex(); 55 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 56 | vertices.push_back(newVertex); 57 | } -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DMask.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMtlMapping2DShape.h" 4 | 5 | //-------------------------------------------------------------- 6 | //-------------------------------------------------------------- 7 | class ofxMtlMapping2DMask : public ofxMtlMapping2DShape { 8 | 9 | public: 10 | 11 | ofxMtlMapping2DMask(); 12 | ~ofxMtlMapping2DMask(); 13 | 14 | protected: 15 | virtual void createDefaultShape(); 16 | virtual void render(); 17 | 18 | }; 19 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DPolygon.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DPolygon.h" 2 | 3 | ofxMtlMapping2DPolygon* ofxMtlMapping2DPolygon::activePolygon = NULL; 4 | ofxMtlMapping2DPolygon* ofxMtlMapping2DPolygon::previousActivePolygon = NULL; 5 | int ofxMtlMapping2DPolygon::activeVertexId = -1; 6 | 7 | //-------------------------------------------------------------- 8 | //-------------------------------------------------------------- 9 | void ofxMtlMapping2DPolygon::resetActivePolygonVars(){ 10 | ofxMtlMapping2DPolygon::activePolygon = NULL; 11 | ofxMtlMapping2DPolygon::previousActivePolygon = NULL; 12 | ofxMtlMapping2DVertex::activeVertex = NULL; 13 | ofxMtlMapping2DPolygon::activeVertexId = -1; 14 | } 15 | 16 | 17 | 18 | //-------------------------------------------------------------- 19 | //-------------------------------------------------------------- 20 | ofxMtlMapping2DPolygon::ofxMtlMapping2DPolygon() 21 | { 22 | disableAllEvents(); 23 | enableMouseEvents(); 24 | 25 | // ---- 26 | polyline = new ofPolyline(); 27 | shapeId = -1; 28 | } 29 | 30 | //-------------------------------------------------------------- 31 | ofxMtlMapping2DPolygon::~ofxMtlMapping2DPolygon(){ 32 | 33 | // ---- 34 | while(!vertices.empty()) delete vertices.back(), vertices.pop_back(); 35 | vertices.clear(); 36 | 37 | // ---- 38 | polyline->clear(); 39 | delete polyline; 40 | 41 | // ---- 42 | resetActivePolygonVars(); 43 | } 44 | 45 | 46 | #pragma mark - 47 | #pragma mark Lifecycle 48 | 49 | //-------------------------------------------------------------- 50 | void ofxMtlMapping2DPolygon::init(int sId, bool defaultShape) 51 | { 52 | shapeId = sId; 53 | 54 | if (defaultShape) { 55 | createDefaultShape(); 56 | } 57 | 58 | updatePolyline(); 59 | } 60 | 61 | //-------------------------------------------------------------- 62 | void ofxMtlMapping2DPolygon::update() 63 | { 64 | if (activePolygon == this) { 65 | list::iterator it; 66 | for (it=vertices.begin(); it!=vertices.end(); it++) { 67 | ofxMtlMapping2DVertex* vertex = *it; 68 | 69 | if(ofxMtlMapping2DVertex::activeVertex == vertex) { 70 | activeVertexId = distance(vertices.begin(), it); 71 | } 72 | 73 | if (vertex->toBeRemoved) { 74 | vertex->kill(); 75 | vertices.remove(vertex); 76 | } 77 | } 78 | 79 | updatePolyline(); 80 | 81 | } 82 | 83 | //EST CE NECESSAIRE !!!! 84 | 85 | else { 86 | disableVertices(); 87 | } 88 | } 89 | 90 | 91 | //-------------------------------------------------------------- 92 | void ofxMtlMapping2DPolygon::draw() 93 | { 94 | ofEnableAlphaBlending(); 95 | 96 | // ---- 97 | list::iterator it; 98 | for (it=vertices.begin(); it!=vertices.end(); it++) { 99 | ofxMtlMapping2DVertex* vertex = *it; 100 | vertex->drawBack(); 101 | } 102 | 103 | // --- 104 | vector &polyPoints = polyline->getVertices(); 105 | 106 | ofFill(); 107 | ofBeginShape(); 108 | { 109 | if(activePolygon == this) { 110 | ofSetColor(0, 216, 255, 50); 111 | } else { 112 | ofSetColor(0, 216, 255, 20); 113 | } 114 | 115 | for (int i=0; i < polyPoints.size(); i++) { 116 | ofVertex(polyPoints[i].x, polyPoints[i].y); 117 | } 118 | } 119 | ofEndShape(true); 120 | 121 | ofNoFill(); 122 | ofBeginShape(); 123 | { 124 | ofSetColor(0, 216, 255, 150); 125 | for (int i=0; i < polyPoints.size(); i++) { 126 | ofVertex(polyPoints[i].x, polyPoints[i].y); 127 | } 128 | } 129 | ofEndShape(true); 130 | 131 | // ---- 132 | //Vertices 133 | for (it=vertices.begin(); it!=vertices.end(); it++) { 134 | ofxMtlMapping2DVertex* vertex = *it; 135 | vertex->drawTop(); 136 | } 137 | 138 | ofDisableAlphaBlending(); 139 | } 140 | 141 | 142 | //-------------------------------------------------------------- 143 | void ofxMtlMapping2DPolygon::drawID() 144 | { 145 | ofSetHexColor(0x000000); 146 | ofFill(); 147 | ofRect(_centroid2D.x - 10, _centroid2D.y - 10, 20, 20); 148 | ofSetHexColor(0xFFFFFF); 149 | 150 | int xOffset; 151 | int yOffset = 3; 152 | if (shapeId < 10) { 153 | xOffset = -3; 154 | } else if (shapeId < 100) { 155 | xOffset = -7; 156 | } else { 157 | xOffset = -11; 158 | } 159 | 160 | ofxMtlMapping2DSettings::infoFont.drawString(ofToString(shapeId), _centroid2D.x + xOffset, _centroid2D.y + yOffset); 161 | } 162 | 163 | 164 | 165 | #pragma mark - 166 | #pragma mark Update Shape's elemets 167 | 168 | //-------------------------------------------------------------- 169 | void ofxMtlMapping2DPolygon::updatePosition(int xInc, int yInc) 170 | { 171 | list::iterator it; 172 | for (it=vertices.begin(); it!=vertices.end(); it++) { 173 | ofxMtlMapping2DVertex* vertex = *it; 174 | vertex->setPosition(vertex->x + xInc, vertex->y + yInc); 175 | vertex->updateCenter(); 176 | } 177 | 178 | updatePolyline(); 179 | 180 | } 181 | 182 | //-------------------------------------------------------------- 183 | void ofxMtlMapping2DPolygon::updatePolyline() 184 | { 185 | // ---- 186 | polyline->clear(); 187 | 188 | list::iterator it; 189 | 190 | if (shapeType == MAPPING_2D_SHAPE_GRID) { 191 | for (int i=0; i <= 1; i++) { 192 | for (it=vertices.begin(); it!=vertices.end(); it++) { 193 | ofxMtlMapping2DVertex* vertex = *it; 194 | if (vertex->bIsOnAnEdge && vertex->edgeIndex == i) { 195 | // We check this for the grids, so that we don't add the vertices forming the interior of the grid 196 | polyline->addVertex(vertex->center.x, vertex->center.y); 197 | } 198 | } 199 | } 200 | 201 | for (int i=2; i <= 3; i++) { 202 | for (it=vertices.end(); it!=vertices.begin(); it--) { 203 | ofxMtlMapping2DVertex* vertex = *it; 204 | 205 | if (vertex->bIsOnAnEdge && vertex->edgeIndex == i) { 206 | // We check this for the grids, so that we don't add the vertices forming the interior of the grid 207 | polyline->addVertex(vertex->center.x, vertex->center.y); 208 | } 209 | } 210 | } 211 | 212 | } else { 213 | for (it=vertices.begin(); it!=vertices.end(); it++) { 214 | ofxMtlMapping2DVertex* vertex = *it; 215 | polyline->addVertex(vertex->center.x, vertex->center.y); 216 | } 217 | } 218 | 219 | // ---- 220 | _centroid2D = polyline->getCentroid2D(); 221 | 222 | 223 | // ---- Interactive obj 224 | boundingBox = polyline->getBoundingBox(); 225 | setPosition(boundingBox.x, boundingBox.y); 226 | setSize(boundingBox.width, boundingBox.height); 227 | } 228 | 229 | //-------------------------------------------------------------- 230 | bool ofxMtlMapping2DPolygon::hitTest(int tx, int ty) 231 | { 232 | if (polyline->inside(tx, ty)) { 233 | return true; 234 | } else { 235 | return false; 236 | } 237 | } 238 | 239 | //-------------------------------------------------------------- 240 | void ofxMtlMapping2DPolygon::select(int x, int y) 241 | { 242 | _grabAnchor.set(x, y); 243 | 244 | if(ofxMtlMapping2DVertex::activeVertex) 245 | return; 246 | 247 | setAsActive(); 248 | } 249 | 250 | //-------------------------------------------------------------- 251 | void ofxMtlMapping2DPolygon::setAsActive() 252 | { 253 | if (activePolygon != this) { 254 | previousActivePolygon = activePolygon; 255 | activePolygon = this; 256 | activeVertexId = -1; 257 | 258 | if (previousActivePolygon) { 259 | previousActivePolygon->setAsIdle(); 260 | } 261 | 262 | enableVertices(); 263 | } 264 | } 265 | 266 | //-------------------------------------------------------------- 267 | void ofxMtlMapping2DPolygon::setAsIdle() 268 | { 269 | disable(); 270 | disableVertices(); 271 | } 272 | 273 | #pragma mark - 274 | #pragma mark Mapping Vertices 275 | 276 | //-------------------------------------------------------------- 277 | void ofxMtlMapping2DPolygon::enableVertices() 278 | { 279 | list::iterator it; 280 | for (it=vertices.begin(); it!=vertices.end(); it++) { 281 | ofxMtlMapping2DVertex* vertex = *it; 282 | vertex->enabled = true; 283 | } 284 | } 285 | 286 | //-------------------------------------------------------------- 287 | void ofxMtlMapping2DPolygon::disableVertices() 288 | { 289 | list::iterator it; 290 | for (it=vertices.begin(); it!=vertices.end(); it++) { 291 | ofxMtlMapping2DVertex* vertex = *it; 292 | vertex->enabled = false; 293 | } 294 | } 295 | 296 | //-------------------------------------------------------------- 297 | ofxMtlMapping2DVertex* ofxMtlMapping2DPolygon::getVertex(int index) 298 | { 299 | list::iterator it; 300 | it = vertices.begin(); 301 | advance(it, index); 302 | 303 | return *it; 304 | } 305 | 306 | 307 | 308 | #pragma mark - 309 | #pragma mark Modify Shape at run time 310 | //-------------------------------------------------------------- 311 | void ofxMtlMapping2DPolygon::addPoint(int x, int y) 312 | { 313 | //Check if we are not clicking on an already existing vertex 314 | list::iterator it; 315 | for (it=vertices.begin(); it!=vertices.end(); it++) { 316 | ofxMtlMapping2DVertex* vertex = *it; 317 | 318 | //CE IF JE DOIS POUVOIR LE REMPLACER PAR UNE VAR STATIC. 319 | if (vertex->isMouseOver()){ 320 | cout << "EXISTING VERTEX \n"; 321 | return; 322 | } 323 | } 324 | 325 | //Check if we are not an existing line 326 | if (vertices.size() >= 2) { 327 | int nextVertex = 0; 328 | list::iterator it; 329 | list::iterator itNext; 330 | for (it=vertices.begin(); it!=vertices.end(); it++) { 331 | it++; 332 | if (it == vertices.end()) { 333 | itNext = vertices.begin(); 334 | } else { 335 | itNext = it; 336 | } 337 | it--; 338 | ofxMtlMapping2DVertex* vertex = *it; 339 | ofxMtlMapping2DVertex* nextVertex = *itNext; 340 | 341 | double dist = distanceToSegment(vertex->center, nextVertex->center, ofVec2f(x, y)); 342 | if ( dist < 10.0) { 343 | //Create a new vertex 344 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 345 | newVertex->init(x-newVertex->width/2, y-newVertex->height/2); 346 | newVertex->enabled = true; 347 | it++; 348 | vertices.insert(it, newVertex); 349 | it--; 350 | return; 351 | } 352 | } 353 | return; 354 | } 355 | 356 | //Create a new vertex 357 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 358 | newVertex->init(x-newVertex->width/2, y-newVertex->height/2); 359 | newVertex->enabled = true; 360 | vertices.push_back(newVertex); 361 | } 362 | 363 | 364 | #pragma mark - 365 | #pragma mark ofxMSAInteractiveObject related 366 | //-------------------------------------------------------------- 367 | void ofxMtlMapping2DPolygon::disable() 368 | { 369 | disableAllEvents(); 370 | } 371 | 372 | //-------------------------------------------------------------- 373 | void ofxMtlMapping2DPolygon::enable() 374 | { 375 | disableAllEvents(); 376 | enableMouseEvents(); 377 | } 378 | 379 | #pragma mark - 380 | #pragma mark Interactive Obj Callback methods 381 | //-------------------------------------------------------------- 382 | void ofxMtlMapping2DPolygon::onRollOver(int x, int y) 383 | { 384 | } 385 | 386 | //-------------------------------------------------------------- 387 | void ofxMtlMapping2DPolygon::onRollOut() 388 | { 389 | } 390 | 391 | //-------------------------------------------------------------- 392 | void ofxMtlMapping2DPolygon::onMouseMove(int x, int y) 393 | { 394 | } 395 | 396 | //-------------------------------------------------------------- 397 | void ofxMtlMapping2DPolygon::onDragOver(int x, int y, int button) 398 | { 399 | if(ofxMtlMapping2DVertex::activeVertex) 400 | return; 401 | 402 | if(activePolygon == this) { 403 | updatePosition(x - _grabAnchor.x, y - _grabAnchor.y); 404 | _grabAnchor.set(x, y); 405 | } 406 | } 407 | 408 | //-------------------------------------------------------------- 409 | void ofxMtlMapping2DPolygon::onDragOutside(int x, int y, int button) 410 | { 411 | if(ofxMtlMapping2DVertex::activeVertex) 412 | return; 413 | 414 | if(activePolygon == this) { 415 | updatePosition(x - _grabAnchor.x, y - _grabAnchor.y); 416 | _grabAnchor.set(x, y); 417 | } 418 | } 419 | 420 | //-------------------------------------------------------------- 421 | void ofxMtlMapping2DPolygon::onRelease(int x, int y, int button) 422 | { 423 | 424 | } 425 | 426 | //-------------------------------------------------------------- 427 | void ofxMtlMapping2DPolygon::onReleaseOutside(int x, int y, int button) 428 | { 429 | } 430 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DPolygon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //OF 4 | #include "ofMain.h" 5 | 6 | #include "ofxMtlMapping2DShapeType.h" 7 | #include "ofxMtlMapping2DSettings.h" 8 | #include "mtlUtils.h" 9 | #include "ofxMtlMapping2DVertex.h" 10 | 11 | //MSA Libs 12 | #include "ofxMSAInteractiveObject.h" 13 | 14 | //-------------------------------------------------------------- 15 | //-------------------------------------------------------------- 16 | class ofxMtlMapping2DPolygon : public ofxMSAInteractiveObject { 17 | 18 | public: 19 | 20 | // ---- 21 | static ofxMtlMapping2DPolygon* activePolygon; 22 | static ofxMtlMapping2DPolygon* previousActivePolygon; 23 | static int activeVertexId; 24 | static void resetActivePolygonVars(); 25 | 26 | // ---- 27 | ofxMtlMapping2DPolygon(); 28 | ~ofxMtlMapping2DPolygon(); 29 | 30 | int shapeId; 31 | int shapeType; 32 | list vertices; 33 | ofPolyline *polyline; 34 | ofRectangle boundingBox; 35 | 36 | void init(int sId, bool defaultShape = false); 37 | 38 | void update(); 39 | void draw(); 40 | void addPoint(int x, int y); 41 | void drawID(); 42 | virtual void render() {}; 43 | void setAsActive(); 44 | void setAsIdle(); 45 | 46 | void select(int x, int y); 47 | 48 | 49 | ofxMtlMapping2DVertex* getVertex(int index); 50 | 51 | // ---- ofxMSAInteractiveObject related 52 | void enable(); 53 | void disable(); 54 | 55 | virtual bool hitTest(int tx, int ty); 56 | 57 | virtual void onRollOver(int x, int y); 58 | virtual void onRollOut(); 59 | virtual void onMouseMove(int x, int y); 60 | virtual void onDragOver(int x, int y, int button); 61 | virtual void onDragOutside(int x, int y, int button); 62 | virtual void onRelease(int x, int y, int button); 63 | virtual void onReleaseOutside(int x, int y, int button); 64 | 65 | protected: 66 | ofPoint _centroid2D; 67 | ofPoint _grabAnchor; 68 | 69 | void disableVertices(); 70 | void enableVertices(); 71 | 72 | void updatePosition(int xInc, int yInc); 73 | void updatePolyline(); 74 | 75 | virtual void createDefaultShape() {}; 76 | }; 77 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DQuad.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DQuad.h" 2 | 3 | //-------------------------------------------------------------- 4 | //-------------------------------------------------------------- 5 | ofxMtlMapping2DQuad::ofxMtlMapping2DQuad() 6 | { 7 | 8 | } 9 | 10 | //-------------------------------------------------------------- 11 | ofxMtlMapping2DQuad::~ofxMtlMapping2DQuad(){ 12 | 13 | } 14 | 15 | //-------------------------------------------------------------- 16 | void ofxMtlMapping2DQuad::render() 17 | { 18 | glPushMatrix(); 19 | glMultMatrixf(inputPolygon->homoMatrix); 20 | glBegin(GL_POLYGON); 21 | 22 | // int i = 0; 23 | // list::iterator it; 24 | // for (it=inputPolygon->vertices.begin(); it!=inputPolygon->vertices.end(); it++) { 25 | // ofxMtlMapping2DVertex* vertex = *it; 26 | // glTexCoord2f(vertex->center.x, vertex->center.y); 27 | // glVertex2f(inputPolygon->polyline->getVertices()[i].x - inputPolygon->boundingBox.x, inputPolygon->polyline->getVertices()[i].y - inputPolygon->boundingBox.y); 28 | // i++; 29 | // } 30 | 31 | for (int i = 0; i < inputPolygon->polyline->size(); i++) { 32 | glTexCoord2f(inputPolygon->polyline->getVertices()[i].x, inputPolygon->polyline->getVertices()[i].y); 33 | //glVertex2f(inputPolygon->polyline->getVertices()[i].x, inputPolygon->polyline->getVertices()[i].y); 34 | glVertex2f(inputPolygon->polyline->getVertices()[i].x - inputPolygon->boundingBox.x, inputPolygon->polyline->getVertices()[i].y - inputPolygon->boundingBox.y); 35 | } 36 | 37 | 38 | glEnd(); 39 | glPopMatrix(); 40 | } 41 | 42 | 43 | //-------------------------------------------------------------- 44 | void ofxMtlMapping2DQuad::createDefaultShape() 45 | { 46 | shapeSettings["type"] = "quad"; 47 | 48 | inputPolygon = new ofxMtlMapping2DInput(); 49 | 50 | 51 | int xOffset = ofGetWidth()/2.0; 52 | int yOffset = ofGetHeight()/2.0; 53 | 54 | //Create a new vertex 55 | int x = 0; 56 | int y = 0; 57 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 58 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 59 | vertices.push_back(newVertex); 60 | 61 | // Input 62 | newVertex = new ofxMtlMapping2DVertex(); 63 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 64 | newVertex->isDefiningTectureCoord = true; 65 | inputPolygon->vertices.push_back(newVertex); 66 | 67 | x = 100; 68 | y = 0; 69 | newVertex = new ofxMtlMapping2DVertex(); 70 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 71 | vertices.push_back(newVertex); 72 | 73 | // Input 74 | newVertex = new ofxMtlMapping2DVertex(); 75 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 76 | newVertex->isDefiningTectureCoord = true; 77 | inputPolygon->vertices.push_back(newVertex); 78 | 79 | x = 100; 80 | y = 100; 81 | newVertex = new ofxMtlMapping2DVertex(); 82 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 83 | vertices.push_back(newVertex); 84 | 85 | // Input 86 | newVertex = new ofxMtlMapping2DVertex(); 87 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 88 | newVertex->isDefiningTectureCoord = true; 89 | inputPolygon->vertices.push_back(newVertex); 90 | 91 | x = 0; 92 | y = 100; 93 | newVertex = new ofxMtlMapping2DVertex(); 94 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 95 | vertices.push_back(newVertex); 96 | 97 | // Input 98 | newVertex = new ofxMtlMapping2DVertex(); 99 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 100 | newVertex->isDefiningTectureCoord = true; 101 | inputPolygon->vertices.push_back(newVertex); 102 | 103 | // ---- 104 | inputPolygon->init(shapeId); 105 | } 106 | 107 | //-------------------------------------------------------------- 108 | void ofxMtlMapping2DQuad::calcHomography() 109 | { 110 | updatePolyline(); 111 | 112 | inputPolygon->calcHomography(polyline->getVertices()[0].x, polyline->getVertices()[0].y, 113 | polyline->getVertices()[1].x, polyline->getVertices()[1].y, 114 | polyline->getVertices()[2].x, polyline->getVertices()[2].y, 115 | polyline->getVertices()[3].x, polyline->getVertices()[3].y); 116 | } -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DQuad.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMtlMapping2DShape.h" 4 | 5 | 6 | //-------------------------------------------------------------- 7 | //-------------------------------------------------------------- 8 | class ofxMtlMapping2DQuad : public ofxMtlMapping2DShape { 9 | 10 | public: 11 | 12 | ofxMtlMapping2DQuad(); 13 | ~ofxMtlMapping2DQuad(); 14 | 15 | protected: 16 | virtual void createDefaultShape(); 17 | virtual void render(); 18 | virtual void calcHomography(); 19 | }; 20 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DShape.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DShape.h" 2 | #include "ofxMtlMapping2DControls.h" 3 | #include "ofxMtlMapping2DGrid.h" 4 | 5 | int ofxMtlMapping2DShape::nextShapeId = 0; 6 | ofxMtlMapping2DShape* ofxMtlMapping2DShape::activeShape = NULL; 7 | ofxMtlMapping2DShape* ofxMtlMapping2DShape::previousActiveShape = NULL; 8 | 9 | //-------------------------------------------------------------- 10 | //-------------------------------------------------------------- 11 | void ofxMtlMapping2DShape::resetActiveShapeVars(){ 12 | ofxMtlMapping2DShape::activeShape = NULL; 13 | ofxMtlMapping2DShape::previousActiveShape = NULL; 14 | } 15 | 16 | 17 | 18 | //-------------------------------------------------------------- 19 | //-------------------------------------------------------------- 20 | ofxMtlMapping2DShape::ofxMtlMapping2DShape() 21 | { 22 | inputPolygon = NULL; 23 | } 24 | 25 | //-------------------------------------------------------------- 26 | ofxMtlMapping2DShape::~ofxMtlMapping2DShape() 27 | { 28 | // ---- 29 | delete inputPolygon; 30 | } 31 | 32 | 33 | #pragma mark - 34 | #pragma mark Lifecycle 35 | //-------------------------------------------------------------- 36 | void ofxMtlMapping2DShape::init(int sId, bool defaultShape) 37 | { 38 | if (!defaultShape) { 39 | initShape(); 40 | } 41 | 42 | _super::init(sId, defaultShape); 43 | 44 | calcHomography(); 45 | } 46 | 47 | //-------------------------------------------------------------- 48 | void ofxMtlMapping2DShape::update() 49 | { 50 | _super::update(); 51 | 52 | 53 | if(activePolygon != this && activePolygon != inputPolygon) 54 | return; 55 | 56 | if(activePolygon == this || (activePolygon == inputPolygon && inputPolygon) || (activePolygon == this && !inputPolygon && shapeType == MAPPING_2D_SHAPE_MASK)) { 57 | setAsActiveShape(); 58 | 59 | // ---- recalculate the homography transformation matrix (for textured Shapes - for now only Quads) . 60 | calcHomography(); 61 | } 62 | 63 | if (activeShape == this) { 64 | if (ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_INPUT) { 65 | if (shapeType == MAPPING_2D_SHAPE_QUAD || shapeType == MAPPING_2D_SHAPE_GRID) { 66 | inputPolygon->update(true); 67 | } else { 68 | inputPolygon->update(false); 69 | } 70 | } 71 | } 72 | } 73 | 74 | 75 | //-------------------------------------------------------------- 76 | void ofxMtlMapping2DShape::draw() 77 | { 78 | //-------- 79 | ofEnableAlphaBlending(); 80 | 81 | // ---- OUTPUT MODE 82 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 83 | _super::draw(); 84 | 85 | // ---- INPUT MODE 86 | } else if (ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_INPUT) { 87 | if (inputPolygon && shapeType != MAPPING_2D_SHAPE_MASK) { 88 | inputPolygon->draw(); 89 | } 90 | } 91 | 92 | if(ofxMtlMapping2DControls::mapping2DControls()->showShapesId()) { 93 | drawID(); 94 | } 95 | 96 | ofDisableAlphaBlending(); 97 | } 98 | 99 | 100 | //-------------------------------------------------------------- 101 | void ofxMtlMapping2DShape::drawID() 102 | { 103 | // ---- OUTPUT MODE 104 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 105 | _super::drawID(); 106 | 107 | // ---- INPUT MODE 108 | } else if (ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_INPUT) { 109 | if (inputPolygon && shapeType != MAPPING_2D_SHAPE_MASK) { 110 | inputPolygon->drawID(); 111 | } 112 | } 113 | } 114 | 115 | //-------------------------------------------------------------- 116 | void ofxMtlMapping2DShape::setAsActiveShape(bool fromUI) 117 | { 118 | // ---- OUTPUT MODE 119 | if(ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_OUTPUT) { 120 | if (activeShape != this) { 121 | // ---- 122 | if (shapeType == MAPPING_2D_SHAPE_MASK) { 123 | ofxMtlMapping2DControls::mapping2DControls()->hideInputModeToggle(); 124 | } else { 125 | ofxMtlMapping2DControls::mapping2DControls()->showInputModeToggle(); 126 | } 127 | 128 | // ---- 129 | previousActiveShape = activeShape; 130 | activeShape = this; 131 | 132 | // Update UI 133 | if (fromUI) { 134 | setAsActive(); 135 | } else { 136 | ofxMtlMapping2DControls::mapping2DControls()->setAsActiveShapeWithId(shapeId, shapeType); 137 | } 138 | 139 | // Is a grid 140 | if (activeShape->shapeType == MAPPING_2D_SHAPE_GRID) { 141 | ofxMtlMapping2DControls::mapping2DControls()->showGridSettingsCanvas(); 142 | } else { 143 | ofxMtlMapping2DControls::mapping2DControls()->hideGridSettingsCanvas(); 144 | } 145 | } 146 | 147 | // ---- INPUT MODE 148 | } else if (ofxMtlMapping2DControls::mapping2DControls()->mappingMode() == MAPPING_MODE_INPUT) { 149 | if (activeShape != this) { 150 | previousActiveShape = activeShape; 151 | activeShape = this; 152 | 153 | // Update UI 154 | if (fromUI) { 155 | inputPolygon->setAsActive(); 156 | } else { 157 | ofxMtlMapping2DControls::mapping2DControls()->setAsActiveShapeWithId(shapeId, shapeType); 158 | } 159 | } 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DShape.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //OF 4 | #include "ofMain.h" 5 | 6 | #include "ofxMtlMapping2DPolygon.h" 7 | #include "ofxMtlMapping2DSettings.h" 8 | #include "mtlUtils.h" 9 | #include "ofxMtlMapping2DInput.h" 10 | #include "ofxMtlMapping2DVertex.h" 11 | 12 | //-------------------------------------------------------------- 13 | //-------------------------------------------------------------- 14 | class ofxMtlMapping2DShape : public ofxMtlMapping2DPolygon { 15 | 16 | public: 17 | // ---- 18 | static int nextShapeId; 19 | static ofxMtlMapping2DShape* activeShape; 20 | static ofxMtlMapping2DShape* previousActiveShape; 21 | static void resetActiveShapeVars(); 22 | 23 | // ---- 24 | ofxMtlMapping2DShape(); 25 | ~ofxMtlMapping2DShape(); 26 | 27 | map shapeSettings; 28 | ofxMtlMapping2DInput* inputPolygon; 29 | 30 | void init(int sId, bool defaultShape = false); 31 | 32 | void update(); 33 | void draw(); 34 | void drawID(); 35 | virtual void render() {}; 36 | 37 | void setAsActiveShape(bool fromUI = false); 38 | 39 | protected: 40 | virtual void calcHomography() {}; 41 | virtual void createDefaultShape() {}; 42 | virtual void initShape() {}; 43 | 44 | private: 45 | typedef ofxMtlMapping2DPolygon _super; 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DTriangle.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DTriangle.h" 2 | 3 | //-------------------------------------------------------------- 4 | //-------------------------------------------------------------- 5 | ofxMtlMapping2DTriangle::ofxMtlMapping2DTriangle() 6 | { 7 | 8 | } 9 | 10 | //-------------------------------------------------------------- 11 | ofxMtlMapping2DTriangle::~ofxMtlMapping2DTriangle(){ 12 | 13 | } 14 | 15 | //-------------------------------------------------------------- 16 | void ofxMtlMapping2DTriangle::render() 17 | { 18 | glPushMatrix(); 19 | glBegin(GL_POLYGON); 20 | 21 | for (int i = 0; i < inputPolygon->polyline->size(); i++) { 22 | glTexCoord2f(inputPolygon->polyline->getVertices()[i].x, inputPolygon->polyline->getVertices()[i].y); 23 | glVertex2f(polyline->getVertices()[i].x, polyline->getVertices()[i].y); 24 | } 25 | 26 | glEnd(); 27 | glPopMatrix(); 28 | } 29 | 30 | //-------------------------------------------------------------- 31 | void ofxMtlMapping2DTriangle::createDefaultShape() 32 | { 33 | shapeSettings["type"] = "triangle"; 34 | inputPolygon = new ofxMtlMapping2DInput(); 35 | 36 | int xOffset = ofGetWidth()/2.0; 37 | int yOffset = ofGetHeight()/2.0; 38 | 39 | int x = 50; 40 | int y = 0; 41 | 42 | ofxMtlMapping2DVertex* newVertex = new ofxMtlMapping2DVertex(); 43 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 44 | vertices.push_back(newVertex); 45 | 46 | // Input 47 | newVertex = new ofxMtlMapping2DVertex(); 48 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 49 | newVertex->isDefiningTectureCoord = true; 50 | inputPolygon->vertices.push_back(newVertex); 51 | 52 | x = 0; 53 | y = 100; 54 | 55 | //Create a new vertex 56 | newVertex = new ofxMtlMapping2DVertex(); 57 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 58 | vertices.push_back(newVertex); 59 | 60 | // Input 61 | newVertex = new ofxMtlMapping2DVertex(); 62 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 63 | newVertex->isDefiningTectureCoord = true; 64 | inputPolygon->vertices.push_back(newVertex); 65 | 66 | x = 100; 67 | y = 100; 68 | 69 | //Create a new vertex 70 | newVertex = new ofxMtlMapping2DVertex(); 71 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 72 | vertices.push_back(newVertex); 73 | 74 | // Input 75 | newVertex = new ofxMtlMapping2DVertex(); 76 | newVertex->init(xOffset + x - newVertex->width/2, yOffset + y - newVertex->height/2); 77 | newVertex->isDefiningTectureCoord = true; 78 | inputPolygon->vertices.push_back(newVertex); 79 | 80 | inputPolygon->init(shapeId); 81 | } -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DTriangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "ofxMtlMapping2DShape.h" 4 | 5 | //-------------------------------------------------------------- 6 | //-------------------------------------------------------------- 7 | class ofxMtlMapping2DTriangle : public ofxMtlMapping2DShape { 8 | 9 | public: 10 | 11 | ofxMtlMapping2DTriangle(); 12 | ~ofxMtlMapping2DTriangle(); 13 | 14 | protected: 15 | virtual void createDefaultShape(); 16 | virtual void render(); 17 | 18 | }; 19 | -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DVertex.cpp: -------------------------------------------------------------------------------- 1 | #include "ofxMtlMapping2DVertex.h" 2 | #include "ofxMtlMapping2DSettings.h" 3 | 4 | ofxMtlMapping2DVertex* ofxMtlMapping2DVertex::activeVertex = NULL; 5 | 6 | //-------------------------------------------------------------- 7 | ofxMtlMapping2DVertex::ofxMtlMapping2DVertex() 8 | { 9 | disableAllEvents(); 10 | enableMouseEvents(); 11 | enabled = false; 12 | bIsOnAnEdge = true; 13 | edgeIndex = -1; 14 | 15 | //Vertex 16 | setSize(30, 30); 17 | toBeRemoved = false; 18 | isDefiningTectureCoord = false; 19 | updateCenter(); 20 | } 21 | 22 | //-------------------------------------------------------------- 23 | ofxMtlMapping2DVertex::~ofxMtlMapping2DVertex() 24 | { 25 | } 26 | 27 | //-------------------------------------------------------------- 28 | void ofxMtlMapping2DVertex::init(float _x, float _y, int _index) 29 | { 30 | index = _index; 31 | setPosition(_x, _y); 32 | 33 | //Center 34 | updateCenter(); 35 | } 36 | 37 | //-------------------------------------------------------------- 38 | void ofxMtlMapping2DVertex::kill() 39 | { 40 | if(activeVertex == this) { 41 | activeVertex = NULL; 42 | } 43 | 44 | delete this; 45 | } 46 | 47 | //-------------------------------------------------------------- 48 | void ofxMtlMapping2DVertex::update() 49 | { 50 | 51 | } 52 | 53 | //-------------------------------------------------------------- 54 | void ofxMtlMapping2DVertex::drawBack() 55 | { 56 | ofFill(); 57 | if(activeVertex == this) { 58 | ofSetColor(255, 255, 255, 150); 59 | ofCircle(x+15, y+15, 20); 60 | } else if(isMouseOver()) { 61 | ofSetColor(255, 255, 255, 125); 62 | ofCircle(x+15, y+15, 20); 63 | } else { 64 | //ofSetColor(255, 255, 255, 80); 65 | } 66 | } 67 | 68 | //-------------------------------------------------------------- 69 | void ofxMtlMapping2DVertex::drawTop() 70 | { 71 | ofNoFill(); 72 | if(activeVertex == this) { 73 | ofSetColor(255, 255, 0, 150); 74 | } else if(isMouseOver()) { 75 | ofSetColor(255, 0, 0, 120); 76 | } else { 77 | ofSetColor(255, 255, 255, 80); 78 | } 79 | 80 | //ofCircle(x+11, y+11, 8); 81 | ofRect(x+11, y+11, 8, 8); 82 | } 83 | 84 | //-------------------------------------------------------------- 85 | ofxMtlMapping2DVertex* ofxMtlMapping2DVertex::getActiveVertex() 86 | { 87 | return activeVertex; 88 | } 89 | 90 | //-------------------------------------------------------------- 91 | void ofxMtlMapping2DVertex::updateCenter() 92 | { 93 | center.set(x+15, y+15); 94 | } 95 | 96 | //-------------------------------------------------------------- 97 | void ofxMtlMapping2DVertex::snapIt(float _x, float _y) 98 | { 99 | setPosition(_x, _y); 100 | updateCenter(); 101 | } 102 | 103 | 104 | #pragma mark - 105 | #pragma mark up with keyboard 106 | //-------------------------------------------------------------- 107 | void ofxMtlMapping2DVertex::left() 108 | { 109 | if(activeVertex) 110 | snapIt(x-1, y); 111 | } 112 | 113 | //-------------------------------------------------------------- 114 | void ofxMtlMapping2DVertex::up() 115 | { 116 | if(activeVertex) 117 | snapIt(x, y-1); 118 | } 119 | 120 | //-------------------------------------------------------------- 121 | void ofxMtlMapping2DVertex::right() 122 | { 123 | if(activeVertex) 124 | snapIt(x+1, y); 125 | } 126 | 127 | //-------------------------------------------------------------- 128 | void ofxMtlMapping2DVertex::down() 129 | { 130 | if(activeVertex) 131 | snapIt(x, y+1); 132 | } 133 | 134 | 135 | #pragma mark - 136 | #pragma mark Interactive Obj Callback methods 137 | //-------------------------------------------------------------- 138 | void ofxMtlMapping2DVertex::onRollOver(int x, int y) 139 | { 140 | } 141 | 142 | //-------------------------------------------------------------- 143 | void ofxMtlMapping2DVertex::onRollOut() 144 | { 145 | } 146 | 147 | //-------------------------------------------------------------- 148 | void ofxMtlMapping2DVertex::onMouseMove(int x, int y) 149 | { 150 | } 151 | 152 | //-------------------------------------------------------------- 153 | void ofxMtlMapping2DVertex::onDragOver(int x, int y, int button) 154 | { 155 | if(activeVertex == this) { 156 | this->x = x - width/2; 157 | this->y = y - height/2; 158 | updateCenter(); 159 | } 160 | } 161 | 162 | //-------------------------------------------------------------- 163 | void ofxMtlMapping2DVertex::onDragOutside(int x, int y, int button) 164 | { 165 | if(activeVertex == this) { 166 | this->x = x - width/2; 167 | this->y = y - height/2; 168 | updateCenter(); 169 | } 170 | } 171 | 172 | //-------------------------------------------------------------- 173 | void ofxMtlMapping2DVertex::onPress(int x, int y, int button) 174 | { 175 | if (button == 0) { 176 | activeVertex = this; 177 | } else if (button == 2 && !isDefiningTectureCoord && ofxMtlMapping2DSettings::kIsManuallyAddingDeletingVertexEnabled) { 178 | toBeRemoved = true; 179 | activeVertex = NULL; 180 | } 181 | } 182 | 183 | //-------------------------------------------------------------- 184 | void ofxMtlMapping2DVertex::onPressOutside(int x, int y, int button) 185 | { 186 | if(activeVertex == this) { 187 | activeVertex = NULL; 188 | } 189 | } 190 | 191 | //-------------------------------------------------------------- 192 | void ofxMtlMapping2DVertex::setAsActive() 193 | { 194 | activeVertex = this; 195 | } 196 | 197 | //-------------------------------------------------------------- 198 | void ofxMtlMapping2DVertex::onRelease(int x, int y, int button) 199 | { 200 | } 201 | 202 | //-------------------------------------------------------------- 203 | void ofxMtlMapping2DVertex::onReleaseOutside(int x, int y, int button) 204 | { 205 | if(activeVertex == this) { 206 | activeVertex = NULL; 207 | } 208 | } -------------------------------------------------------------------------------- /src/shapes/ofxMtlMapping2DVertex.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //OF 4 | #include "ofMain.h" 5 | #include "ofVec2f.h" 6 | 7 | //MSA Libs 8 | #include "ofxMSAInteractiveObject.h" 9 | 10 | //-------------------------------------------------------------- 11 | //-------------------------------------------------------------- 12 | class ofxMtlMapping2DVertex : public ofxMSAInteractiveObject { 13 | 14 | public: 15 | 16 | static ofxMtlMapping2DVertex* activeVertex; 17 | 18 | ofxMtlMapping2DVertex(); 19 | ~ofxMtlMapping2DVertex(); 20 | 21 | void kill(); 22 | void update(); 23 | void updateCenter(); 24 | void drawBack(); 25 | void drawTop(); 26 | 27 | void snapIt(float _x, float _y); 28 | 29 | void init(float _x, float _y, int _index = -1); 30 | 31 | static ofxMtlMapping2DVertex* getActiveVertex(); 32 | 33 | virtual void onRollOver(int x, int y); 34 | virtual void onRollOut(); 35 | virtual void onMouseMove(int x, int y); 36 | virtual void onDragOver(int x, int y, int button); 37 | virtual void onDragOutside(int x, int y, int button); 38 | virtual void onPress(int x, int y, int button); 39 | virtual void onPressOutside(int x, int y, int button); 40 | virtual void onRelease(int x, int y, int button); 41 | virtual void onReleaseOutside(int x, int y, int button); 42 | 43 | bool toBeRemoved; 44 | bool isDefiningTectureCoord; 45 | ofVec2f center; 46 | int index; 47 | bool bIsOnAnEdge; 48 | int edgeIndex; 49 | 50 | void setAsActive(); 51 | 52 | void left(); 53 | void up(); 54 | void right(); 55 | void down(); 56 | 57 | }; 58 | -------------------------------------------------------------------------------- /src/utils/homography/homography.h: -------------------------------------------------------------------------------- 1 | /* 2 | * homography.h 3 | * 4 | * Created on: 08/01/2010 5 | * Author: arturo castro 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "ofPoint.h" 11 | #include "ofMatrix4x4.h" 12 | 13 | void gaussian_elimination(float *input, int n){ 14 | // ported to c from pseudocode in 15 | // http://en.wikipedia.org/wiki/Gaussian_elimination 16 | 17 | float * A = input; 18 | int i = 0; 19 | int j = 0; 20 | int m = n-1; 21 | while (i < m && j < n){ 22 | // Find pivot in column j, starting in row i: 23 | int maxi = i; 24 | for(int k = i+1; k fabs(A[maxi*n+j])){ 26 | maxi = k; 27 | } 28 | } 29 | if (A[maxi*n+j] != 0){ 30 | //swap rows i and maxi, but do not change the value of i 31 | if(i!=maxi) 32 | for(int k=0;k=0;i--){ 60 | for(int j=i+1;j 1) { 29 | closestPoint = p2; 30 | } else { 31 | closestPoint.set(p1.x + u * xDelta, p1.y + u * yDelta); 32 | } 33 | 34 | return closestPoint.distance(p3); 35 | } 36 | 37 | --------------------------------------------------------------------------------