diff --git a/example/src/ofApp.cpp b/example/src/ofApp.cpp index 2cab8a6..260ebfe 100755 --- a/example/src/ofApp.cpp +++ b/example/src/ofApp.cpp @@ -1,164 +1,183 @@ #include "ofApp.h" -void ofApp::setup() -{ - bShowInfo = false; - - // check if the surfaces.xml file is there - // if not - load defaultSurfaces.xml - if ( ofFile::doesFileExist("surfaces.xml") ) { - surfaceManager.loadXmlSettings("surfaces.xml"); - } else { - surfaceManager.loadXmlSettings("defaultSurfaces.xml"); - } - - // Pass the surface manager to the mapper graphical user interface - gui.setSurfaceManager( &surfaceManager ); - - // Create FBO - fbo = new ofFbo(); - fbo->allocate( 500, 500 ); - setFboAsTexture(); - - // Genereate rects - int numRects = 20; // change this to add more or less rects - for ( int i=0; igetHeight()), fbo->getWidth(), ofRandom(20)) ); - rectSpeeds.push_back( (1.0f + ofRandom(5)) ); - } +void ofApp::setup() { + bShowInfo = false; + + // check if the surfaces.xml file is there + // if not - load defaultSurfaces.xml + if (ofFile::doesFileExist("surfaces.xml")) { + surfaceManager.loadXmlSettings("surfaces.xml"); + } else { + surfaceManager.loadXmlSettings("defaultSurfaces.xml"); + } + + // Pass the surface manager to the mapper graphical user interface + gui.setSurfaceManager(&surfaceManager); + + // Create FBO + fbo = new ofFbo(); + fbo->allocate(500, 500); + setFboAsTexture(); + + // Genereate rects + int numRects = 20; // change this to add more or less rects + for (int i = 0; i < numRects; i++) { + rects.push_back(ofRectangle(0, ofRandom(fbo->getHeight()), fbo->getWidth(), + ofRandom(20))); + rectSpeeds.push_back((1.0f + ofRandom(5))); + } } -void ofApp::update() -{ - // Move rects - for ( int i=0; i fbo->getHeight() ) { - rects[i].y = -rects[i].getHeight(); - } - } - - // Fill FBO - fbo->begin(); - ofClear(0); - ofBackground(0); - ofSetColor(255); - for ( int i=0; i fbo->getHeight()) { + rects[i].y = -rects[i].getHeight(); } - fbo->end(); + } + + // Fill FBO + fbo->begin(); + ofClear(0); + ofBackground(0); + ofSetColor(255); + for (int i = 0; i < rects.size(); i++) { + ofRect(rects[i]); + } + fbo->end(); } -void ofApp::draw() -{ - // Draw the piMapper GUI - gui.draw(); - - if ( bShowInfo ) { - // Draw instructions - stringstream ss; - ss << "There are 4 modes:\n\n"; - ss << " 1. Presentation mode\n"; - ss << " 2. Texture mapping mode\n"; - ss << " 3. Projection mapping mode\n"; - ss << " 4. Source selection mode\n\n"; - ss << "You can switch between the modes by using <1>, <2>, <3> and <4> keys on the keyboard.\n\n"; - ss << "Press or to add random or normal surface.\n"; - ss << "Press to add a new quad surface.\n"; - ss << "Press to save the composition.\n"; - ss << "Press to toggle fullscreen.\n"; - ss << "Press to reassign the fbo texture to the first surface\n"; - ss << "Hit to hide this message."; - - ofDrawBitmapStringHighlight(ss.str(), 10, 20, ofColor(0,0,0,100), ofColor(255,255,255,200)); - } +void ofApp::draw() { + // Draw the piMapper GUI + gui.draw(); + + if (bShowInfo) { + // Draw instructions + stringstream ss; + ss << "There are 4 modes:\n\n"; + ss << " 1. Presentation mode\n"; + ss << " 2. Texture mapping mode\n"; + ss << " 3. Projection mapping mode\n"; + ss << " 4. Source selection mode\n\n"; + ss << "You can switch between the modes by using <1>, <2>, <3> and <4> " + "keys on the keyboard.\n\n"; + ss << "Press or to add random or normal surface.\n"; + ss << "Press to add a new quad surface.\n"; + ss << "Press to save the composition.\n"; + ss << "Press to toggle fullscreen.\n"; + ss << "Press to reassign the fbo texture to the first surface\n"; + ss << "Hit to hide this message."; + + ofDrawBitmapStringHighlight(ss.str(), 10, 20, ofColor(0, 0, 0, 100), + ofColor(255, 255, 255, 200)); + } } -void ofApp::exit() -{ - // Clear FBO from mem - delete fbo; +void ofApp::exit() { + // Clear FBO from mem + delete fbo; } -void ofApp::keyPressed(int key) -{ - cout << "Key pressed: " << static_cast(key) << endl; - - switch (key) { - case '1': gui.setMode(ofxGuiMode::NONE); break; - case '2': gui.setMode(ofxGuiMode::TEXTURE_MAPPING); break; - case '3': gui.setMode(ofxGuiMode::PROJECTION_MAPPING); break; - case '4': gui.setMode(ofxGuiMode::SOURCE_SELECTION); break; - case 'i': bShowInfo = !bShowInfo; break; - case 'r': addRandomSurface(); break; - case 'q': addQuadSurface(); break; - case 'n': addSurface(); break; - case 'f': ofToggleFullscreen(); break; - case 's': surfaceManager.saveXmlSettings("surfaces.xml"); break; - case 'a': setFboAsTexture(); break; - case OF_KEY_BACKSPACE: surfaceManager.removeSelectedSurface(); break; - default: break; - } +void ofApp::keyPressed(int key) { + cout << "Key pressed: " << static_cast(key) << endl; + + switch (key) { + case '1': + gui.setMode(ofx::piMapper::GuiMode::NONE); + break; + case '2': + gui.setMode(ofx::piMapper::GuiMode::TEXTURE_MAPPING); + break; + case '3': + gui.setMode(ofx::piMapper::GuiMode::PROJECTION_MAPPING); + break; + case '4': + gui.setMode(ofx::piMapper::GuiMode::SOURCE_SELECTION); + break; + case 'i': + bShowInfo = !bShowInfo; + break; + case 'r': + addRandomSurface(); + break; + case 'q': + addQuadSurface(); + break; + case 'n': + addSurface(); + break; + case 'f': + ofToggleFullscreen(); + break; + case 's': + surfaceManager.saveXmlSettings("surfaces.xml"); + break; + case 'a': + setFboAsTexture(); + break; + case OF_KEY_BACKSPACE: + surfaceManager.removeSelectedSurface(); + break; + default: + break; + } } -void ofApp::addRandomSurface() -{ - int surfaceType = ofxSurfaceType::TRIANGLE_SURFACE; - vector vertices; - vertices.push_back( ofVec2f( ofRandomWidth(), ofRandomHeight() ) ); - vertices.push_back( ofVec2f( ofRandomWidth(), ofRandomHeight() ) ); - vertices.push_back( ofVec2f( ofRandomWidth(), ofRandomHeight() ) ); - vector texCoords; - texCoords.push_back( ofVec2f( ofRandomuf(), ofRandomuf() ) ); - texCoords.push_back( ofVec2f( ofRandomuf(), ofRandomuf() ) ); - texCoords.push_back( ofVec2f( ofRandomuf(), ofRandomuf() ) ); - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // select this surface right away - surfaceManager.selectSurface(surfaceManager.size()-1); +void ofApp::addRandomSurface() { + int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; + vector vertices; + vertices.push_back(ofVec2f(ofRandomWidth(), ofRandomHeight())); + vertices.push_back(ofVec2f(ofRandomWidth(), ofRandomHeight())); + vertices.push_back(ofVec2f(ofRandomWidth(), ofRandomHeight())); + vector texCoords; + texCoords.push_back(ofVec2f(ofRandomuf(), ofRandomuf())); + texCoords.push_back(ofVec2f(ofRandomuf(), ofRandomuf())); + texCoords.push_back(ofVec2f(ofRandomuf(), ofRandomuf())); + surfaceManager.addSurface(surfaceType, vertices, texCoords); + + // select this surface right away + surfaceManager.selectSurface(surfaceManager.size() - 1); } -void ofApp::addQuadSurface() -{ - int surfaceType = ofxSurfaceType::QUAD_SURFACE; - vector vertices; - - int border = 50; - vertices.push_back(ofVec2f(border, border)); - vertices.push_back(ofVec2f(ofGetWidth() - border, border)); - vertices.push_back(ofVec2f(ofGetWidth() - border, ofGetHeight() - border)); - vertices.push_back(ofVec2f(border, ofGetHeight() - border)); - - vector texCoords; - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); - - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // select this surface right away - surfaceManager.selectSurface(surfaceManager.size()-1); +void ofApp::addQuadSurface() { + int surfaceType = ofx::piMapper::SurfaceType::QUAD_SURFACE; + vector vertices; + + int border = 50; + vertices.push_back(ofVec2f(border, border)); + vertices.push_back(ofVec2f(ofGetWidth() - border, border)); + vertices.push_back(ofVec2f(ofGetWidth() - border, ofGetHeight() - border)); + vertices.push_back(ofVec2f(border, ofGetHeight() - border)); + + vector texCoords; + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); + + surfaceManager.addSurface(surfaceType, vertices, texCoords); + + // select this surface right away + surfaceManager.selectSurface(surfaceManager.size() - 1); } -void ofApp::addSurface() -{ - int surfaceType = ofxSurfaceType::TRIANGLE_SURFACE; - vector vertices; - vertices.push_back( ofVec2f( (float)ofGetWidth()/2.0f, 0.0f ) ); - vertices.push_back( ofVec2f( (float)ofGetWidth(), (float)ofGetHeight() ) ); - vertices.push_back( ofVec2f( 0.0f, (float)ofGetHeight() ) ); - vector texCoords; - texCoords.push_back( ofVec2f( 0.5f, 0.0f ) ); - texCoords.push_back( ofVec2f( 1.0f, 1.0f ) ); - texCoords.push_back( ofVec2f( 0.0f, 1.0f ) ); - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // select this surface right away - surfaceManager.selectSurface(surfaceManager.size()-1); +void ofApp::addSurface() { + int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; + vector vertices; + vertices.push_back(ofVec2f((float)ofGetWidth() / 2.0f, 0.0f)); + vertices.push_back(ofVec2f((float)ofGetWidth(), (float)ofGetHeight())); + vertices.push_back(ofVec2f(0.0f, (float)ofGetHeight())); + vector texCoords; + texCoords.push_back(ofVec2f(0.5f, 0.0f)); + texCoords.push_back(ofVec2f(1.0f, 1.0f)); + texCoords.push_back(ofVec2f(0.0f, 1.0f)); + surfaceManager.addSurface(surfaceType, vertices, texCoords); + + // select this surface right away + surfaceManager.selectSurface(surfaceManager.size() - 1); } -void ofApp::setFboAsTexture() -{ - surfaceManager.getSurface(0)->setTexture( &fbo->getTextureReference() ); +void ofApp::setFboAsTexture() { + surfaceManager.getSurface(0)->setTexture(&fbo->getTextureReference()); } \ No newline at end of file diff --git a/example/src/ofApp.h b/example/src/ofApp.h index 05d7a8f..1a81109 100755 --- a/example/src/ofApp.h +++ b/example/src/ofApp.h @@ -1,31 +1,27 @@ -#ifndef H_OF_APP -#define H_OF_APP +#pragma once #include "ofMain.h" #include "ofxPiMapper.h" -class ofApp : public ofBaseApp -{ -public: - void setup(); - void update(); - void draw(); - void exit(); +class ofApp : public ofBaseApp { + public: + void setup(); + void update(); + void draw(); + void exit(); - void keyPressed(int key); - - void addRandomSurface(); - void addQuadSurface(); - void addSurface(); - void setFboAsTexture(); - - ofImage image; - ofxSurfaceManager surfaceManager; - ofxSurfaceManagerGui gui; - bool bShowInfo; - ofFbo* fbo; - vector rects; - vector rectSpeeds; -}; + void keyPressed(int key); -#endif \ No newline at end of file + void addRandomSurface(); + void addQuadSurface(); + void addSurface(); + void setFboAsTexture(); + + ofImage image; + ofx::piMapper::SurfaceManager surfaceManager; + ofx::piMapper::SurfaceManagerGui gui; + bool bShowInfo; + ofFbo* fbo; + vector rects; + vector rectSpeeds; +}; \ No newline at end of file diff --git a/src/BaseJoint.cpp b/src/BaseJoint.cpp new file mode 100644 index 0000000..37b96b2 --- /dev/null +++ b/src/BaseJoint.cpp @@ -0,0 +1,72 @@ +#include "BaseJoint.h" + +namespace ofx { +namespace piMapper { + +BaseJoint::BaseJoint() { + setDefaultColors(); + setDefaultProperties(); + registerMouseEvents(); +} + +BaseJoint::~BaseJoint() { unregisterMouseEvents(); } + +void BaseJoint::registerMouseEvents() { + ofAddListener(ofEvents().mousePressed, this, &BaseJoint::mousePressed); + ofAddListener(ofEvents().mouseDragged, this, &BaseJoint::mouseDragged); +} + +void BaseJoint::unregisterMouseEvents() { + ofRemoveListener(ofEvents().mousePressed, this, &BaseJoint::mousePressed); + ofRemoveListener(ofEvents().mouseDragged, this, &BaseJoint::mouseDragged); +} + +void BaseJoint::mousePressed(ofMouseEventArgs& args) { + if (hitTest(ofVec2f(args.x, args.y))) { + // selected = true; + clickDistance = position - ofVec2f(args.x, args.y); + // startDrag(); + } +} + +void BaseJoint::mouseReleased(int x, int y, int button) { stopDrag(); } + +void BaseJoint::mouseDragged(ofMouseEventArgs& args) { + if (!bDrag) return; + position = ofVec2f(args.x, args.y) + clickDistance; +} + +void BaseJoint::startDrag() { bDrag = true; } + +void BaseJoint::stopDrag() { bDrag = false; } + +void BaseJoint::select() { selected = true; } + +void BaseJoint::unselect() { selected = false; } + +void BaseJoint::setClickDistance(ofVec2f newClickDistance) { + clickDistance = newClickDistance; +} + +bool BaseJoint::isDragged() { return bDrag; } + +bool BaseJoint::isSelected() { return selected; } + +void BaseJoint::setDefaultColors() { + fillColor = ofColor(0, 255, 255, 0); + strokeColor = ofColor(255, 255, 255); + fillColorSelected = ofColor(255, 255, 0, 0); + strokeColorSelected = ofColor(255, 0, 0); +} + +void BaseJoint::setDefaultProperties() { + enabled = true; + visible = true; + position = ofVec2f(20.0f, 20.0f); + clickDistance = ofVec2f(0.0f, 0.0f); + bDrag = false; + selected = false; + strokeWidth = 1.5f; +} +} +} \ No newline at end of file diff --git a/src/BaseJoint.h b/src/BaseJoint.h new file mode 100644 index 0000000..d2fdcf0 --- /dev/null +++ b/src/BaseJoint.h @@ -0,0 +1,51 @@ +#pragma once + +#include "ofMain.h" + +namespace ofx { +namespace piMapper { + +class BaseJoint { + public: + BaseJoint(); + ~BaseJoint(); + + void registerMouseEvents(); + void unregisterMouseEvents(); + + ofVec2f position; + bool enabled; + bool visible; + bool selected; + + void mousePressed(ofMouseEventArgs& args); + void mouseReleased(int x, int y, int button); + void mouseDragged(ofMouseEventArgs& args); + void startDrag(); + void stopDrag(); + void select(); + void unselect(); + void setClickDistance(ofVec2f newClickDistance); + bool isDragged(); + bool isSelected(); + + virtual void update() {}; + virtual void draw() {}; + virtual bool hitTest(ofVec2f position) {}; + + protected: + ofColor fillColor; + ofColor strokeColor; + ofColor fillColorSelected; + ofColor strokeColorSelected; + float strokeWidth; + ofVec2f clickDistance; // How far from the center of the joint the user has + // clicked? + bool bDrag; + + private: + void setDefaultColors(); + void setDefaultProperties(); +}; +} +} diff --git a/src/BaseSurface.cpp b/src/BaseSurface.cpp new file mode 100644 index 0000000..b674cd8 --- /dev/null +++ b/src/BaseSurface.cpp @@ -0,0 +1,70 @@ +#include "BaseSurface.h" + +namespace ofx { +namespace piMapper { + +BaseSurface::BaseSurface() { + ofEnableNormalizedTexCoords(); + createDefaultTexture(); +} + +void BaseSurface::createDefaultTexture() { + ofPixels pixels; + pixels.allocate(500, 500, 1); + for (int i = 0; i < pixels.size(); i++) { + pixels[i] = 255; + } + int squareSize = 10; // size of each test pattern square + bool sy = false; + for (int y = 0; y < pixels.getWidth(); y += squareSize) { + bool sx = false; + for (int x = 0; x < pixels.getHeight(); x += squareSize) { + for (int yi = 0; yi < squareSize; yi++) { + for (int xi = 0; xi < squareSize; xi++) { + if (sx && sy) + pixels[(y + yi) * pixels.getWidth() + x + xi] = 255; + else if (sx && !sy) + pixels[(y + yi) * pixels.getWidth() + x + xi] = 0; + else if (!sx && sy) + pixels[(y + yi) * pixels.getWidth() + x + xi] = 0; + else + pixels[(y + yi) * pixels.getWidth() + x + xi] = 255; + } + } + sx = !sx; + } + sy = !sy; + } + + // load pixels into texture + defaultTexture.loadData(pixels); + + // Assign default texture to texture pointer + texture = &defaultTexture; +} + +void BaseSurface::drawTexture(ofVec2f position) { + ofMesh texMesh; + texMesh.addVertex(position); + texMesh.addVertex(position + ofVec2f(texture->getWidth(), 0.0f)); + texMesh.addVertex(position + + ofVec2f(texture->getWidth(), texture->getHeight())); + texMesh.addVertex(position + ofVec2f(0.0f, texture->getHeight())); + texMesh.addTriangle(0, 2, 3); + texMesh.addTriangle(0, 1, 2); + texMesh.addTexCoord(ofVec2f(0.0f, 0.0f)); + texMesh.addTexCoord(ofVec2f(1.0f, 0.0f)); + texMesh.addTexCoord(ofVec2f(1.0f, 1.0f)); + texMesh.addTexCoord(ofVec2f(0.0f, 1.0f)); + texture->bind(); + texMesh.draw(); + texture->unbind(); +} + +void BaseSurface::setTexture(ofTexture* texturePtr) { texture = texturePtr; } + +ofTexture* BaseSurface::getTexture() { return texture; } + +ofTexture* BaseSurface::getDefaultTexture() { return &defaultTexture; } +} +} \ No newline at end of file diff --git a/src/BaseSurface.h b/src/BaseSurface.h new file mode 100644 index 0000000..bf6703f --- /dev/null +++ b/src/BaseSurface.h @@ -0,0 +1,40 @@ +#pragma once + +#include "ofMain.h" +#include + +using namespace std; + +namespace ofx { +namespace piMapper { +class BaseSurface { + public: + BaseSurface(); + virtual void setup() {}; + virtual void draw() {}; + virtual void setVertex(int index, ofVec2f p) {}; + virtual void setTexCoord(int index, ofVec2f t) {}; + virtual void moveBy(ofVec2f v) {}; + virtual int getType() {}; + virtual bool hitTest(ofVec2f p) {}; + virtual ofPolyline getHitArea() {}; + virtual ofPolyline getTextureHitArea() {}; + virtual vector& getVertices() {}; + virtual vector& getTexCoords() {}; + + // Draws a texture using ofMesh + void drawTexture(ofVec2f position); + void setTexture(ofTexture* texturePtr); + + ofTexture* getTexture(); + ofTexture* getDefaultTexture(); + + protected: + ofMesh mesh; + ofTexture* texture; + ofTexture defaultTexture; + + void createDefaultTexture(); +}; +} +} \ No newline at end of file diff --git a/src/CircleJoint.cpp b/src/CircleJoint.cpp new file mode 100644 index 0000000..1e3bb3d --- /dev/null +++ b/src/CircleJoint.cpp @@ -0,0 +1,49 @@ +#include "CircleJoint.h" + +namespace ofx { +namespace piMapper { + +CircleJoint::CircleJoint() { setDefaultProperties(); } + +void CircleJoint::update() { + if (!enabled) return; +} + +void CircleJoint::draw() { + if (!visible) return; + if (!enabled) return; + + ofPushStyle(); + ofFill(); + + if (selected) { + ofSetColor(fillColorSelected); + } else { + ofSetColor(fillColor); + } + + ofCircle(position.x, position.y, radius); + ofNoFill(); + + if (selected) { + ofSetColor(strokeColorSelected); + } else { + ofSetColor(strokeColor); + } + + ofSetLineWidth(strokeWidth); + ofCircle(position.x, position.y, radius); + ofPopStyle(); +} + +void CircleJoint::setDefaultProperties() { radius = 10.0f; } + +bool CircleJoint::hitTest(ofVec2f pos) { + float distance = position.distance(pos); + if (distance < radius) + return true; + else + return false; +} +} +} \ No newline at end of file diff --git a/src/CircleJoint.h b/src/CircleJoint.h new file mode 100644 index 0000000..ade616f --- /dev/null +++ b/src/CircleJoint.h @@ -0,0 +1,22 @@ +#pragma once + +#include "ofMain.h" +#include "BaseJoint.h" + +namespace ofx { +namespace piMapper { +class CircleJoint : public BaseJoint { + public: + CircleJoint(); + + void update(); + void draw(); + bool hitTest(ofVec2f position); + + private: + float radius; + + void setDefaultProperties(); +}; +} +} \ No newline at end of file diff --git a/src/EditorType.h b/src/EditorType.h new file mode 100644 index 0000000..b7fdc14 --- /dev/null +++ b/src/EditorType.h @@ -0,0 +1,9 @@ +#pragma once + +namespace ofx { +namespace piMapper { +struct EditorType { + enum { TEXTURE, PROJECTION }; +}; +} +} \ No newline at end of file diff --git a/src/GuiMode.h b/src/GuiMode.h new file mode 100644 index 0000000..f6b1ac4 --- /dev/null +++ b/src/GuiMode.h @@ -0,0 +1,9 @@ +#pragma once + +namespace ofx { +namespace piMapper { +struct GuiMode { + enum { NONE, TEXTURE_MAPPING, PROJECTION_MAPPING, SOURCE_SELECTION }; +}; +} +} \ No newline at end of file diff --git a/src/ProjectionEditor.cpp b/src/ProjectionEditor.cpp new file mode 100644 index 0000000..1851cd2 --- /dev/null +++ b/src/ProjectionEditor.cpp @@ -0,0 +1,263 @@ +#include "ProjectionEditor.h" + +namespace ofx { +namespace piMapper { +ProjectionEditor::ProjectionEditor() { + surfaceManager = NULL; + bShiftKeyDown = false; + fSnapDistance = 10.0f; + enable(); +} + +ProjectionEditor::~ProjectionEditor() { + clearJoints(); + surfaceManager = NULL; + disable(); +} + +void ProjectionEditor::registerAppEvents() { + ofAddListener(ofEvents().update, this, &ProjectionEditor::update); + ofAddListener(ofEvents().messageEvent, this, &ProjectionEditor::gotMessage); +} + +void ProjectionEditor::unregisterAppEvents() { + ofRemoveListener(ofEvents().update, this, &ProjectionEditor::update); + ofRemoveListener(ofEvents().messageEvent, this, + &ProjectionEditor::gotMessage); +} + +void ProjectionEditor::registerMouseEvents() { + ofAddListener(ofEvents().mouseDragged, this, &ProjectionEditor::mouseDragged); +} + +void ProjectionEditor::unregisterMouseEvents() { + ofRemoveListener(ofEvents().mouseDragged, this, + &ProjectionEditor::mouseDragged); +} + +void ProjectionEditor::registerKeyEvents() { + ofAddListener(ofEvents().keyPressed, this, &ProjectionEditor::keyPressed); + ofAddListener(ofEvents().keyReleased, this, &ProjectionEditor::keyReleased); +} + +void ProjectionEditor::unregisterKeyEvents() { + ofRemoveListener(ofEvents().keyPressed, this, &ProjectionEditor::keyPressed); + ofRemoveListener(ofEvents().keyReleased, this, + &ProjectionEditor::keyReleased); +} + +void ProjectionEditor::enable() { + registerAppEvents(); + registerMouseEvents(); + registerKeyEvents(); +} + +void ProjectionEditor::disable() { + unregisterAppEvents(); + unregisterMouseEvents(); + unregisterKeyEvents(); +} + +void ProjectionEditor::update(ofEventArgs& args) { + // update surface if one of the joints is being dragged + for (int i = 0; i < joints.size(); i++) { + if (joints[i]->isDragged() || joints[i]->isSelected()) { + if (surfaceManager->getSelectedSurface() != NULL) { + // update vertex to new location + surfaceManager->getSelectedSurface()->setVertex(i, joints[i]->position); + } else { + // clear joints if there is no surface selected + // as the remove selected surface in the surface manager + // is not supposed to access joints here + joints.clear(); + } + break; + } + } +} + +void ProjectionEditor::draw() { + if (surfaceManager == NULL) return; + if (surfaceManager->getSelectedSurface() == NULL) return; + if (joints.size() <= 0) createJoints(); + drawJoints(); +} + +void ProjectionEditor::mouseDragged(ofMouseEventArgs& args) { + ofVec2f mousePosition = ofVec2f(args.x, args.y); + + // Collect all vertices of the projection surfaces + vector allVertices; + for (int i = 0; i < surfaceManager->size(); i++) { + BaseSurface* surface = surfaceManager->getSurface(i); + if (surface == surfaceManager->getSelectedSurface()) { + continue; // Don't add vertices of selected surface + } + for (int j = 0; j < surface->getVertices().size(); j++) { + allVertices.push_back(&surface->getVertices()[j]); + } + } + + // Snap currently dragged joint to nearest vertex + for (int i = 0; i < joints.size(); i++) { + if (joints[i]->isDragged()) { + // Snap it! + for (int j = 0; j < allVertices.size(); j++) { + float distance = mousePosition.distance(*allVertices[j]); + // cout << "distance: " << distance << endl; + if (distance < fSnapDistance) { + joints[i]->position = *allVertices[j]; + ofVec2f clickDistance = joints[i]->position - ofVec2f(args.x, args.y); + joints[i]->setClickDistance(clickDistance); + break; + } + } + } + } +} + +void ProjectionEditor::keyPressed(ofKeyEventArgs& args) { + int key = args.key; + float moveStep; + + if (bShiftKeyDown) + moveStep = 10.0f; + else + moveStep = 0.5f; + + switch (key) { + case OF_KEY_LEFT: + moveSelection(ofVec2f(-moveStep, 0.0f)); + break; + case OF_KEY_RIGHT: + moveSelection(ofVec2f(moveStep, 0.0f)); + break; + case OF_KEY_UP: + moveSelection(ofVec2f(0.0f, -moveStep)); + break; + case OF_KEY_DOWN: + moveSelection(ofVec2f(0.0f, moveStep)); + break; + case OF_KEY_SHIFT: + bShiftKeyDown = true; + break; + } +} + +void ProjectionEditor::keyReleased(ofKeyEventArgs& args) { + int key = args.key; + switch (key) { + case OF_KEY_SHIFT: + bShiftKeyDown = false; + break; + } +} + +void ProjectionEditor::gotMessage(ofMessage& msg) { + if (msg.message == "surfaceSelected") { + // refresh gui + clearJoints(); + createJoints(); + } +} + +void ProjectionEditor::setSurfaceManager(SurfaceManager* newSurfaceManager) { + surfaceManager = newSurfaceManager; +} + +void ProjectionEditor::clearJoints() { + while (joints.size()) { + delete joints.back(); + joints.pop_back(); + } +} + +void ProjectionEditor::createJoints() { + if (surfaceManager == NULL) return; + clearJoints(); + + if (surfaceManager->getSelectedSurface() == NULL) { + ofLog(OF_LOG_WARNING, "Trying to create joints while no surface selected."); + return; + } + + vector& vertices = + surfaceManager->getSelectedSurface()->getVertices(); + + for (int i = 0; i < vertices.size(); i++) { + joints.push_back(new CircleJoint()); + joints.back()->position = ofVec2f(vertices[i].x, vertices[i].y); + } +} + +void ProjectionEditor::updateJoints() { + vector& vertices = + surfaceManager->getSelectedSurface()->getVertices(); + for (int i = 0; i < vertices.size(); i++) { + joints[i]->position = ofVec2f(vertices[i].x, vertices[i].y); + } +} + +void ProjectionEditor::unselectAllJoints() { + for (int i = 0; i < joints.size(); i++) { + joints[i]->unselect(); + } +} + +void ProjectionEditor::moveSelectedSurface(ofVec2f by) { + if (surfaceManager == NULL) return; + if (surfaceManager->getSelectedSurface() == NULL) return; + surfaceManager->getSelectedSurface()->moveBy(by); + /*vector& vertices = + surfaceManager->getSelectedSurface()->getVertices(); + for (int i=0; istopDrag(); + } +} + +void ProjectionEditor::moveSelection(ofVec2f by) { + // check if joints selected + bool bJointSelected = false; + BaseJoint* selectedJoint; + for (int i = 0; i < joints.size(); i++) { + if (joints[i]->isSelected()) { + bJointSelected = true; + selectedJoint = joints[i]; + break; + } + } + + if (bJointSelected) { + selectedJoint->position += by; + } else { + moveSelectedSurface(by); + } +} + +void ProjectionEditor::setSnapDistance(float newSnapDistance) { + fSnapDistance = newSnapDistance; +} + +CircleJoint* ProjectionEditor::hitTestJoints(ofVec2f pos) { + for (int i = 0; i < joints.size(); i++) { + if (joints[i]->hitTest(pos)) { + return joints[i]; + } + } + return NULL; +} + +void ProjectionEditor::drawJoints() { + for (int i = 0; i < joints.size(); i++) { + joints[i]->draw(); + } +} +} +} \ No newline at end of file diff --git a/src/ProjectionEditor.h b/src/ProjectionEditor.h new file mode 100755 index 0000000..50b8582 --- /dev/null +++ b/src/ProjectionEditor.h @@ -0,0 +1,50 @@ +#pragma once + +#include "SurfaceManager.h" +#include "CircleJoint.h" + +namespace ofx { +namespace piMapper { +class ProjectionEditor { + public: + ProjectionEditor(); + ~ProjectionEditor(); + + void registerAppEvents(); + void unregisterAppEvents(); + void registerMouseEvents(); + void unregisterMouseEvents(); + void registerKeyEvents(); + void unregisterKeyEvents(); + + void enable(); + void disable(); + + void update(ofEventArgs& args); + void draw(); + void mouseDragged(ofMouseEventArgs& args); + void keyPressed(ofKeyEventArgs& args); + void keyReleased(ofKeyEventArgs& args); + void gotMessage(ofMessage& msg); + void setSurfaceManager(SurfaceManager* newSurfaceManager); + void clearJoints(); + void createJoints(); + void updateJoints(); + void unselectAllJoints(); + void moveSelectedSurface(ofVec2f by); + void stopDragJoints(); + void updateVertices(); + void moveSelection(ofVec2f by); + void setSnapDistance(float newSnapDistance); + CircleJoint* hitTestJoints(ofVec2f pos); + + private: + SurfaceManager* surfaceManager; + vector joints; + bool bShiftKeyDown; + float fSnapDistance; + + void drawJoints(); +}; +} +} \ No newline at end of file diff --git a/src/QuadSurface.cpp b/src/QuadSurface.cpp new file mode 100644 index 0000000..c72587c --- /dev/null +++ b/src/QuadSurface.cpp @@ -0,0 +1,243 @@ +#include "QuadSurface.h" + +namespace ofx { +namespace piMapper { +QuadSurface::QuadSurface() { + cout << "QuadSurface constructor." << endl; + setup(); +} + +QuadSurface::~QuadSurface() { cout << "QuadSurface destructor." << endl; } + +void QuadSurface::setup() { + // Create 4 points for the 2 triangles + ofVec2f p1 = ofVec2f(0, 0); + ofVec2f p2 = ofVec2f(0, ofGetHeight()); + ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); + ofVec2f p4 = ofVec2f(ofGetWidth(), 0); + + // Create 4 point for the texture coordinates + ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 0.0f)); + ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 0.0f)); + ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f)); + ofVec2f t4 = ofVec2f(ofVec2f(0.0f, 1.0f)); + + setup(p1, p2, p3, p4, t1, t2, t3, t4, texture); +} + +void QuadSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, + ofVec2f t1, ofVec2f t2, ofVec2f t3, ofVec2f t4, + ofTexture* texturePtr) { + // Assign texture + texture = texturePtr; + + // Clear mesh + mesh.clear(); + + // Create a surface with the points + mesh.addVertex(p1); + mesh.addVertex(p2); + mesh.addVertex(p3); + mesh.addVertex(p4); + + // Add 2 triangles + mesh.addTriangle(0, 2, 3); + mesh.addTriangle(0, 1, 2); + + // Add texture coordinates + mesh.addTexCoord(t1); + mesh.addTexCoord(t2); + mesh.addTexCoord(t3); + mesh.addTexCoord(t4); + + // Pure GL setup + // indices + quadIndices[0] = 0; + quadIndices[1] = 1; + quadIndices[2] = 2; + quadIndices[3] = 0; + quadIndices[4] = 2; + quadIndices[5] = 3; + // tex coords (those are alway 0) + quadTexCoordinates[2] = 0; + quadTexCoordinates[6] = 0; + quadTexCoordinates[10] = 0; + quadTexCoordinates[14] = 0; + + calculate4dTextureCoords(); +} + +void QuadSurface::draw() { + /*if(mesh.haveVertsChanged() || mesh.haveTexCoordsChanged()){ + calculate4dTextureCoords(); + }*/ + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(4, GL_FLOAT, 0, quadTexCoordinates); + glVertexPointer(3, GL_FLOAT, 0, quadVertices); + + texture->bind(); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, quadIndices); + texture->unbind(); +} + +void QuadSurface::setVertex(int index, ofVec2f p) { + if (index > 3) { + ofLog() << "Vertex with this index does not exist: " << index << endl; + return; + } + + mesh.setVertex(index, p); + calculate4dTextureCoords(); +} + +void QuadSurface::setTexCoord(int index, ofVec2f t) { + if (index > 3) { + ofLog() << "Texture coordinate with this index does not exist: " << index + << endl; + return; + } + + mesh.setTexCoord(index, t); + calculate4dTextureCoords(); +} + +void QuadSurface::moveBy(ofVec2f v) { + vector& vertices = getVertices(); + for (int i = 0; i < vertices.size(); i++) { + vertices[i] += v; + } + calculate4dTextureCoords(); +} + +int QuadSurface::getType() { return SurfaceType::QUAD_SURFACE; } + +bool QuadSurface::hitTest(ofVec2f p) { + // Construct ofPolyline from vertices + ofPolyline line = getHitArea(); + + if (line.inside(p.x, p.y)) { + return true; + } else { + return false; + } +} + +ofVec2f QuadSurface::getVertex(int index) { + if (index > 3) { + ofLog() << "Vertex with this index does not exist: " << index << endl; + throw std::runtime_error("Vertex index out of bounds."); + } + + ofVec3f vert = mesh.getVertex(index); + return ofVec2f(vert.x, vert.y); +} + +ofVec2f QuadSurface::getTexCoord(int index) { + if (index > 3) { + throw std::runtime_error("Texture coordinate index out of bounds."); + } + + return mesh.getTexCoord(index); +} + +ofPolyline QuadSurface::getHitArea() { + ofPolyline line; + line.addVertex(ofPoint(mesh.getVertex(0).x, mesh.getVertex(0).y)); + line.addVertex(ofPoint(mesh.getVertex(1).x, mesh.getVertex(1).y)); + line.addVertex(ofPoint(mesh.getVertex(2).x, mesh.getVertex(2).y)); + line.addVertex(ofPoint(mesh.getVertex(3).x, mesh.getVertex(3).y)); + line.close(); + + return line; +} + +ofPolyline QuadSurface::getTextureHitArea() { + ofPolyline line; + vector& texCoords = mesh.getTexCoords(); + ofVec2f textureSize = ofVec2f(texture->getWidth(), texture->getHeight()); + for (int i = 0; i < texCoords.size(); i++) { + line.addVertex(ofPoint(texCoords[i] * textureSize)); + } + line.close(); + + return line; +} + +vector& QuadSurface::getVertices() { + // return only joint vertices + return mesh.getVertices(); +} + +vector& QuadSurface::getTexCoords() { return mesh.getTexCoords(); } + +void QuadSurface::calculate4dTextureCoords() { + // Perspective Warping with OpenGL Fixed Pipeline and q coordinates + // see: + // http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/ + // for information on the technique + // Pue OpenGL is used because the ofMesh sadly doesn't support ofVec4f as + // texture coordinates. + // calculate intersection point + ofVec3f p0 = mesh.getVertex(0); + ofVec3f p1 = mesh.getVertex(1); + ofVec3f p2 = mesh.getVertex(2); + ofVec3f p3 = mesh.getVertex(3); + + ofVec3f t0 = mesh.getTexCoord(0); + ofVec3f t1 = mesh.getTexCoord(1); + ofVec3f t2 = mesh.getTexCoord(2); + ofVec3f t3 = mesh.getTexCoord(3); + + ofPoint interSect; + ofLineSegmentIntersection(ofPoint(p0.x, p0.y), ofPoint(p2.x, p2.y), + ofPoint(p1.x, p1.y), ofPoint(p3.x, p3.y), + interSect); + ofVec3f interSecVec = ofVec3f(interSect.x, interSect.y, 0); + + // calculate distances to intersection point + float d0 = interSecVec.distance(p0); + float d1 = interSecVec.distance(p1); + float d2 = interSecVec.distance(p2); + float d3 = interSecVec.distance(p3); + + // vertices + // top left corner + quadVertices[0] = p0.x; + quadVertices[1] = p0.y; + quadVertices[2] = 0; + // top right corner + quadVertices[3] = p1.x; + quadVertices[4] = p1.y; + quadVertices[5] = 0; + // bottom right corner + quadVertices[6] = p2.x; + quadVertices[7] = p2.y; + quadVertices[8] = 0; + // bottom left corner + quadVertices[9] = p3.x; + quadVertices[10] = p3.y; + quadVertices[11] = 0; + + float q0 = (d0 + d2) / (d2); + float q1 = (d1 + d3) / (d3); + float q2 = (d2 + d0) / (d0); + float q3 = (d3 + d1) / (d1); + + quadTexCoordinates[0] = t0.x; + quadTexCoordinates[1] = t0.y; + quadTexCoordinates[3] = q0; + + quadTexCoordinates[4] = t1.x * q1; + quadTexCoordinates[5] = t1.y; + quadTexCoordinates[7] = q1; + + quadTexCoordinates[8] = t2.x * q2; + quadTexCoordinates[9] = t2.y * q2; + quadTexCoordinates[11] = q2; + + quadTexCoordinates[12] = t3.x; + quadTexCoordinates[13] = t3.y * q3; + quadTexCoordinates[15] = q3; +} +} +} \ No newline at end of file diff --git a/src/QuadSurface.h b/src/QuadSurface.h new file mode 100755 index 0000000..223e367 --- /dev/null +++ b/src/QuadSurface.h @@ -0,0 +1,40 @@ +#pragma once + +#include "ofMain.h" +#include "BaseSurface.h" +#include "SurfaceType.h" + +namespace ofx { +namespace piMapper { +class QuadSurface : public BaseSurface { + public: + QuadSurface(); + ~QuadSurface(); + + void setup(); + + void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, ofVec2f t1, + ofVec2f t2, ofVec2f t3, ofVec2f t4, ofTexture* texturePtr); + + void draw(); + void setVertex(int index, ofVec2f p); + void setTexCoord(int index, ofVec2f t); + void moveBy(ofVec2f v); + + int getType(); + bool hitTest(ofVec2f p); + ofVec2f getVertex(int index); + ofVec2f getTexCoord(int index); + ofPolyline getHitArea(); + ofPolyline getTextureHitArea(); + vector& getVertices(); + vector& getTexCoords(); + + private: + void calculate4dTextureCoords(); + GLfloat quadVertices[12]; + GLubyte quadIndices[6]; + GLfloat quadTexCoordinates[16]; +}; +} +} \ No newline at end of file diff --git a/src/SourcesEditor.cpp b/src/SourcesEditor.cpp new file mode 100644 index 0000000..452ddb9 --- /dev/null +++ b/src/SourcesEditor.cpp @@ -0,0 +1,121 @@ +#include "SourcesEditor.h" + +namespace ofx { +namespace piMapper { +SourcesEditor::SourcesEditor() { + defImgDir = DEFAULT_IMAGES_DIR; + registerAppEvents(); +} + +SourcesEditor::~SourcesEditor() { + unregisterAppEvents(); + delete gui; + while (images.size()) { + delete images.back(); + images.pop_back(); + } +} + +void SourcesEditor::registerAppEvents() { + ofAddListener(ofEvents().setup, this, &SourcesEditor::setup); +} + +void SourcesEditor::unregisterAppEvents() { + ofRemoveListener(ofEvents().setup, this, &SourcesEditor::setup); +} + +void SourcesEditor::setup(ofEventArgs& args) { + gui = new RadioList(); + + // read directory contents + ofDirectory imgDir; + imgDir.listDir(defImgDir); + imgDir.sort(); + + vector vnames; + + for (int i = 0; i < (int)imgDir.size(); i++) { + // images[i].loadImage(imgDir.getPath(i)); + vnames.push_back(imgDir.getName(i)); + } + + gui->setup("Images", vnames); + gui->setPosition(20, 20); + ofAddListener(gui->radioSelectedEvent, this, &SourcesEditor::guiEvent); +} + +void SourcesEditor::draw() { + // Don't draw if there is no source selected + if (surfaceManager->getSelectedSurface() == NULL) { + return; + } + + gui->draw(); +} + +void SourcesEditor::loadImage(string name, string path) { + images.push_back(new ofImage()); + images.back()->loadImage(path); + + imageNames.push_back(name); + + ofSendMessage("imageLoaded"); +} + +void SourcesEditor::disable() { gui->disable(); } + +void SourcesEditor::enable() { + // Don't enable if there is no surface selected + if (surfaceManager->getSelectedSurface() == NULL) { + cout << "No surface selected. Not enable()ing source list." << endl; + return; + } + + gui->enable(); +} + +void SourcesEditor::setSurfaceManager(SurfaceManager* newSurfaceManager) { + surfaceManager = newSurfaceManager; +} + +void SourcesEditor::selectImageSourceRadioButton(string name) { + if (name == "none") { + gui->unselectAll(); + return; + } else { + int i; + for (i = 0; i < gui->size(); i++) { + if (gui->getItemName(i) == name) { + gui->selectItem(i); + return; + } + } + } +} + +int SourcesEditor::getLoadedTexCount() { return images.size(); } + +ofTexture* SourcesEditor::getTexture(int index) { + if (index >= images.size()) { + throw std::runtime_error("Texture index out of bounds."); + } + + return &images[index]->getTextureReference(); +} + +void SourcesEditor::guiEvent(string& imageName) { + string name = imageName; + + if (surfaceManager->getSelectedSurface() == NULL) { + return; + } + + stringstream ss; + ss << defImgDir << name; + cout << "attempt to load image: " << ss.str() << endl; + ofTexture* texture = surfaceManager->loadImageSource(name, ss.str()); + surfaceManager->getSelectedSurface()->setTexture(texture); + surfaceManager->manageMemory(); +} +} +} \ No newline at end of file diff --git a/src/SourcesEditor.h b/src/SourcesEditor.h new file mode 100644 index 0000000..ee4462b --- /dev/null +++ b/src/SourcesEditor.h @@ -0,0 +1,40 @@ +#pragma once + +#include "ofGraphics.h" +#include "ofEvents.h" +#include "SurfaceManager.h" +#include "RadioList.h" + +#define DEFAULT_IMAGES_DIR "sources/images/"; + +namespace ofx { +namespace piMapper { +class SourcesEditor { + public: + SourcesEditor(); + ~SourcesEditor(); + + void registerAppEvents(); + void unregisterAppEvents(); + + void setup(ofEventArgs& args); + void draw(); + void loadImage(string name, string path); + void disable(); + void enable(); + void setSurfaceManager(SurfaceManager* newSurfaceManager); + void selectImageSourceRadioButton(string name); + + int getLoadedTexCount(); + ofTexture* getTexture(int index); + + private: + SurfaceManager* surfaceManager; + RadioList* gui; + string defImgDir; + void guiEvent(string& imageName); + vector images; + vector imageNames; +}; +} +} \ No newline at end of file diff --git a/src/SurfaceManager.cpp b/src/SurfaceManager.cpp new file mode 100644 index 0000000..d29ca09 --- /dev/null +++ b/src/SurfaceManager.cpp @@ -0,0 +1,462 @@ +#include "SurfaceManager.h" + +namespace ofx { +namespace piMapper { +SurfaceManager::SurfaceManager() {} + +SurfaceManager::~SurfaceManager() { clear(); } + +void SurfaceManager::draw() { + for (int i = 0; i < surfaces.size(); i++) { + surfaces[i]->draw(); + } +} + +void SurfaceManager::addSurface(int surfaceType) { + if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { + surfaces.push_back(new TriangleSurface()); + } else if (surfaceType == SurfaceType::QUAD_SURFACE) { + surfaces.push_back(new QuadSurface()); + } else { + throw std::runtime_error("Attempt to add non-existing surface type."); + } +} + +void SurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr) { + if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { + surfaces.push_back(new TriangleSurface()); + surfaces.back()->setTexture(texturePtr); + } else if (surfaceType == SurfaceType::QUAD_SURFACE) { + surfaces.push_back(new QuadSurface()); + surfaces.back()->setTexture(texturePtr); + } else { + throw std::runtime_error("Attempt to add non-existing surface type."); + } +} + +void SurfaceManager::addSurface(int surfaceType, vector vertices, + vector texCoords) { + if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { + if (vertices.size() < 3) { + throw std::runtime_error( + "There must be 3 vertices for a triangle surface."); + } else if (texCoords.size() < 3) { + throw std::runtime_error( + "There must be 3 texture coordinates for a triangle surface."); + } + + surfaces.push_back(new TriangleSurface()); + + for (int i = 0; i < 3; i++) { + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + + } else if (surfaceType == SurfaceType::QUAD_SURFACE) { + if (vertices.size() < 4) { + throw std::runtime_error("There must be 4 vertices for a quad surface."); + } else if (texCoords.size() < 4) { + throw std::runtime_error( + "There must be 4 texture coordinates for a quad surface."); + } + + surfaces.push_back(new QuadSurface()); + + for (int i = 0; i < 4; i++) { + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + } else { + throw std::runtime_error("Attempt to add non-existing surface type."); + } +} + +void SurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr, + vector vertices, + vector texCoords) { + if (surfaceType == SurfaceType::TRIANGLE_SURFACE) { + if (vertices.size() < 3) { + throw std::runtime_error( + "There must be 3 vertices for a triangle surface."); + } else if (texCoords.size() < 3) { + throw std::runtime_error( + "Thre must be 3 texture coordinates for a triangle surface."); + } + + surfaces.push_back(new TriangleSurface()); + surfaces.back()->setTexture(texturePtr); + + for (int i = 0; i < 3; i++) { + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + + } else if (surfaceType == SurfaceType::QUAD_SURFACE) { + if (vertices.size() < 4) { + throw std::runtime_error("There must be 4 vertices for a quad surface."); + } else if (texCoords.size() < 4) { + throw std::runtime_error( + "Thre must be 4 texture coordinates for a quad surface."); + } + + surfaces.push_back(new QuadSurface()); + surfaces.back()->setTexture(texturePtr); + + for (int i = 0; i < 4; i++) { + surfaces.back()->setVertex(i, vertices[i]); + surfaces.back()->setTexCoord(i, texCoords[i]); + } + } else { + throw std::runtime_error("Attempt to add non-existing surface type."); + } +} + +void SurfaceManager::removeSelectedSurface() { + if (selectedSurface == NULL) return; + + for (int i = 0; i < surfaces.size(); i++) { + if (surfaces[i] == selectedSurface) { + delete surfaces[i]; + surfaces.erase(surfaces.begin() + i); + selectedSurface = NULL; + break; + } + } +} + +void SurfaceManager::manageMemory() { + // check if each of the sources is assigned to a surface or not + for (int i = 0; i < loadedImageSources.size(); i++) { + bool bAssigned = false; + + for (int j = 0; j < surfaces.size(); j++) { + if (surfaces[j]->getTexture() == + &loadedImageSources[i]->getTextureReference()) { + bAssigned = true; + break; + } + } + + if (!bAssigned) { + // purge the image source from memory + delete loadedImageSources[i]; + loadedImageSources.erase(loadedImageSources.begin() + i); + cout << "Deleting image source: " << loadedImageSourceNames[i] << endl; + loadedImageSourceNames.erase(loadedImageSourceNames.begin() + i); + i--; + } + } +} + +void SurfaceManager::clear() { + // delete all extra allocations from the heap + while (surfaces.size()) { + delete surfaces.back(); + surfaces.pop_back(); + } + + while (loadedImageSources.size()) { + delete loadedImageSources.back(); + loadedImageSources.pop_back(); + } + + while (loadedImageSourceNames.size()) { + loadedImageSourceNames.pop_back(); + } +} + +// String getTypeString(SurfaceType e) +// { +// switch e +// { +// case TRINAGLE_SURFACE: return "TRINAGLE_SURFACE"; +// case QUAD_SURFACE: return "QUAD_SURFACE"; +// default: throw Exception("Bad MyEnum"); +// } +// } + +void SurfaceManager::saveXmlSettings(string fileName) { + xmlSettings.clear(); + + // save surfaces + xmlSettings.addTag("surfaces"); + xmlSettings.pushTag("surfaces"); + for (int i = 0; i < surfaces.size(); i++) { + xmlSettings.addTag("surface"); + xmlSettings.pushTag("surface", i); + BaseSurface* surface = surfaces[i]; + + xmlSettings.addTag("vertices"); + xmlSettings.pushTag("vertices"); + vector* vertices = &surface->getVertices(); + for (int j = 0; j < vertices->size(); j++) { + xmlSettings.addTag("vertex"); + xmlSettings.pushTag("vertex", j); + ofVec3f* vertex = &(*vertices)[j]; + xmlSettings.addValue("x", vertex->x); + xmlSettings.addValue("y", vertex->y); + + // we don't need z as it will be 0 anyways + + xmlSettings.popTag(); // vertex + } + xmlSettings.popTag(); // vertices + + xmlSettings.addTag("texCoords"); + xmlSettings.pushTag("texCoords"); + vector* texCoords = &surface->getTexCoords(); + for (int j = 0; j < texCoords->size(); j++) { + xmlSettings.addTag("texCoord"); + xmlSettings.pushTag("texCoord", j); + ofVec2f* texCoord = &(*texCoords)[j]; + xmlSettings.addValue("x", texCoord->x); + xmlSettings.addValue("y", texCoord->y); + xmlSettings.popTag(); // texCoord + } + xmlSettings.popTag(); // texCoords + + xmlSettings.addTag("source"); + xmlSettings.pushTag("source"); + + xmlSettings.addValue("source-type", "image"); + xmlSettings.addValue("source-name", getSurfaceSourceName(surface)); + // xmlSettings.addValue("source-path", "/root/etc/image.jpg"); + xmlSettings.popTag(); // source + + // xmlSettings.addTag("type"); + // xmlSettings.pushTag("type"); + // // surfaceType == SurfaceType::TRIANGLE_SURFACE + // SurfaceType surfaceType = &surface->getType(); + // xmlSettings.addValue("surface-type", surfaceType); + // xmlSettings.popTag(); // type + + xmlSettings.popTag(); // surface + } + xmlSettings.popTag(); // surfaces + + xmlSettings.save(fileName); +} + +void SurfaceManager::loadXmlSettings(string fileName) { + if (!xmlSettings.loadFile(fileName)) { + ofLog(OF_LOG_WARNING, "Could not load XML settings."); + return; + } + + if (!xmlSettings.tagExists("surfaces")) { + ofLog(OF_LOG_WARNING, "XML settings is empty or has wrong markup."); + return; + } + + xmlSettings.pushTag("surfaces"); + + int numSurfaces = xmlSettings.getNumTags("surface"); + for (int i = 0; i < numSurfaces; i++) { + xmlSettings.pushTag("surface", i); + // attempt to load surface source + xmlSettings.pushTag("source"); + string sourceType = xmlSettings.getValue("source-type", "image"); + string sourceName = xmlSettings.getValue("source-name", "none"); + ofTexture* sourceTexture = NULL; + if (sourceName != "none") { + stringstream ss; + ss << "sources/images/" << sourceName; // TODO: reuse constants here + sourceTexture = loadImageSource(sourceName, ss.str()); + } + xmlSettings.popTag(); // source + + // // attempt to load surface type + // ofLog(OF_LOG_WARNING, "Attempt to load surface type."); + // xmlSettings.pushTag("type"); + // string surfaceType = xmlSettings.getValue("surface-type", + // "TRIANGLE_SURFACE"); + // xmlSettings.popTag(); // type + + xmlSettings.pushTag("vertices"); + vector vertices; + + int vertexCount = xmlSettings.getNumTags("vertex"); + + // it's a triangle ? + if (vertexCount == 3) { + ofLog(OF_LOG_NOTICE, "create Triangle"); + xmlSettings.pushTag("vertex", 0); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 1); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 2); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 100.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // vertices + + xmlSettings.pushTag("texCoords"); + + vector texCoords; + + xmlSettings.pushTag("texCoord", 0); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 1); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 2); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 1.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // texCoords + + // now we have variables sourceName and sourceTexture + // by checking those we can use one or another addSurface method + if (sourceName != "none" && sourceTexture != NULL) { + addSurface(SurfaceType::TRIANGLE_SURFACE, sourceTexture, vertices, + texCoords); + } else { + addSurface(SurfaceType::TRIANGLE_SURFACE, vertices, texCoords); + } + } + // it's a quad ? + else if (vertexCount == 4) + // if (surface-type == QUAD_SURFACE) + { + xmlSettings.pushTag("vertex", 0); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 1); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 2); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 100.0f), + xmlSettings.getValue("y", 100.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("vertex", 3); + vertices.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 100.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // vertices + + xmlSettings.pushTag("texCoords"); + + vector texCoords; + + xmlSettings.pushTag("texCoord", 0); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 1); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), + xmlSettings.getValue("y", 0.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 2); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 1.0f), + xmlSettings.getValue("y", 1.0f))); + xmlSettings.popTag(); + + xmlSettings.pushTag("texCoord", 3); + texCoords.push_back(ofVec2f(xmlSettings.getValue("x", 0.0f), + xmlSettings.getValue("y", 1.0f))); + xmlSettings.popTag(); + + xmlSettings.popTag(); // texCoords + + // now we have variables sourceName and sourceTexture + // by checking those we can use one or another addSurface method + if (sourceName != "none" && sourceTexture != NULL) { + addSurface(SurfaceType::QUAD_SURFACE, sourceTexture, vertices, + texCoords); + } else { + addSurface(SurfaceType::QUAD_SURFACE, vertices, texCoords); + } + } + + xmlSettings.popTag(); // surface + } + + xmlSettings.popTag(); // surfaces +} + +BaseSurface* SurfaceManager::selectSurface(int index) { + if (index >= surfaces.size()) { + throw std::runtime_error("Surface index out of bounds."); + } + + selectedSurface = surfaces[index]; + + // notify that a new surface has been selected + ofSendMessage("surfaceSelected"); +} + +BaseSurface* SurfaceManager::getSelectedSurface() { return selectedSurface; } + +void SurfaceManager::deselectSurface() { selectedSurface = NULL; } + +ofTexture* SurfaceManager::loadImageSource(string name, string path) { + // check if it is loaded + for (int i = 0; i < loadedImageSourceNames.size(); i++) { + if (loadedImageSourceNames[i] == name) { + // this image is already loaded + return &loadedImageSources[i]->getTextureReference(); + } + } + + // not loaded - load + ofImage* image = new ofImage(); + if (!image->loadImage(path)) { + return NULL; + } + loadedImageSources.push_back(image); + loadedImageSourceNames.push_back(name); + return &image->getTextureReference(); +} + +string SurfaceManager::getSelectedSurfaceSourceName() { + if (selectedSurface == NULL) { + return "none"; + } + + return getSurfaceSourceName(selectedSurface); +} + +string SurfaceManager::getSurfaceSourceName(BaseSurface* surface) { + ofTexture* tex = surface->getTexture(); + for (int i = 0; i < loadedImageSources.size(); i++) { + if (tex == &loadedImageSources[i]->getTextureReference()) { + return loadedImageSourceNames[i]; + } + } + + return "none"; +} + +BaseSurface* SurfaceManager::getSurface(int index) { + if (index >= surfaces.size()) { + throw std::runtime_error("Surface index out of bounds."); + return NULL; + } + + return surfaces[index]; +} + +int SurfaceManager::size() { return surfaces.size(); } +} +} diff --git a/src/SurfaceManager.h b/src/SurfaceManager.h new file mode 100755 index 0000000..38af95f --- /dev/null +++ b/src/SurfaceManager.h @@ -0,0 +1,50 @@ +#pragma once + +#include "BaseSurface.h" +#include "TriangleSurface.h" +#include "QuadSurface.h" +#include "SurfaceType.h" + +#include "ofEvents.h" +#include "ofxXmlSettings.h" + +using namespace std; + +namespace ofx { +namespace piMapper { +class SurfaceManager { + public: + SurfaceManager(); + ~SurfaceManager(); + + void draw(); + void addSurface(int surfaceType); + void addSurface(int surfaceType, ofTexture* texturePtr); + void addSurface(int surfaceType, vector vertices, + vector texCoords); + void addSurface(int surfaceType, ofTexture* texturePtr, + vector vertices, vector texCoords); + void removeSelectedSurface(); + void manageMemory(); // deletes unasigned sources + void clear(); + void saveXmlSettings(string fileName); + void loadXmlSettings(string fileName); + + BaseSurface* getSurface(int index); + int size(); + BaseSurface* selectSurface(int index); + BaseSurface* getSelectedSurface(); + void deselectSurface(); + ofTexture* loadImageSource(string name, string path); + string getSelectedSurfaceSourceName(); + string getSurfaceSourceName(BaseSurface* surface); + + private: + vector surfaces; + BaseSurface* selectedSurface; + vector loadedImageSourceNames; + vector loadedImageSources; + ofxXmlSettings xmlSettings; +}; +} +} \ No newline at end of file diff --git a/src/SurfaceManagerGui.cpp b/src/SurfaceManagerGui.cpp new file mode 100644 index 0000000..ce73e99 --- /dev/null +++ b/src/SurfaceManagerGui.cpp @@ -0,0 +1,243 @@ +#include "SurfaceManagerGui.h" + +namespace ofx { +namespace piMapper { +SurfaceManagerGui::SurfaceManagerGui() { + surfaceManager = NULL; + guiMode = GuiMode::NONE; + bDrag = false; + registerMouseEvents(); + ofHideCursor(); +} + +SurfaceManagerGui::~SurfaceManagerGui() { + unregisterMouseEvents(); + surfaceManager = NULL; +} + +void SurfaceManagerGui::registerMouseEvents() { + ofAddListener(ofEvents().mousePressed, this, + &SurfaceManagerGui::mousePressed); + ofAddListener(ofEvents().mouseReleased, this, + &SurfaceManagerGui::mouseReleased); + ofAddListener(ofEvents().mouseDragged, this, + &SurfaceManagerGui::mouseDragged); +} + +void SurfaceManagerGui::unregisterMouseEvents() { + ofRemoveListener(ofEvents().mousePressed, this, + &SurfaceManagerGui::mousePressed); + ofRemoveListener(ofEvents().mouseReleased, this, + &SurfaceManagerGui::mouseReleased); + ofRemoveListener(ofEvents().mouseDragged, this, + &SurfaceManagerGui::mouseDragged); +} + +void SurfaceManagerGui::draw() { + if (surfaceManager == NULL) return; + + if (guiMode == GuiMode::NONE) { + surfaceManager->draw(); + } else if (guiMode == GuiMode::TEXTURE_MAPPING) { + // draw the texture of the selected surface + if (surfaceManager->getSelectedSurface() != NULL) { + surfaceManager->getSelectedSurface()->drawTexture(ofVec2f(0, 0)); + } + + // draw surfaces with opacity + ofPushStyle(); + ofSetColor(255, 255, 255, 200); + surfaceManager->draw(); + ofPopStyle(); + + // highlight selected surface + drawSelectedSurfaceHighlight(); + + // hilight selected surface texture + drawSelectedSurfaceTextureHighlight(); + + // draw texture editing GUI on top + textureEditor.draw(); + + } else if (guiMode == GuiMode::PROJECTION_MAPPING) { + // draw projection surfaces first + surfaceManager->draw(); + + // highlight selected surface + drawSelectedSurfaceHighlight(); + + // draw projection mapping editing gui + projectionEditor.draw(); + + } else if (guiMode == GuiMode::SOURCE_SELECTION) { + // draw projection surfaces first + surfaceManager->draw(); + + // highlight selected surface + drawSelectedSurfaceHighlight(); + + sourcesEditor.draw(); + } +} + +void SurfaceManagerGui::mousePressed(ofMouseEventArgs& args) { + if (guiMode == GuiMode::NONE) { + return; + } else if (guiMode == GuiMode::TEXTURE_MAPPING) { + bool bSurfaceSelected = false; + + CircleJoint* hitJoint = + textureEditor.hitTestJoints(ofVec2f(args.x, args.y)); + if (hitJoint != NULL) { + textureEditor.unselectAllJoints(); + hitJoint->select(); + hitJoint->startDrag(); + bSurfaceSelected = true; + } else { + textureEditor.unselectAllJoints(); + } + + if (surfaceManager->getSelectedSurface() != NULL && !bSurfaceSelected) { + // hittest texture area to see if we are hitting the texture surface + if (surfaceManager->getSelectedSurface()->getTextureHitArea().inside( + args.x, args.y)) { + clickPosition = ofVec2f(args.x, args.y); + startDrag(); + } + } + + } else if (guiMode == GuiMode::PROJECTION_MAPPING) { + bool bSurfaceSelected = false; + + CircleJoint* hitJoint = + projectionEditor.hitTestJoints(ofVec2f(args.x, args.y)); + if (hitJoint != NULL) { + projectionEditor.unselectAllJoints(); + hitJoint->select(); + hitJoint->startDrag(); + bSurfaceSelected = true; + } + + // attempt to select surface, loop from end to beginning + if (!bSurfaceSelected) { + for (int i = surfaceManager->size() - 1; i >= 0; i--) { + if (surfaceManager->getSurface(i)->hitTest(ofVec2f(args.x, args.y))) { + projectionEditor.clearJoints(); + surfaceManager->selectSurface(i); + projectionEditor.createJoints(); + bSurfaceSelected = true; + break; + } + } + } + + if (bSurfaceSelected && hitJoint == NULL) { + // if not hitting the joints, start drag only if we have a selected + // surface + clickPosition = ofVec2f(args.x, args.y); + startDrag(); + } + + if (!bSurfaceSelected) { + // unselect if no surface selected + projectionEditor.clearJoints(); + surfaceManager->deselectSurface(); + } + } else if (guiMode == GuiMode::SOURCE_SELECTION) { + } +} + +void SurfaceManagerGui::mouseReleased(ofMouseEventArgs& args) { + stopDrag(); + projectionEditor.stopDragJoints(); + textureEditor.stopDragJoints(); +} + +void SurfaceManagerGui::mouseDragged(ofMouseEventArgs& args) { + if (bDrag) { + ofVec2f mousePosition = ofVec2f(args.x, args.y); + ofVec2f distance = mousePosition - clickPosition; + + if (guiMode == GuiMode::PROJECTION_MAPPING) { + // add this distance to all vertices in surface + projectionEditor.moveSelectedSurface(distance); + } else if (guiMode == GuiMode::TEXTURE_MAPPING) { + textureEditor.moveTexCoords(distance); + } + clickPosition = mousePosition; + } +} + +void SurfaceManagerGui::setSurfaceManager(SurfaceManager* newSurfaceManager) { + surfaceManager = newSurfaceManager; + projectionEditor.setSurfaceManager(surfaceManager); + sourcesEditor.setSurfaceManager(surfaceManager); +} + +void SurfaceManagerGui::setMode(int newGuiMode) { + if (newGuiMode != GuiMode::NONE && newGuiMode != GuiMode::TEXTURE_MAPPING && + newGuiMode != GuiMode::PROJECTION_MAPPING && + newGuiMode != GuiMode::SOURCE_SELECTION) { + throw std::runtime_error("Trying to set invalid mode."); + } + + if (newGuiMode == GuiMode::NONE) { + ofHideCursor(); + } else { + ofShowCursor(); + } + + guiMode = newGuiMode; + + if (guiMode == GuiMode::SOURCE_SELECTION) { + sourcesEditor.enable(); + string sourceName = surfaceManager->getSelectedSurfaceSourceName(); + sourcesEditor.selectImageSourceRadioButton(sourceName); + } else { + sourcesEditor.disable(); + } + + if (guiMode == GuiMode::TEXTURE_MAPPING) { + textureEditor.enable(); + // refresh texture editor surface reference + textureEditor.setSurface(surfaceManager->getSelectedSurface()); + } else { + textureEditor.disable(); + } + + if (guiMode == GuiMode::PROJECTION_MAPPING) { + projectionEditor.enable(); + } else { + projectionEditor.disable(); + } +} + +void SurfaceManagerGui::drawSelectedSurfaceHighlight() { + if (surfaceManager->getSelectedSurface() == NULL) return; + + ofPolyline line = surfaceManager->getSelectedSurface()->getHitArea(); + + ofPushStyle(); + ofSetLineWidth(1); + ofSetColor(255, 255, 255, 255); + line.draw(); + ofPopStyle(); +} + +void SurfaceManagerGui::drawSelectedSurfaceTextureHighlight() { + if (surfaceManager->getSelectedSurface() == NULL) return; + + ofPolyline line = surfaceManager->getSelectedSurface()->getTextureHitArea(); + + ofPushStyle(); + ofSetLineWidth(1); + ofSetColor(255, 255, 0, 255); + line.draw(); + ofPopStyle(); +} + +void SurfaceManagerGui::startDrag() { bDrag = true; } + +void SurfaceManagerGui::stopDrag() { bDrag = false; } +} +} \ No newline at end of file diff --git a/src/SurfaceManagerGui.h b/src/SurfaceManagerGui.h new file mode 100644 index 0000000..1c62cf6 --- /dev/null +++ b/src/SurfaceManagerGui.h @@ -0,0 +1,46 @@ +#pragma once + +// I'm starting to think, maybe we should use ofxStateMachine here. +// Would make sense. TODO later. + +#include "ofEvents.h" +#include "ofGraphics.h" + +#include "SurfaceManager.h" +#include "TextureEditor.h" +#include "ProjectionEditor.h" +#include "SourcesEditor.h" +#include "GuiMode.h" + +namespace ofx { +namespace piMapper { +class SurfaceManagerGui { + public: + SurfaceManagerGui(); + ~SurfaceManagerGui(); + + void registerMouseEvents(); + void unregisterMouseEvents(); + + void draw(); + void mousePressed(ofMouseEventArgs& args); + void mouseReleased(ofMouseEventArgs& args); + void mouseDragged(ofMouseEventArgs& args); + void setSurfaceManager(SurfaceManager* newSurfaceManager); + void setMode(int newGuiMode); + void drawSelectedSurfaceHighlight(); + void drawSelectedSurfaceTextureHighlight(); + void startDrag(); + void stopDrag(); + + private: + SurfaceManager* surfaceManager; + TextureEditor textureEditor; + ProjectionEditor projectionEditor; + SourcesEditor sourcesEditor; + int guiMode; + bool bDrag; + ofVec2f clickPosition; +}; +} +} \ No newline at end of file diff --git a/src/SurfaceType.h b/src/SurfaceType.h new file mode 100755 index 0000000..9db0cca --- /dev/null +++ b/src/SurfaceType.h @@ -0,0 +1,9 @@ +#pragma once + +namespace ofx { +namespace piMapper { +struct SurfaceType { + enum { TRIANGLE_SURFACE, QUAD_SURFACE }; +}; +} +} \ No newline at end of file diff --git a/src/TextureEditor.cpp b/src/TextureEditor.cpp new file mode 100755 index 0000000..feb0728 --- /dev/null +++ b/src/TextureEditor.cpp @@ -0,0 +1,189 @@ +#include "TextureEditor.h" + +namespace ofx { +namespace piMapper { +TextureEditor::TextureEditor() { + clear(); + enable(); +} + +TextureEditor::~TextureEditor() { + clear(); + disable(); +} + +void TextureEditor::registerAppEvents() { + ofAddListener(ofEvents().update, this, &TextureEditor::update); +} + +void TextureEditor::unregisterAppEvents() { + ofRemoveListener(ofEvents().update, this, &TextureEditor::update); +} + +void TextureEditor::registerKeyEvents() { + ofAddListener(ofEvents().keyPressed, this, &TextureEditor::keyPressed); + ofAddListener(ofEvents().keyReleased, this, &TextureEditor::keyReleased); +} + +void TextureEditor::unregisterKeyEvents() { + ofRemoveListener(ofEvents().keyPressed, this, &TextureEditor::keyPressed); + ofRemoveListener(ofEvents().keyReleased, this, &TextureEditor::keyReleased); +} + +void TextureEditor::enable() { + registerAppEvents(); + registerKeyEvents(); + bShiftKeyDown = false; +} + +void TextureEditor::disable() { + unregisterAppEvents(); + unregisterKeyEvents(); +} + +void TextureEditor::update(ofEventArgs& args) { + if (surface == NULL) return; + + // update surface if one of the joints is being dragged + ofVec2f textureSize = ofVec2f(surface->getTexture()->getWidth(), + surface->getTexture()->getHeight()); + for (int i = 0; i < joints.size(); i++) { + if (joints[i]->isDragged() || joints[i]->isSelected()) { + // update vertex to new location + surface->setTexCoord(i, joints[i]->position / textureSize); + break; + } + } +} + +void TextureEditor::keyPressed(ofKeyEventArgs& args) { + int key = args.key; + float moveStep; + + if (bShiftKeyDown) + moveStep = 10.0f; + else + moveStep = 0.5f; + + switch (key) { + case OF_KEY_LEFT: + moveSelection(ofVec2f(-moveStep, 0.0f)); + break; + case OF_KEY_RIGHT: + moveSelection(ofVec2f(moveStep, 0.0f)); + break; + case OF_KEY_UP: + moveSelection(ofVec2f(0.0f, -moveStep)); + break; + case OF_KEY_DOWN: + moveSelection(ofVec2f(0.0f, moveStep)); + break; + case OF_KEY_SHIFT: + bShiftKeyDown = true; + break; + } +} + +void TextureEditor::keyReleased(ofKeyEventArgs& args) { + int key = args.key; + switch (key) { + case OF_KEY_SHIFT: + bShiftKeyDown = false; + break; + } +} + +void TextureEditor::draw() { + if (surface == NULL) return; + + drawJoints(); +} + +void TextureEditor::drawJoints() { + for (int i = 0; i < joints.size(); i++) { + joints[i]->draw(); + } +} + +void TextureEditor::setSurface(BaseSurface* newSurface) { + surface = newSurface; + createJoints(); +} + +void TextureEditor::clear() { + surface = NULL; + clearJoints(); +} + +void TextureEditor::createJoints() { + if (surface == NULL) return; + clearJoints(); + vector& texCoords = surface->getTexCoords(); + ofVec2f textureSize = ofVec2f(surface->getTexture()->getWidth(), + surface->getTexture()->getHeight()); + + for (int i = 0; i < texCoords.size(); i++) { + joints.push_back(new CircleJoint()); + joints.back()->position = texCoords[i] * textureSize; + } +} + +void TextureEditor::clearJoints() { + while (joints.size()) { + delete joints.back(); + joints.pop_back(); + } +} + +void TextureEditor::unselectAllJoints() { + for (int i = 0; i < joints.size(); i++) { + joints[i]->unselect(); + } +} + +void TextureEditor::moveTexCoords(ofVec2f by) { + if (surface == NULL) return; + vector& texCoords = surface->getTexCoords(); + ofVec2f textureSize = ofVec2f(surface->getTexture()->getWidth(), + surface->getTexture()->getHeight()); + for (int i = 0; i < texCoords.size(); i++) { + joints[i]->position += by; + texCoords[i] = joints[i]->position / textureSize; + } +} + +void TextureEditor::stopDragJoints() { + for (int i = 0; i < joints.size(); i++) { + joints[i]->stopDrag(); + } +} + +void TextureEditor::moveSelection(ofVec2f by) { + // check if joints selected + bool bJointSelected = false; + BaseJoint* selectedJoint; + for (int i = 0; i < joints.size(); i++) { + if (joints[i]->isSelected()) { + bJointSelected = true; + selectedJoint = joints[i]; + break; + } + } + + if (bJointSelected) { + selectedJoint->position += by; + } else { + moveTexCoords(by); + } +} + +CircleJoint* TextureEditor::hitTestJoints(ofVec2f pos) { + for (int i = 0; i < joints.size(); i++) { + if (joints[i]->hitTest(pos)) { + return joints[i]; + } + } + return NULL; +} +} +} \ No newline at end of file diff --git a/src/TextureEditor.h b/src/TextureEditor.h new file mode 100644 index 0000000..cae4383 --- /dev/null +++ b/src/TextureEditor.h @@ -0,0 +1,43 @@ +#pragma once + +#include "ofEvents.h" + +#include "BaseSurface.h" +#include "CircleJoint.h" + +namespace ofx { +namespace piMapper { +class TextureEditor { + public: + TextureEditor(); + ~TextureEditor(); + + void registerAppEvents(); + void unregisterAppEvents(); + void registerKeyEvents(); + void unregisterKeyEvents(); + void enable(); + void disable(); + + void update(ofEventArgs& args); + void keyPressed(ofKeyEventArgs& args); + void keyReleased(ofKeyEventArgs& args); + void draw(); + void drawJoints(); + void setSurface(BaseSurface* newSurface); + void clear(); + void createJoints(); + void clearJoints(); + void unselectAllJoints(); + void moveTexCoords(ofVec2f by); + void stopDragJoints(); + void moveSelection(ofVec2f by); + CircleJoint* hitTestJoints(ofVec2f pos); + + private: + BaseSurface* surface; + vector joints; + bool bShiftKeyDown; +}; +} +} \ No newline at end of file diff --git a/src/TriangleSurface.cpp b/src/TriangleSurface.cpp new file mode 100644 index 0000000..b5d816e --- /dev/null +++ b/src/TriangleSurface.cpp @@ -0,0 +1,139 @@ +#include "TriangleSurface.h" + +namespace ofx { +namespace piMapper { +TriangleSurface::TriangleSurface() { + cout << "TriangleSurface constructor." << endl; + setup(); +} + +TriangleSurface::~TriangleSurface() { + cout << "TriangleSurface destructor." << endl; +} + +void TriangleSurface::setup() { + // Create 3 points for the triangle + ofVec2f p1 = ofVec2f(ofGetWidth() / 2.0f, 0); + ofVec2f p2 = ofVec2f(ofVec2f(0, ofGetHeight())); + ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); + + // Create 3 point for the texture coordinates + ofVec2f t1 = ofVec2f(0.5f, 0); + ofVec2f t2 = ofVec2f(0, 1.0f); + ofVec2f t3 = ofVec2f(1, 1.0f); + + setup(p1, p2, p3, t1, t2, t3, texture); +} + +void TriangleSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, + ofVec2f t2, ofVec2f t3, ofTexture* texturePtr) { + // Assign texture + texture = texturePtr; + + // Clear mesh + mesh.clear(); + + // Create a surface with the points + mesh.addVertex(p1); + mesh.addVertex(p2); + mesh.addVertex(p3); + + // Add texture coordinates + mesh.addTexCoord(t1); + mesh.addTexCoord(t2); + mesh.addTexCoord(t3); +} + +void TriangleSurface::draw() { + texture->bind(); + mesh.draw(); + texture->unbind(); +} + +void TriangleSurface::setVertex(int index, ofVec2f p) { + if (index > 2) { + ofLog() << "Vertex with this index does not exist: " << index << endl; + return; + } + + mesh.setVertex(index, p); +} + +void TriangleSurface::setTexCoord(int index, ofVec2f t) { + if (index > 2) { + ofLog() << "Texture coordinate with this index does not exist: " << index + << endl; + return; + } + + mesh.setTexCoord(index, t); +} + +void TriangleSurface::moveBy(ofVec2f v) { + vector& vertices = getVertices(); + for (int i = 0; i < vertices.size(); i++) { + vertices[i] += v; + } +} + +int TriangleSurface::getType() { return SurfaceType::TRIANGLE_SURFACE; } + +bool TriangleSurface::hitTest(ofVec2f p) { + // Construct ofPolyline from vertices + ofPolyline line = getHitArea(); + + if (line.inside(p.x, p.y)) { + return true; + } else { + return false; + } +} + +ofVec2f TriangleSurface::getVertex(int index) { + if (index > 2) { + ofLog() << "Vertex with this index does not exist: " << index << endl; + throw std::runtime_error("Vertex index out of bounds."); + } + + ofVec3f vert = mesh.getVertex(index); + return ofVec2f(vert.x, vert.y); +} + +ofVec2f TriangleSurface::getTexCoord(int index) { + if (index > 2) { + throw std::runtime_error("Texture coordinate index out of bounds."); + } + + return mesh.getTexCoord(index); +} + +ofPolyline TriangleSurface::getHitArea() { + ofPolyline line; + line.addVertex(ofPoint(mesh.getVertex(0).x, mesh.getVertex(0).y)); + line.addVertex(ofPoint(mesh.getVertex(1).x, mesh.getVertex(1).y)); + line.addVertex(ofPoint(mesh.getVertex(2).x, mesh.getVertex(2).y)); + line.close(); + + return line; +} + +ofPolyline TriangleSurface::getTextureHitArea() { + ofPolyline line; + vector& texCoords = mesh.getTexCoords(); + ofVec2f textureSize = ofVec2f(texture->getWidth(), texture->getHeight()); + for (int i = 0; i < texCoords.size(); i++) { + line.addVertex(ofPoint(texCoords[i] * textureSize)); + } + line.close(); + + return line; +} + +vector& TriangleSurface::getVertices() { + // return only joint vertices + return mesh.getVertices(); +} + +vector& TriangleSurface::getTexCoords() { return mesh.getTexCoords(); } +} +} \ No newline at end of file diff --git a/src/TriangleSurface.h b/src/TriangleSurface.h new file mode 100644 index 0000000..c3e968c --- /dev/null +++ b/src/TriangleSurface.h @@ -0,0 +1,32 @@ +#pragma once + +#include "ofMain.h" +#include "BaseSurface.h" +#include "SurfaceType.h" + +namespace ofx { +namespace piMapper { +class TriangleSurface : public BaseSurface { + public: + TriangleSurface(); + ~TriangleSurface(); + + void setup(); + void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, ofVec2f t2, + ofVec2f t3, ofTexture* texturePtr); + void draw(); + void setVertex(int index, ofVec2f p); + void setTexCoord(int index, ofVec2f t); + void moveBy(ofVec2f v); + + int getType(); + bool hitTest(ofVec2f p); + ofVec2f getVertex(int index); + ofVec2f getTexCoord(int index); + ofPolyline getHitArea(); + ofPolyline getTextureHitArea(); + vector& getVertices(); + vector& getTexCoords(); +}; +} +} \ No newline at end of file diff --git a/src/ofxBaseJoint.cpp b/src/ofxBaseJoint.cpp deleted file mode 100644 index 22d147d..0000000 --- a/src/ofxBaseJoint.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "ofxBaseJoint.h" - -ofxBaseJoint::ofxBaseJoint() -{ - setDefaultColors(); - setDefaultProperties(); - registerMouseEvents(); -} - -ofxBaseJoint::~ofxBaseJoint() -{ - unregisterMouseEvents(); -} - -void ofxBaseJoint::registerMouseEvents() -{ - ofAddListener(ofEvents().mousePressed, this, &ofxBaseJoint::mousePressed); - ofAddListener(ofEvents().mouseDragged, this, &ofxBaseJoint::mouseDragged); -} - -void ofxBaseJoint::unregisterMouseEvents() -{ - ofRemoveListener(ofEvents().mousePressed, this, &ofxBaseJoint::mousePressed); - ofRemoveListener(ofEvents().mouseDragged, this, &ofxBaseJoint::mouseDragged); -} - -void ofxBaseJoint::mousePressed(ofMouseEventArgs& args) -{ - if ( hitTest(ofVec2f(args.x, args.y)) ) { - //selected = true; - clickDistance = position - ofVec2f(args.x, args.y); - //startDrag(); - } -} - -void ofxBaseJoint::mouseReleased(int x, int y, int button) -{ - stopDrag(); -} - -void ofxBaseJoint::mouseDragged(ofMouseEventArgs& args) -{ - if ( !bDrag ) return; - position = ofVec2f(args.x, args.y) + clickDistance; -} - -void ofxBaseJoint::startDrag() -{ - bDrag = true; -} - -void ofxBaseJoint::stopDrag() -{ - bDrag = false; -} - -void ofxBaseJoint::select() -{ - selected = true; -} - -void ofxBaseJoint::unselect() -{ - selected = false; -} - -void ofxBaseJoint::setClickDistance(ofVec2f newClickDistance) -{ - clickDistance = newClickDistance; -} - -bool ofxBaseJoint::isDragged() -{ - return bDrag; -} - -bool ofxBaseJoint::isSelected() -{ - return selected; -} - -void ofxBaseJoint::setDefaultColors() -{ - fillColor = ofColor(0, 255, 255, 0); - strokeColor = ofColor(255, 255, 255); - fillColorSelected = ofColor(255, 255, 0, 0); - strokeColorSelected = ofColor(255, 0, 0); -} - -void ofxBaseJoint::setDefaultProperties() -{ - enabled = true; - visible = true; - position = ofVec2f(20.0f, 20.0f); - clickDistance = ofVec2f(0.0f, 0.0f); - bDrag = false; - selected = false; - strokeWidth = 1.5f; -} \ No newline at end of file diff --git a/src/ofxBaseJoint.h b/src/ofxBaseJoint.h deleted file mode 100644 index d3decb7..0000000 --- a/src/ofxBaseJoint.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef H_OFX_BASE_JOINT -#define H_OFX_BASE_JOINT - -#include "ofMain.h" - -class ofxBaseJoint { -public: - ofxBaseJoint(); - ~ofxBaseJoint(); - - void registerMouseEvents(); - void unregisterMouseEvents(); - - ofVec2f position; - bool enabled; - bool visible; - bool selected; - - void mousePressed(ofMouseEventArgs& args); - void mouseReleased(int x, int y, int button); - void mouseDragged(ofMouseEventArgs& args); - void startDrag(); - void stopDrag(); - void select(); - void unselect(); - void setClickDistance(ofVec2f newClickDistance); - bool isDragged(); - bool isSelected(); - - virtual void update(){}; - virtual void draw(){}; - virtual bool hitTest(ofVec2f position){}; - -protected: - ofColor fillColor; - ofColor strokeColor; - ofColor fillColorSelected; - ofColor strokeColorSelected; - float strokeWidth; - ofVec2f clickDistance; // How far from the center of the joint the user has clicked? - bool bDrag; - -private: - void setDefaultColors(); - void setDefaultProperties(); -}; - -#endif diff --git a/src/ofxBaseSurface.cpp b/src/ofxBaseSurface.cpp deleted file mode 100644 index 67db7ef..0000000 --- a/src/ofxBaseSurface.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "ofxBaseSurface.h" - -ofxBaseSurface::ofxBaseSurface() -{ - ofEnableNormalizedTexCoords(); - createDefaultTexture(); -} - -void ofxBaseSurface::createDefaultTexture() -{ - ofPixels pixels; - pixels.allocate(500, 500, 1); - for ( int i=0; igetWidth(), 0.0f)); - texMesh.addVertex(position + ofVec2f(texture->getWidth(), texture->getHeight())); - texMesh.addVertex(position + ofVec2f(0.0f, texture->getHeight())); - texMesh.addTriangle(0, 2, 3); - texMesh.addTriangle(0, 1, 2); - texMesh.addTexCoord(ofVec2f(0.0f, 0.0f)); - texMesh.addTexCoord(ofVec2f(1.0f, 0.0f)); - texMesh.addTexCoord(ofVec2f(1.0f, 1.0f)); - texMesh.addTexCoord(ofVec2f(0.0f, 1.0f)); - texture->bind(); - texMesh.draw(); - texture->unbind(); -} - -void ofxBaseSurface::setTexture(ofTexture *texturePtr) -{ - texture = texturePtr; -} - -ofTexture* ofxBaseSurface::getTexture() -{ - return texture; -} - -ofTexture* ofxBaseSurface::getDefaultTexture() -{ - return &defaultTexture; -} \ No newline at end of file diff --git a/src/ofxBaseSurface.h b/src/ofxBaseSurface.h deleted file mode 100644 index 9cd98b6..0000000 --- a/src/ofxBaseSurface.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef H_OFX_BASE_SURFACE -#define H_OFX_BASE_SURFACE - -#include "ofMain.h" -#include - -using namespace std; - -class ofxBaseSurface -{ -public: - ofxBaseSurface(); - virtual void setup(){}; - virtual void draw(){}; - virtual void setVertex(int index, ofVec2f p){}; - virtual void setTexCoord(int index, ofVec2f t){}; - virtual void moveBy(ofVec2f v){}; - virtual int getType(){}; - virtual bool hitTest(ofVec2f p){}; - virtual ofPolyline getHitArea(){}; - virtual ofPolyline getTextureHitArea(){}; - virtual vector& getVertices(){}; - virtual vector& getTexCoords(){}; - - // Draws a texture using ofMesh - void drawTexture(ofVec2f position); - void setTexture(ofTexture* texturePtr); - - ofTexture* getTexture(); - ofTexture* getDefaultTexture(); - -protected: - ofMesh mesh; - ofTexture* texture; - ofTexture defaultTexture; - - void createDefaultTexture(); -}; - -#endif \ No newline at end of file diff --git a/src/ofxCircleJoint.cpp b/src/ofxCircleJoint.cpp deleted file mode 100644 index 4abbc5c..0000000 --- a/src/ofxCircleJoint.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "ofxCircleJoint.h" - -ofxCircleJoint::ofxCircleJoint() -{ - setDefaultProperties(); -} - -void ofxCircleJoint::update() -{ - if (!enabled) return; -} - -void ofxCircleJoint::draw() -{ - if (!visible) return; - if (!enabled) return; - - ofPushStyle(); - ofFill(); - - if ( selected ) { - ofSetColor(fillColorSelected); - } else { - ofSetColor(fillColor); - } - - ofCircle(position.x, position.y, radius); - ofNoFill(); - - if ( selected ) { - ofSetColor(strokeColorSelected); - } else { - ofSetColor(strokeColor); - } - - ofSetLineWidth(strokeWidth); - ofCircle(position.x, position.y, radius); - ofPopStyle(); -} - -void ofxCircleJoint::setDefaultProperties() -{ - radius = 10.0f; -} - -bool ofxCircleJoint::hitTest(ofVec2f pos) -{ - float distance = position.distance(pos); - if ( distance < radius ) return true; - else return false; -} \ No newline at end of file diff --git a/src/ofxCircleJoint.h b/src/ofxCircleJoint.h deleted file mode 100644 index f3016e9..0000000 --- a/src/ofxCircleJoint.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef H_OFX_CIRCLE_JOINT -#define H_OFX_CIRCLE_JOINT - -#include "ofMain.h" -#include "ofxBaseJoint.h" - -class ofxCircleJoint : public ofxBaseJoint -{ -public: - ofxCircleJoint(); - - void update(); - void draw(); - bool hitTest(ofVec2f position); - -private: - float radius; - - void setDefaultProperties(); -}; - -#endif \ No newline at end of file diff --git a/src/ofxEditorType.h b/src/ofxEditorType.h deleted file mode 100644 index cc0c1c8..0000000 --- a/src/ofxEditorType.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef H_OFX_EDITOR_TYPE -#define H_OFX_EDITOR_TYPE - -struct ofxEditorType -{ - enum { - TEXTURE, - PROJECTION - }; -}; - -#endif \ No newline at end of file diff --git a/src/ofxGuiMode.h b/src/ofxGuiMode.h deleted file mode 100644 index c60fe71..0000000 --- a/src/ofxGuiMode.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef H_OFX_GUI_MODE -#define H_OFX_GUI_MODE - -struct ofxGuiMode -{ - enum { - NONE, - TEXTURE_MAPPING, - PROJECTION_MAPPING, - SOURCE_SELECTION - }; -}; - -#endif \ No newline at end of file diff --git a/src/ofxPiMapper.h b/src/ofxPiMapper.h index 4f65bd2..b0b5fea 100644 --- a/src/ofxPiMapper.h +++ b/src/ofxPiMapper.h @@ -1,7 +1,4 @@ -#ifndef H_OFX_PI_MAPPER -#define H_OFX_PI_MAPPER +#pragma once -#include "ofxSurfaceManager.h" -#include "ofxSurfaceManagerGui.h" - -#endif \ No newline at end of file +#include "SurfaceManager.h" +#include "SurfaceManagerGui.h" \ No newline at end of file diff --git a/src/ofxProjectionEditor.cpp b/src/ofxProjectionEditor.cpp deleted file mode 100644 index 7560ba8..0000000 --- a/src/ofxProjectionEditor.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include "ofxProjectionEditor.h" - -ofxProjectionEditor::ofxProjectionEditor() -{ - surfaceManager = NULL; - bShiftKeyDown = false; - fSnapDistance = 10.0f; - enable(); -} - -ofxProjectionEditor::~ofxProjectionEditor() -{ - clearJoints(); - surfaceManager = NULL; - disable(); -} - -void ofxProjectionEditor::registerAppEvents() -{ - ofAddListener(ofEvents().update, this, &ofxProjectionEditor::update); - ofAddListener(ofEvents().messageEvent, this, &ofxProjectionEditor::gotMessage); -} - -void ofxProjectionEditor::unregisterAppEvents() -{ - ofRemoveListener(ofEvents().update, this, &ofxProjectionEditor::update); - ofRemoveListener(ofEvents().messageEvent, this, &ofxProjectionEditor::gotMessage); -} - -void ofxProjectionEditor::registerMouseEvents() -{ - ofAddListener(ofEvents().mouseDragged, this, &ofxProjectionEditor::mouseDragged); -} - -void ofxProjectionEditor::unregisterMouseEvents() -{ - ofRemoveListener(ofEvents().mouseDragged, this, &ofxProjectionEditor::mouseDragged); -} - -void ofxProjectionEditor::registerKeyEvents() -{ - ofAddListener(ofEvents().keyPressed, this, &ofxProjectionEditor::keyPressed); - ofAddListener(ofEvents().keyReleased, this, &ofxProjectionEditor::keyReleased); -} - -void ofxProjectionEditor::unregisterKeyEvents() -{ - ofRemoveListener(ofEvents().keyPressed, this, &ofxProjectionEditor::keyPressed); - ofRemoveListener(ofEvents().keyReleased, this, &ofxProjectionEditor::keyReleased); -} - -void ofxProjectionEditor::enable() -{ - registerAppEvents(); - registerMouseEvents(); - registerKeyEvents(); -} - -void ofxProjectionEditor::disable() -{ - unregisterAppEvents(); - unregisterMouseEvents(); - unregisterKeyEvents(); -} - -void ofxProjectionEditor::update(ofEventArgs &args) -{ - // update surface if one of the joints is being dragged - for ( int i=0; iisDragged() || joints[i]->isSelected() ) { - - if ( surfaceManager->getSelectedSurface() != NULL ) { - // update vertex to new location - surfaceManager->getSelectedSurface()->setVertex(i, joints[i]->position); - } else { - // clear joints if there is no surface selected - // as the remove selected surface in the surface manager - // is not supposed to access joints here - joints.clear(); - } - break; - } - } -} - -void ofxProjectionEditor::draw() -{ - if ( surfaceManager == NULL ) return; - if ( surfaceManager->getSelectedSurface() == NULL ) return; - if ( joints.size() <= 0 ) createJoints(); - drawJoints(); -} - -void ofxProjectionEditor::mouseDragged(ofMouseEventArgs &args) -{ - ofVec2f mousePosition = ofVec2f(args.x, args.y); - - // Collect all vertices of the projection surfaces - vector allVertices; - for ( int i=0; isize(); i++ ) { - ofxBaseSurface* surface = surfaceManager->getSurface(i); - if ( surface == surfaceManager->getSelectedSurface() ) { - continue; // Don't add vertices of selected surface - } - for ( int j=0; jgetVertices().size(); j++ ) { - allVertices.push_back(&surface->getVertices()[j]); - } - } - - // Snap currently dragged joint to nearest vertex - for ( int i=0; iisDragged() ) { - // Snap it! - for ( int j=0; jposition = *allVertices[j]; - ofVec2f clickDistance = joints[i]->position - ofVec2f(args.x, args.y); - joints[i]->setClickDistance(clickDistance); - break; - } - } - } - } -} - -void ofxProjectionEditor::keyPressed(ofKeyEventArgs &args) -{ - int key = args.key; - float moveStep; - - if (bShiftKeyDown) moveStep = 10.0f; - else moveStep = 0.5f; - - switch (key) { - case OF_KEY_LEFT: moveSelection(ofVec2f(-moveStep,0.0f)); break; - case OF_KEY_RIGHT: moveSelection(ofVec2f(moveStep,0.0f)); break; - case OF_KEY_UP: moveSelection(ofVec2f(0.0f,-moveStep)); break; - case OF_KEY_DOWN: moveSelection(ofVec2f(0.0f,moveStep)); break; - case OF_KEY_SHIFT: bShiftKeyDown = true; break; - } -} - -void ofxProjectionEditor::keyReleased(ofKeyEventArgs &args) -{ - int key = args.key; - switch (key) { - case OF_KEY_SHIFT: bShiftKeyDown = false; break; - } -} - -void ofxProjectionEditor::gotMessage(ofMessage& msg) -{ - if (msg.message == "surfaceSelected") { - // refresh gui - clearJoints(); - createJoints(); - } -} - -void ofxProjectionEditor::setSurfaceManager(ofxSurfaceManager *newSurfaceManager) -{ - surfaceManager = newSurfaceManager; -} - -void ofxProjectionEditor::clearJoints() -{ - while ( joints.size() ) { - delete joints.back(); - joints.pop_back(); - } -} - -void ofxProjectionEditor::createJoints() -{ - if ( surfaceManager == NULL ) return; - clearJoints(); - - if ( surfaceManager->getSelectedSurface() == NULL ) { - ofLog(OF_LOG_WARNING, "Trying to create joints while no surface selected."); - return; - } - - vector& vertices = surfaceManager->getSelectedSurface()->getVertices(); - - for ( int i=0; iposition = ofVec2f(vertices[i].x, vertices[i].y); - } -} - -void ofxProjectionEditor::updateJoints() -{ - vector& vertices = surfaceManager->getSelectedSurface()->getVertices(); - for ( int i=0; iposition = ofVec2f(vertices[i].x, vertices[i].y); - } -} - -void ofxProjectionEditor::unselectAllJoints() -{ - for ( int i=0; iunselect(); - } -} - -void ofxProjectionEditor::moveSelectedSurface(ofVec2f by) -{ - if ( surfaceManager == NULL ) return; - if ( surfaceManager->getSelectedSurface() == NULL ) return; - surfaceManager->getSelectedSurface()->moveBy(by); - /*vector& vertices = surfaceManager->getSelectedSurface()->getVertices(); - for (int i=0; istopDrag(); - } -} - -void ofxProjectionEditor::moveSelection(ofVec2f by) -{ - // check if joints selected - bool bJointSelected = false; - ofxBaseJoint* selectedJoint; - for ( int i=0; iisSelected()) { - bJointSelected = true; - selectedJoint = joints[i]; - break; - } - } - - if ( bJointSelected ) { - selectedJoint->position += by; - } else { - moveSelectedSurface(by); - } -} - -void ofxProjectionEditor::setSnapDistance(float newSnapDistance) -{ - fSnapDistance = newSnapDistance; -} - -ofxCircleJoint* ofxProjectionEditor::hitTestJoints(ofVec2f pos) -{ - for ( int i=0; ihitTest(pos) ){ - return joints[i]; - } - } - return NULL; -} - -void ofxProjectionEditor::drawJoints() -{ - for ( int i=0; idraw(); - } -} \ No newline at end of file diff --git a/src/ofxProjectionEditor.h b/src/ofxProjectionEditor.h deleted file mode 100755 index c4b95ec..0000000 --- a/src/ofxProjectionEditor.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef H_OFX_PROJECTION_EDITOR -#define H_OFX_PROJECTION_EDITOR - -#include "ofxSurfaceManager.h" -#include "ofxCircleJoint.h" - -class ofxProjectionEditor -{ -public: - ofxProjectionEditor(); - ~ofxProjectionEditor(); - - void registerAppEvents(); - void unregisterAppEvents(); - void registerMouseEvents(); - void unregisterMouseEvents(); - void registerKeyEvents(); - void unregisterKeyEvents(); - - void enable(); - void disable(); - - void update(ofEventArgs& args); - void draw(); - void mouseDragged(ofMouseEventArgs& args); - void keyPressed(ofKeyEventArgs& args); - void keyReleased(ofKeyEventArgs& args); - void gotMessage(ofMessage& msg); - void setSurfaceManager(ofxSurfaceManager* newSurfaceManager); - void clearJoints(); - void createJoints(); - void updateJoints(); - void unselectAllJoints(); - void moveSelectedSurface(ofVec2f by); - void stopDragJoints(); - void updateVertices(); - void moveSelection(ofVec2f by); - void setSnapDistance(float newSnapDistance); - ofxCircleJoint* hitTestJoints(ofVec2f pos); - -private: - ofxSurfaceManager* surfaceManager; - vector joints; - bool bShiftKeyDown; - float fSnapDistance; - - void drawJoints(); -}; - -#endif \ No newline at end of file diff --git a/src/ofxQuadSurface.cpp b/src/ofxQuadSurface.cpp deleted file mode 100644 index 91f296b..0000000 --- a/src/ofxQuadSurface.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include "ofxQuadSurface.h" - -ofxQuadSurface::ofxQuadSurface() -{ - cout << "ofxQuadSurface constructor." << endl; - setup(); -} - -ofxQuadSurface::~ofxQuadSurface() -{ - cout << "ofxQuadSurface destructor." << endl; -} - -void ofxQuadSurface::setup() -{ - // Create 4 points for the 2 triangles - ofVec2f p1 = ofVec2f(0, 0); - ofVec2f p2 = ofVec2f(0, ofGetHeight()); - ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); - ofVec2f p4 = ofVec2f(ofGetWidth(), 0); - - // Create 4 point for the texture coordinates - ofVec2f t1 = ofVec2f(ofVec2f(0.0f, 0.0f)); - ofVec2f t2 = ofVec2f(ofVec2f(1.0f, 0.0f)); - ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f)); - ofVec2f t4 = ofVec2f(ofVec2f(0.0f, 1.0f)); - - setup( p1, p2, p3, p4, t1, t2, t3, t4, texture ); -} - -void ofxQuadSurface::setup( ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, - ofVec2f t1, ofVec2f t2, ofVec2f t3, ofVec2f t4, ofTexture* texturePtr ) -{ - // Assign texture - texture = texturePtr; - - // Clear mesh - mesh.clear(); - - // Create a surface with the points - mesh.addVertex( p1 ); - mesh.addVertex( p2 ); - mesh.addVertex( p3 ); - mesh.addVertex( p4 ); - - // Add 2 triangles - mesh.addTriangle(0, 2, 3); - mesh.addTriangle(0, 1, 2); - - // Add texture coordinates - mesh.addTexCoord(t1); - mesh.addTexCoord(t2); - mesh.addTexCoord(t3); - mesh.addTexCoord(t4); - - // Pure GL setup - // indices - quadIndices[0] = 0; - quadIndices[1] = 1; - quadIndices[2] = 2; - quadIndices[3] = 0; - quadIndices[4] = 2; - quadIndices[5] = 3; - //tex coords (those are alway 0) - quadTexCoordinates[2] = 0; - quadTexCoordinates[6] = 0; - quadTexCoordinates[10] = 0; - quadTexCoordinates[14] = 0; - - calculate4dTextureCoords(); -} - -void ofxQuadSurface::draw() -{ - /*if(mesh.haveVertsChanged() || mesh.haveTexCoordsChanged()){ - calculate4dTextureCoords(); - }*/ - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(4, GL_FLOAT, 0, quadTexCoordinates); - glVertexPointer(3, GL_FLOAT, 0, quadVertices); - - texture->bind(); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, quadIndices); - texture->unbind(); -} - -void ofxQuadSurface::setVertex(int index, ofVec2f p) -{ - if ( index > 3 ) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - return; - } - - mesh.setVertex(index, p); - calculate4dTextureCoords(); -} - -void ofxQuadSurface::setTexCoord(int index, ofVec2f t) -{ - if ( index > 3 ) { - ofLog() << "Texture coordinate with this index does not exist: " << index << endl; - return; - } - - mesh.setTexCoord(index, t); - calculate4dTextureCoords(); -} - -void ofxQuadSurface::moveBy(ofVec2f v) -{ - vector& vertices = getVertices(); - for (int i=0; i 3 ) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - throw std::runtime_error("Vertex index out of bounds."); - } - - ofVec3f vert = mesh.getVertex(index); - return ofVec2f(vert.x, vert.y); -} - -ofVec2f ofxQuadSurface::getTexCoord(int index) -{ - if (index > 3) { - throw std::runtime_error("Texture coordinate index out of bounds."); - } - - return mesh.getTexCoord(index); -} - -ofPolyline ofxQuadSurface::getHitArea() -{ - ofPolyline line; - line.addVertex( ofPoint( mesh.getVertex(0).x, mesh.getVertex(0).y ) ); - line.addVertex( ofPoint( mesh.getVertex(1).x, mesh.getVertex(1).y ) ); - line.addVertex( ofPoint( mesh.getVertex(2).x, mesh.getVertex(2).y ) ); - line.addVertex( ofPoint( mesh.getVertex(3).x, mesh.getVertex(3).y ) ); - line.close(); - - return line; -} - -ofPolyline ofxQuadSurface::getTextureHitArea() -{ - ofPolyline line; - vector& texCoords = mesh.getTexCoords(); - ofVec2f textureSize = ofVec2f(texture->getWidth(), texture->getHeight()); - for ( int i=0; i& ofxQuadSurface::getVertices() -{ - // return only joint vertices - return mesh.getVertices(); -} - -vector& ofxQuadSurface::getTexCoords() -{ - - return mesh.getTexCoords(); -} - -void ofxQuadSurface::calculate4dTextureCoords() -{ - // Perspective Warping with OpenGL Fixed Pipeline and q coordinates - // see: - // http://www.reedbeta.com/blog/2012/05/26/quadrilateral-interpolation-part-1/ - // for information on the technique - // Pue OpenGL is used because the ofMesh sadly doesn't support ofVec4f as - // texture coordinates. - // calculate intersection point - ofVec3f p0 = mesh.getVertex(0); - ofVec3f p1 = mesh.getVertex(1); - ofVec3f p2 = mesh.getVertex(2); - ofVec3f p3 = mesh.getVertex(3); - - ofVec3f t0 = mesh.getTexCoord(0); - ofVec3f t1 = mesh.getTexCoord(1); - ofVec3f t2 = mesh.getTexCoord(2); - ofVec3f t3 = mesh.getTexCoord(3); - - ofPoint interSect; - ofLineSegmentIntersection(ofPoint(p0.x, p0.y), ofPoint(p2.x, p2.y), - ofPoint(p1.x, p1.y), ofPoint(p3.x, p3.y), - interSect); - ofVec3f interSecVec = ofVec3f(interSect.x, interSect.y, 0); - - // calculate distances to intersection point - float d0 = interSecVec.distance(p0); - float d1 = interSecVec.distance(p1); - float d2 = interSecVec.distance(p2); - float d3 = interSecVec.distance(p3); - - // vertices - // top left corner - quadVertices[0] = p0.x; - quadVertices[1] = p0.y; - quadVertices[2] = 0; - // top right corner - quadVertices[3] = p1.x; - quadVertices[4] = p1.y; - quadVertices[5] = 0; - // bottom right corner - quadVertices[6] = p2.x; - quadVertices[7] = p2.y; - quadVertices[8] = 0; - // bottom left corner - quadVertices[9] = p3.x; - quadVertices[10] = p3.y; - quadVertices[11] = 0; - - float q0 = (d0 + d2) / (d2); - float q1 = (d1 + d3) / (d3); - float q2 = (d2 + d0) / (d0); - float q3 = (d3 + d1) / (d1); - - quadTexCoordinates[0] = t0.x; - quadTexCoordinates[1] = t0.y; - quadTexCoordinates[3] = q0; - - quadTexCoordinates[4] = t1.x * q1; - quadTexCoordinates[5] = t1.y; - quadTexCoordinates[7] = q1; - - quadTexCoordinates[8] = t2.x * q2; - quadTexCoordinates[9] = t2.y * q2; - quadTexCoordinates[11] = q2; - - quadTexCoordinates[12] = t3.x; - quadTexCoordinates[13] = t3.y * q3; - quadTexCoordinates[15] = q3; - -} \ No newline at end of file diff --git a/src/ofxQuadSurface.h b/src/ofxQuadSurface.h deleted file mode 100755 index 4c6cb9d..0000000 --- a/src/ofxQuadSurface.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef H_OFX_QUAD_SURFACE -#define H_OFX_QUAD_SURFACE - -#include "ofMain.h" -#include "ofxBaseSurface.h" -#include "ofxSurfaceType.h" - -class ofxQuadSurface : public ofxBaseSurface -{ -public: - ofxQuadSurface(); - ~ofxQuadSurface(); - - void setup(); - - void setup( ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, - ofVec2f t1, ofVec2f t2, ofVec2f t3, ofVec2f t4, - ofTexture* texturePtr ); - - void draw(); - void setVertex( int index, ofVec2f p ); - void setTexCoord( int index, ofVec2f t ); - void moveBy(ofVec2f v); - - int getType(); - bool hitTest(ofVec2f p); - ofVec2f getVertex(int index); - ofVec2f getTexCoord(int index); - ofPolyline getHitArea(); - ofPolyline getTextureHitArea(); - vector& getVertices(); - vector& getTexCoords(); -private: - void calculate4dTextureCoords(); - GLfloat quadVertices[12]; - GLubyte quadIndices[6]; - GLfloat quadTexCoordinates[16]; -}; - -#endif \ No newline at end of file diff --git a/src/ofxSourcesEditor.cpp b/src/ofxSourcesEditor.cpp deleted file mode 100644 index 5b5603c..0000000 --- a/src/ofxSourcesEditor.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "ofxSourcesEditor.h" - -ofxSourcesEditor::ofxSourcesEditor() -{ - defImgDir = DEFAULT_IMAGES_DIR; - registerAppEvents(); -} - -ofxSourcesEditor::~ofxSourcesEditor() -{ - unregisterAppEvents(); - delete gui; - while ( images.size() ) { - delete images.back(); - images.pop_back(); - } -} - -void ofxSourcesEditor::registerAppEvents() -{ - ofAddListener(ofEvents().setup, this, &ofxSourcesEditor::setup); -} - -void ofxSourcesEditor::unregisterAppEvents() -{ - ofRemoveListener(ofEvents().setup, this, &ofxSourcesEditor::setup); -} - -void ofxSourcesEditor::setup(ofEventArgs& args) -{ - gui = new ofxRadioList(); - - // read directory contents - ofDirectory imgDir; - imgDir.listDir(defImgDir); - imgDir.sort(); - - vector vnames; - - for(int i = 0; i < (int)imgDir.size(); i++){ - //images[i].loadImage(imgDir.getPath(i)); - vnames.push_back(imgDir.getName(i)); - } - - gui->setup("Images", vnames); - gui->setPosition(20, 20); - ofAddListener(gui->radioSelectedEvent, this, &ofxSourcesEditor::guiEvent); -} - -void ofxSourcesEditor::draw() -{ - // Don't draw if there is no source selected - if ( surfaceManager->getSelectedSurface() == NULL ) { - return; - } - - gui->draw(); -} - -void ofxSourcesEditor::loadImage( string name, string path ) -{ - images.push_back(new ofImage()); - images.back()->loadImage(path); - - imageNames.push_back(name); - - ofSendMessage("imageLoaded"); -} - -void ofxSourcesEditor::disable() -{ - gui->disable(); -} - -void ofxSourcesEditor::enable() -{ - // Don't enable if there is no surface selected - if ( surfaceManager->getSelectedSurface() == NULL ) { - cout << "No surface selected. Not enable()ing source list." << endl; - return; - } - - gui->enable(); -} - -void ofxSourcesEditor::setSurfaceManager(ofxSurfaceManager *newSurfaceManager) -{ - surfaceManager = newSurfaceManager; -} - -void ofxSourcesEditor::selectImageSourceRadioButton(string name) -{ - if (name == "none") { - gui->unselectAll(); - return; - } else { - int i; - for (i = 0; i < gui->size(); i++) { - if (gui->getItemName(i) == name) { - gui->selectItem(i); - return; - } - } - } -} - -int ofxSourcesEditor::getLoadedTexCount() -{ - return images.size(); -} - -ofTexture* ofxSourcesEditor::getTexture(int index) -{ - if (index >= images.size()){ - throw std::runtime_error("Texture index out of bounds."); - } - - return &images[index]->getTextureReference(); -} - -void ofxSourcesEditor::guiEvent(string &imageName) -{ - string name = imageName; - - if ( surfaceManager->getSelectedSurface() == NULL ) { - return; - } - - stringstream ss; - ss << defImgDir << name; - cout << "attempt to load image: " << ss.str() << endl; - ofTexture* texture = surfaceManager->loadImageSource(name, ss.str()); - surfaceManager->getSelectedSurface()->setTexture(texture); - surfaceManager->manageMemory(); -} \ No newline at end of file diff --git a/src/ofxSourcesEditor.h b/src/ofxSourcesEditor.h deleted file mode 100644 index 33aad38..0000000 --- a/src/ofxSourcesEditor.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef H_OFX_SOURCES_EDITOR -#define H_OFX_SOURCES_EDITOR - -#include "ofGraphics.h" -#include "ofEvents.h" -#include "ofxSurfaceManager.h" -#include "ofxRadioList.h" - -#define DEFAULT_IMAGES_DIR "sources/images/"; - -class ofxSourcesEditor -{ -public: - ofxSourcesEditor(); - ~ofxSourcesEditor(); - - void registerAppEvents(); - void unregisterAppEvents(); - - void setup(ofEventArgs& args); - void draw(); - void loadImage( string name, string path ); - void disable(); - void enable(); - void setSurfaceManager(ofxSurfaceManager* newSurfaceManager); - void selectImageSourceRadioButton(string name); - - int getLoadedTexCount(); - ofTexture* getTexture(int index); - -private: - ofxSurfaceManager* surfaceManager; - ofxRadioList* gui; - string defImgDir; - void guiEvent(string &imageName); - vector images; - vector imageNames; -}; - -#endif \ No newline at end of file diff --git a/src/ofxSurfaceManager.cpp b/src/ofxSurfaceManager.cpp deleted file mode 100644 index e7df328..0000000 --- a/src/ofxSurfaceManager.cpp +++ /dev/null @@ -1,486 +0,0 @@ -#include "ofxSurfaceManager.h" - -ofxSurfaceManager::ofxSurfaceManager() -{ - -} - -ofxSurfaceManager::~ofxSurfaceManager() -{ - clear(); -} - -void ofxSurfaceManager::draw() -{ - for ( int i=0; idraw(); - } -} - -void ofxSurfaceManager::addSurface(int surfaceType) -{ - if ( surfaceType == ofxSurfaceType::TRIANGLE_SURFACE ) { - surfaces.push_back( new ofxTriangleSurface() ); - } - else if (surfaceType == ofxSurfaceType::QUAD_SURFACE ) { - surfaces.push_back( new ofxQuadSurface() ); - } - else { - throw std::runtime_error("Attempt to add non-existing surface type."); - } -} - -void ofxSurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr) -{ - if ( surfaceType == ofxSurfaceType::TRIANGLE_SURFACE ) { - surfaces.push_back( new ofxTriangleSurface() ); - surfaces.back()->setTexture(texturePtr); - } - else if (surfaceType == ofxSurfaceType::QUAD_SURFACE ) { - surfaces.push_back( new ofxQuadSurface() ); - surfaces.back()->setTexture(texturePtr); - } - else { - throw std::runtime_error("Attempt to add non-existing surface type."); - } -} - -void ofxSurfaceManager::addSurface(int surfaceType, vector vertices, vector texCoords) -{ - if ( surfaceType == ofxSurfaceType::TRIANGLE_SURFACE ) { - - if ( vertices.size() < 3 ) { - throw std::runtime_error("There must be 3 vertices for a triangle surface."); - } else if (texCoords.size() < 3) { - throw std::runtime_error("There must be 3 texture coordinates for a triangle surface."); - } - - surfaces.push_back( new ofxTriangleSurface() ); - - for ( int i=0; i<3; i++ ) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - - } - else if (surfaceType == ofxSurfaceType::QUAD_SURFACE ) { - if ( vertices.size() < 4 ) { - throw std::runtime_error("There must be 4 vertices for a quad surface."); - } else if (texCoords.size() < 4) { - throw std::runtime_error("There must be 4 texture coordinates for a quad surface."); - } - - surfaces.push_back( new ofxQuadSurface() ); - - for ( int i=0; i<4; i++ ) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - } - else { - throw std::runtime_error("Attempt to add non-existing surface type."); - } - -} - -void ofxSurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr, vector vertices, vector texCoords) -{ - if ( surfaceType == ofxSurfaceType::TRIANGLE_SURFACE ) { - - if ( vertices.size() < 3 ) { - throw std::runtime_error("There must be 3 vertices for a triangle surface."); - } else if (texCoords.size() < 3) { - throw std::runtime_error("Thre must be 3 texture coordinates for a triangle surface."); - } - - surfaces.push_back( new ofxTriangleSurface() ); - surfaces.back()->setTexture(texturePtr); - - for ( int i=0; i<3; i++ ) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - - } - else if (surfaceType == ofxSurfaceType::QUAD_SURFACE ) { - if ( vertices.size() < 4 ) { - throw std::runtime_error("There must be 4 vertices for a quad surface."); - } else if (texCoords.size() < 4) { - throw std::runtime_error("Thre must be 4 texture coordinates for a quad surface."); - } - - surfaces.push_back( new ofxQuadSurface() ); - surfaces.back()->setTexture(texturePtr); - - for ( int i=0; i<4; i++ ) { - surfaces.back()->setVertex(i, vertices[i]); - surfaces.back()->setTexCoord(i, texCoords[i]); - } - } - else { - throw std::runtime_error("Attempt to add non-existing surface type."); - } -} - -void ofxSurfaceManager::removeSelectedSurface() -{ - if ( selectedSurface == NULL ) return; - - for ( int i=0; igetTexture() == &loadedImageSources[i]->getTextureReference() ) { - bAssigned = true; - break; - } - } - - if ( !bAssigned ) { - // purge the image source from memory - delete loadedImageSources[i]; - loadedImageSources.erase(loadedImageSources.begin()+i); - cout << "Deleting image source: " << loadedImageSourceNames[i] << endl; - loadedImageSourceNames.erase(loadedImageSourceNames.begin()+i); - i--; - } - } -} - -void ofxSurfaceManager::clear() -{ - // delete all extra allocations from the heap - while ( surfaces.size() ) { - delete surfaces.back(); - surfaces.pop_back(); - } - - while ( loadedImageSources.size() ) { - delete loadedImageSources.back(); - loadedImageSources.pop_back(); - } - - while ( loadedImageSourceNames.size() ) { - loadedImageSourceNames.pop_back(); - } -} - -// String getTypeString(ofxSurfaceType e) -// { -// switch e -// { -// case TRINAGLE_SURFACE: return "TRINAGLE_SURFACE"; -// case QUAD_SURFACE: return "QUAD_SURFACE"; -// default: throw Exception("Bad MyEnum"); -// } -// } - -void ofxSurfaceManager::saveXmlSettings(string fileName) -{ - xmlSettings.clear(); - - // save surfaces - xmlSettings.addTag("surfaces"); - xmlSettings.pushTag("surfaces"); - for ( int i=0; i* vertices = &surface->getVertices(); - for ( int j=0; jsize(); j++ ) { - xmlSettings.addTag("vertex"); - xmlSettings.pushTag("vertex", j); - ofVec3f* vertex = &(*vertices)[j]; - xmlSettings.addValue("x", vertex->x); - xmlSettings.addValue("y", vertex->y); - - // we don't need z as it will be 0 anyways - - xmlSettings.popTag(); // vertex - } - xmlSettings.popTag(); // vertices - - xmlSettings.addTag("texCoords"); - xmlSettings.pushTag("texCoords"); - vector* texCoords = &surface->getTexCoords(); - for ( int j=0; jsize(); j++ ) { - xmlSettings.addTag("texCoord"); - xmlSettings.pushTag("texCoord", j); - ofVec2f* texCoord = &(*texCoords)[j]; - xmlSettings.addValue("x", texCoord->x); - xmlSettings.addValue("y", texCoord->y); - xmlSettings.popTag(); // texCoord - } - xmlSettings.popTag(); // texCoords - - xmlSettings.addTag("source"); - xmlSettings.pushTag("source"); - - xmlSettings.addValue("source-type", "image"); - xmlSettings.addValue("source-name", getSurfaceSourceName(surface)); - //xmlSettings.addValue("source-path", "/root/etc/image.jpg"); - xmlSettings.popTag(); // source - - - // xmlSettings.addTag("type"); - // xmlSettings.pushTag("type"); - // // surfaceType == ofxSurfaceType::TRIANGLE_SURFACE - // ofxSurfaceType surfaceType = &surface->getType(); - // xmlSettings.addValue("surface-type", surfaceType); - // xmlSettings.popTag(); // type - - xmlSettings.popTag(); // surface - } - xmlSettings.popTag(); // surfaces - - xmlSettings.save(fileName); -} - -void ofxSurfaceManager::loadXmlSettings(string fileName) -{ - - - if (!xmlSettings.loadFile(fileName)){ - ofLog(OF_LOG_WARNING, "Could not load XML settings."); - return; - } - - if (!xmlSettings.tagExists("surfaces")){ - ofLog(OF_LOG_WARNING, "XML settings is empty or has wrong markup."); - return; - } - - xmlSettings.pushTag("surfaces"); - - int numSurfaces = xmlSettings.getNumTags("surface"); - for ( int i=0; i vertices; - - int vertexCount = xmlSettings.getNumTags("vertex"); - - - //it's a triangle ? - if (vertexCount == 3) - { - ofLog(OF_LOG_NOTICE, "create Triangle"); - xmlSettings.pushTag("vertex", 0); - vertices.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 1); - vertices.push_back( ofVec2f( xmlSettings.getValue("x", 100.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 2); - vertices.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 100.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.popTag(); // vertices - - xmlSettings.pushTag("texCoords"); - - vector texCoords; - - xmlSettings.pushTag("texCoord", 0); - texCoords.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 1); - texCoords.push_back( ofVec2f( xmlSettings.getValue("x", 1.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 2); - texCoords.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 1.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.popTag(); // texCoords - - - // now we have variables sourceName and sourceTexture - // by checking those we can use one or another addSurface method - if ( sourceName != "none" && sourceTexture != NULL ) { - addSurface(ofxSurfaceType::TRIANGLE_SURFACE, sourceTexture, vertices, texCoords); - } else { - addSurface(ofxSurfaceType::TRIANGLE_SURFACE, vertices, texCoords); - } - } - // it's a quad ? - else if (vertexCount == 4) - // if (surface-type == QUAD_SURFACE) - { - xmlSettings.pushTag("vertex", 0); - vertices.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 1); - vertices.push_back( ofVec2f( xmlSettings.getValue("x", 100.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 2); - vertices.push_back( ofVec2f( xmlSettings.getValue("x", 100.0f), xmlSettings.getValue("y", 100.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("vertex", 3); - vertices.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 100.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.popTag(); // vertices - - xmlSettings.pushTag("texCoords"); - - vector texCoords; - - xmlSettings.pushTag("texCoord", 0); - texCoords.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 1); - texCoords.push_back( ofVec2f( xmlSettings.getValue("x", 1.0f), xmlSettings.getValue("y", 0.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 2); - texCoords.push_back( ofVec2f( xmlSettings.getValue("x", 1.0f), xmlSettings.getValue("y", 1.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.pushTag("texCoord", 3); - texCoords.push_back( ofVec2f( xmlSettings.getValue("x", 0.0f), xmlSettings.getValue("y", 1.0f) ) ); - xmlSettings.popTag(); - - xmlSettings.popTag(); // texCoords - - - // now we have variables sourceName and sourceTexture - // by checking those we can use one or another addSurface method - if ( sourceName != "none" && sourceTexture != NULL ) { - addSurface(ofxSurfaceType::QUAD_SURFACE, sourceTexture, vertices, texCoords); - } else { - addSurface(ofxSurfaceType::QUAD_SURFACE, vertices, texCoords); - } - - - } - - xmlSettings.popTag(); // surface - } - - xmlSettings.popTag(); // surfaces -} - -ofxBaseSurface* ofxSurfaceManager::selectSurface(int index) -{ - if ( index >= surfaces.size() ) { - throw std::runtime_error("Surface index out of bounds."); - } - - selectedSurface = surfaces[index]; - - // notify that a new surface has been selected - ofSendMessage("surfaceSelected"); -} - -ofxBaseSurface* ofxSurfaceManager::getSelectedSurface() -{ - return selectedSurface; -} - -void ofxSurfaceManager::deselectSurface() -{ - selectedSurface = NULL; -} - -ofTexture* ofxSurfaceManager::loadImageSource(string name, string path) -{ - // check if it is loaded - for ( int i=0; igetTextureReference(); - } - } - - // not loaded - load - ofImage* image = new ofImage(); - if ( !image->loadImage(path) ){ - return NULL; - } - loadedImageSources.push_back(image); - loadedImageSourceNames.push_back(name); - return &image->getTextureReference(); -} - -string ofxSurfaceManager::getSelectedSurfaceSourceName() -{ - if ( selectedSurface == NULL ) { - return "none"; - } - - return getSurfaceSourceName( selectedSurface ); -} - -string ofxSurfaceManager::getSurfaceSourceName(ofxBaseSurface *surface) -{ - ofTexture* tex = surface->getTexture(); - for ( int i=0; igetTextureReference()) { - return loadedImageSourceNames[i]; - } - } - - return "none"; -} - -ofxBaseSurface* ofxSurfaceManager::getSurface(int index) -{ - if ( index >= surfaces.size() ) { - throw std::runtime_error("Surface index out of bounds."); - return NULL; - } - - return surfaces[index]; -} - -int ofxSurfaceManager::size() -{ - return surfaces.size(); -} - - - diff --git a/src/ofxSurfaceManager.h b/src/ofxSurfaceManager.h deleted file mode 100755 index 90e8bb1..0000000 --- a/src/ofxSurfaceManager.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef H_OFX_SURFACE_MANAGER -#define H_OFX_SURFACE_MANAGER - -#include "ofxBaseSurface.h" -#include "ofxTriangleSurface.h" -#include "ofxQuadSurface.h" -#include "ofxSurfaceType.h" -#include "ofEvents.h" -#include "ofxXmlSettings.h" - -using namespace std; - -class ofxSurfaceManager -{ -public: - ofxSurfaceManager(); - ~ofxSurfaceManager(); - - void draw(); - void addSurface(int surfaceType); - void addSurface(int surfaceType, ofTexture* texturePtr); - void addSurface(int surfaceType, vector vertices, vector texCoords); - void addSurface(int surfaceType, ofTexture* texturePtr, vector vertices, vector texCoords); - void removeSelectedSurface(); - void manageMemory(); // deletes unasigned sources - void clear(); - void saveXmlSettings(string fileName); - void loadXmlSettings(string fileName); - - ofxBaseSurface* getSurface(int index); - int size(); - ofxBaseSurface* selectSurface(int index); - ofxBaseSurface* getSelectedSurface(); - void deselectSurface(); - ofTexture* loadImageSource(string name, string path); - string getSelectedSurfaceSourceName(); - string getSurfaceSourceName( ofxBaseSurface* surface ); - -private: - vector surfaces; - ofxBaseSurface* selectedSurface; - vector loadedImageSourceNames; - vector loadedImageSources; - ofxXmlSettings xmlSettings; - -}; - -#endif \ No newline at end of file diff --git a/src/ofxSurfaceManagerGui.cpp b/src/ofxSurfaceManagerGui.cpp deleted file mode 100644 index 49d5a1e..0000000 --- a/src/ofxSurfaceManagerGui.cpp +++ /dev/null @@ -1,254 +0,0 @@ -#include "ofxSurfaceManagerGui.h" - -ofxSurfaceManagerGui::ofxSurfaceManagerGui() -{ - surfaceManager = NULL; - guiMode = ofxGuiMode::NONE; - bDrag = false; - registerMouseEvents(); - ofHideCursor(); -} - -ofxSurfaceManagerGui::~ofxSurfaceManagerGui() -{ - unregisterMouseEvents(); - surfaceManager = NULL; -} - -void ofxSurfaceManagerGui::registerMouseEvents() -{ - ofAddListener(ofEvents().mousePressed, this, &ofxSurfaceManagerGui::mousePressed); - ofAddListener(ofEvents().mouseReleased, this, &ofxSurfaceManagerGui::mouseReleased); - ofAddListener(ofEvents().mouseDragged, this, &ofxSurfaceManagerGui::mouseDragged); -} - -void ofxSurfaceManagerGui::unregisterMouseEvents() -{ - ofRemoveListener(ofEvents().mousePressed, this, &ofxSurfaceManagerGui::mousePressed); - ofRemoveListener(ofEvents().mouseReleased, this, &ofxSurfaceManagerGui::mouseReleased); - ofRemoveListener(ofEvents().mouseDragged, this, &ofxSurfaceManagerGui::mouseDragged); -} - -void ofxSurfaceManagerGui::draw() -{ - if ( surfaceManager == NULL ) return; - - if ( guiMode == ofxGuiMode::NONE ) { - surfaceManager->draw(); - } else if ( guiMode == ofxGuiMode::TEXTURE_MAPPING ) { - - // draw the texture of the selected surface - if ( surfaceManager->getSelectedSurface() != NULL ) { - surfaceManager->getSelectedSurface()->drawTexture( ofVec2f(0,0) ); - } - - // draw surfaces with opacity - ofPushStyle(); - ofSetColor(255, 255, 255, 200); - surfaceManager->draw(); - ofPopStyle(); - - // highlight selected surface - drawSelectedSurfaceHighlight(); - - // hilight selected surface texture - drawSelectedSurfaceTextureHighlight(); - - // draw texture editing GUI on top - textureEditor.draw(); - - } else if ( guiMode == ofxGuiMode::PROJECTION_MAPPING ) { - - // draw projection surfaces first - surfaceManager->draw(); - - // highlight selected surface - drawSelectedSurfaceHighlight(); - - // draw projection mapping editing gui - projectionEditor.draw(); - - } else if ( guiMode == ofxGuiMode::SOURCE_SELECTION ) { - // draw projection surfaces first - surfaceManager->draw(); - - // highlight selected surface - drawSelectedSurfaceHighlight(); - - sourcesEditor.draw(); - } -} - -void ofxSurfaceManagerGui::mousePressed(ofMouseEventArgs &args) -{ - if ( guiMode == ofxGuiMode::NONE ) { - return; - } else if ( guiMode == ofxGuiMode::TEXTURE_MAPPING ) { - - bool bSurfaceSelected = false; - - ofxCircleJoint* hitJoint = textureEditor.hitTestJoints(ofVec2f(args.x, args.y)); - if ( hitJoint != NULL ) { - textureEditor.unselectAllJoints(); - hitJoint->select(); - hitJoint->startDrag(); - bSurfaceSelected = true; - } else { - textureEditor.unselectAllJoints(); - } - - if ( surfaceManager->getSelectedSurface() != NULL && !bSurfaceSelected ) { - // hittest texture area to see if we are hitting the texture surface - if ( surfaceManager->getSelectedSurface()->getTextureHitArea().inside(args.x, args.y) ) { - clickPosition = ofVec2f(args.x, args.y); - startDrag(); - } - } - - } else if ( guiMode == ofxGuiMode::PROJECTION_MAPPING ) { - - bool bSurfaceSelected = false; - - ofxCircleJoint* hitJoint = projectionEditor.hitTestJoints(ofVec2f(args.x, args.y)); - if ( hitJoint != NULL ) { - projectionEditor.unselectAllJoints(); - hitJoint->select(); - hitJoint->startDrag(); - bSurfaceSelected = true; - } - - // attempt to select surface, loop from end to beginning - if ( !bSurfaceSelected ){ - for ( int i=surfaceManager->size()-1; i>=0; i-- ) { - if ( surfaceManager->getSurface(i)->hitTest( ofVec2f(args.x, args.y) ) ) { - projectionEditor.clearJoints(); - surfaceManager->selectSurface(i); - projectionEditor.createJoints(); - bSurfaceSelected = true; - break; - } - } - } - - if ( bSurfaceSelected && hitJoint == NULL ) { - // if not hitting the joints, start drag only if we have a selected surface - clickPosition = ofVec2f(args.x, args.y); - startDrag(); - } - - if ( !bSurfaceSelected ) { - // unselect if no surface selected - projectionEditor.clearJoints(); - surfaceManager->deselectSurface(); - } - } else if ( guiMode == ofxGuiMode::SOURCE_SELECTION ) { - - } -} - -void ofxSurfaceManagerGui::mouseReleased(ofMouseEventArgs &args) -{ - stopDrag(); - projectionEditor.stopDragJoints(); - textureEditor.stopDragJoints(); -} - -void ofxSurfaceManagerGui::mouseDragged(ofMouseEventArgs &args) -{ - if (bDrag) { - ofVec2f mousePosition = ofVec2f(args.x, args.y); - ofVec2f distance = mousePosition - clickPosition; - - if ( guiMode == ofxGuiMode::PROJECTION_MAPPING ) { - // add this distance to all vertices in surface - projectionEditor.moveSelectedSurface(distance); - } else if ( guiMode == ofxGuiMode::TEXTURE_MAPPING ) { - textureEditor.moveTexCoords(distance); - } - clickPosition = mousePosition; - } -} - -void ofxSurfaceManagerGui::setSurfaceManager(ofxSurfaceManager* newSurfaceManager) -{ - surfaceManager = newSurfaceManager; - projectionEditor.setSurfaceManager( surfaceManager ); - sourcesEditor.setSurfaceManager( surfaceManager ); -} - -void ofxSurfaceManagerGui::setMode(int newGuiMode) -{ - if (newGuiMode != ofxGuiMode::NONE && - newGuiMode != ofxGuiMode::TEXTURE_MAPPING && - newGuiMode != ofxGuiMode::PROJECTION_MAPPING && - newGuiMode != ofxGuiMode::SOURCE_SELECTION) { - throw std::runtime_error("Trying to set invalid mode."); - } - - if ( newGuiMode == ofxGuiMode::NONE ) { - ofHideCursor(); - } else { - ofShowCursor(); - } - - guiMode = newGuiMode; - - if ( guiMode == ofxGuiMode::SOURCE_SELECTION ) { - sourcesEditor.enable(); - string sourceName = surfaceManager->getSelectedSurfaceSourceName(); - sourcesEditor.selectImageSourceRadioButton(sourceName); - } else { - sourcesEditor.disable(); - } - - if ( guiMode == ofxGuiMode::TEXTURE_MAPPING ) { - textureEditor.enable(); - // refresh texture editor surface reference - textureEditor.setSurface(surfaceManager->getSelectedSurface()); - } else { - textureEditor.disable(); - } - - if (guiMode == ofxGuiMode::PROJECTION_MAPPING) { - projectionEditor.enable(); - } else { - projectionEditor.disable(); - } -} - -void ofxSurfaceManagerGui::drawSelectedSurfaceHighlight() -{ - if ( surfaceManager->getSelectedSurface() == NULL ) return; - - ofPolyline line = surfaceManager->getSelectedSurface()->getHitArea(); - - ofPushStyle(); - ofSetLineWidth(1); - ofSetColor(255, 255, 255, 255); - line.draw(); - ofPopStyle(); -} - -void ofxSurfaceManagerGui::drawSelectedSurfaceTextureHighlight() -{ - if ( surfaceManager->getSelectedSurface() == NULL ) return; - - ofPolyline line = surfaceManager->getSelectedSurface()->getTextureHitArea(); - - ofPushStyle(); - ofSetLineWidth(1); - ofSetColor(255, 255, 0, 255); - line.draw(); - ofPopStyle(); - -} - -void ofxSurfaceManagerGui::startDrag() -{ - bDrag = true; -} - -void ofxSurfaceManagerGui::stopDrag() -{ - bDrag = false; -} \ No newline at end of file diff --git a/src/ofxSurfaceManagerGui.h b/src/ofxSurfaceManagerGui.h deleted file mode 100644 index 605d8a1..0000000 --- a/src/ofxSurfaceManagerGui.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef H_OFX_SURFACE_MANAGER_GUI -#define H_OFX_SURFACE_MANAGER_GUI - -// I'm starting to think, maybe we should use ofxStateMachine here. -// Would make sense. TODO later. - -#include "ofEvents.h" -#include "ofxSurfaceManager.h" -#include "ofxTextureEditor.h" -#include "ofxProjectionEditor.h" -#include "ofxSourcesEditor.h" -#include "ofxGuiMode.h" -#include "ofGraphics.h" - -class ofxSurfaceManagerGui -{ -public: - ofxSurfaceManagerGui(); - ~ofxSurfaceManagerGui(); - - void registerMouseEvents(); - void unregisterMouseEvents(); - - void draw(); - void mousePressed(ofMouseEventArgs& args); - void mouseReleased(ofMouseEventArgs& args); - void mouseDragged(ofMouseEventArgs& args); - void setSurfaceManager(ofxSurfaceManager* newSurfaceManager); - void setMode(int newGuiMode); - void drawSelectedSurfaceHighlight(); - void drawSelectedSurfaceTextureHighlight(); - void startDrag(); - void stopDrag(); - -private: - ofxSurfaceManager* surfaceManager; - ofxTextureEditor textureEditor; - ofxProjectionEditor projectionEditor; - ofxSourcesEditor sourcesEditor; - int guiMode; - bool bDrag; - ofVec2f clickPosition; - -}; - -#endif \ No newline at end of file diff --git a/src/ofxSurfaceType.h b/src/ofxSurfaceType.h deleted file mode 100755 index cbda131..0000000 --- a/src/ofxSurfaceType.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef H_OFX_SURFACE_TYPE -#define H_OFX_SURFACE_TYPE - -struct ofxSurfaceType -{ - enum { - TRIANGLE_SURFACE, - QUAD_SURFACE - }; -}; - -#endif \ No newline at end of file diff --git a/src/ofxTextureEditor.cpp b/src/ofxTextureEditor.cpp deleted file mode 100755 index 0a1aa41..0000000 --- a/src/ofxTextureEditor.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "ofxTextureEditor.h" - -ofxTextureEditor::ofxTextureEditor() -{ - clear(); - enable(); -} - -ofxTextureEditor::~ofxTextureEditor() -{ - clear(); - disable(); -} - -void ofxTextureEditor::registerAppEvents() -{ - ofAddListener(ofEvents().update, this, &ofxTextureEditor::update); -} - -void ofxTextureEditor::unregisterAppEvents() -{ - ofRemoveListener(ofEvents().update, this, &ofxTextureEditor::update); -} - -void ofxTextureEditor::registerKeyEvents() -{ - ofAddListener(ofEvents().keyPressed, this, &ofxTextureEditor::keyPressed); - ofAddListener(ofEvents().keyReleased, this, &ofxTextureEditor::keyReleased); -} - -void ofxTextureEditor::unregisterKeyEvents() -{ - ofRemoveListener(ofEvents().keyPressed, this, &ofxTextureEditor::keyPressed); - ofRemoveListener(ofEvents().keyReleased, this, &ofxTextureEditor::keyReleased); -} - -void ofxTextureEditor::enable() -{ - registerAppEvents(); - registerKeyEvents(); - bShiftKeyDown = false; -} - -void ofxTextureEditor::disable() -{ - unregisterAppEvents(); - unregisterKeyEvents(); -} - -void ofxTextureEditor::update(ofEventArgs &args) -{ - if ( surface == NULL ) return; - - // update surface if one of the joints is being dragged - ofVec2f textureSize = ofVec2f( surface->getTexture()->getWidth(), surface->getTexture()->getHeight() ); - for ( int i=0; iisDragged() || joints[i]->isSelected() ) { - // update vertex to new location - surface->setTexCoord(i, joints[i]->position / textureSize); - break; - } - } -} - -void ofxTextureEditor::keyPressed(ofKeyEventArgs &args) -{ - int key = args.key; - float moveStep; - - if (bShiftKeyDown) moveStep = 10.0f; - else moveStep = 0.5f; - - switch (key) { - case OF_KEY_LEFT: moveSelection(ofVec2f(-moveStep,0.0f)); break; - case OF_KEY_RIGHT: moveSelection(ofVec2f(moveStep,0.0f)); break; - case OF_KEY_UP: moveSelection(ofVec2f(0.0f,-moveStep)); break; - case OF_KEY_DOWN: moveSelection(ofVec2f(0.0f,moveStep)); break; - case OF_KEY_SHIFT: bShiftKeyDown = true; break; - } -} - -void ofxTextureEditor::keyReleased(ofKeyEventArgs &args) -{ - int key = args.key; - switch (key) { - case OF_KEY_SHIFT: bShiftKeyDown = false; break; - } -} - - -void ofxTextureEditor::draw() -{ - if (surface == NULL) return; - - drawJoints(); -} - -void ofxTextureEditor::drawJoints() -{ - for ( int i=0; idraw(); - } -} - -void ofxTextureEditor::setSurface(ofxBaseSurface* newSurface) -{ - surface = newSurface; - createJoints(); -} - -void ofxTextureEditor::clear() -{ - surface = NULL; - clearJoints(); -} - -void ofxTextureEditor::createJoints() -{ - if ( surface == NULL ) return; - clearJoints(); - vector& texCoords = surface->getTexCoords(); - ofVec2f textureSize = ofVec2f(surface->getTexture()->getWidth(), surface->getTexture()->getHeight()); - - for ( int i=0; iposition = texCoords[i] * textureSize; - } -} - -void ofxTextureEditor::clearJoints() -{ - while ( joints.size() ) { - delete joints.back(); - joints.pop_back(); - } -} - -void ofxTextureEditor::unselectAllJoints() -{ - for ( int i=0; iunselect(); - } -} - -void ofxTextureEditor::moveTexCoords(ofVec2f by) -{ - if ( surface == NULL ) return; - vector& texCoords = surface->getTexCoords(); - ofVec2f textureSize = ofVec2f( surface->getTexture()->getWidth(), surface->getTexture()->getHeight() ); - for (int i=0; iposition += by; - texCoords[i] = joints[i]->position / textureSize; - } -} - -void ofxTextureEditor::stopDragJoints() -{ - for (int i=0; istopDrag(); - } -} - -void ofxTextureEditor::moveSelection(ofVec2f by) -{ - // check if joints selected - bool bJointSelected = false; - ofxBaseJoint* selectedJoint; - for ( int i=0; iisSelected()) { - bJointSelected = true; - selectedJoint = joints[i]; - break; - } - } - - if ( bJointSelected ) { - selectedJoint->position += by; - } else { - moveTexCoords(by); - } -} - -ofxCircleJoint* ofxTextureEditor::hitTestJoints(ofVec2f pos) -{ - for ( int i=0; ihitTest(pos) ){ - return joints[i]; - } - } - return NULL; -} \ No newline at end of file diff --git a/src/ofxTextureEditor.h b/src/ofxTextureEditor.h deleted file mode 100644 index 18f30ef..0000000 --- a/src/ofxTextureEditor.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef H_OFX_TEXTURE_EDITOR -#define H_OFX_TEXTURE_EDITOR - -#include "ofEvents.h" -#include "ofxBaseSurface.h" -#include "ofxCircleJoint.h" - -class ofxTextureEditor -{ -public: - ofxTextureEditor(); - ~ofxTextureEditor(); - - void registerAppEvents(); - void unregisterAppEvents(); - void registerKeyEvents(); - void unregisterKeyEvents(); - void enable(); - void disable(); - - void update(ofEventArgs& args); - void keyPressed(ofKeyEventArgs& args); - void keyReleased(ofKeyEventArgs& args); - void draw(); - void drawJoints(); - void setSurface(ofxBaseSurface* newSurface); - void clear(); - void createJoints(); - void clearJoints(); - void unselectAllJoints(); - void moveTexCoords(ofVec2f by); - void stopDragJoints(); - void moveSelection(ofVec2f by); - ofxCircleJoint* hitTestJoints(ofVec2f pos); - -private: - ofxBaseSurface* surface; - vector joints; - bool bShiftKeyDown; -}; - -#endif \ No newline at end of file diff --git a/src/ofxTriangleSurface.cpp b/src/ofxTriangleSurface.cpp deleted file mode 100644 index 56d0a44..0000000 --- a/src/ofxTriangleSurface.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include "ofxTriangleSurface.h" - -ofxTriangleSurface::ofxTriangleSurface() -{ - cout << "ofxTriangleSurface constructor." << endl; - setup(); -} - -ofxTriangleSurface::~ofxTriangleSurface() -{ - cout << "ofxTriangleSurface destructor." << endl; -} - -void ofxTriangleSurface::setup() -{ - // Create 3 points for the triangle - ofVec2f p1 = ofVec2f(ofGetWidth()/2.0f, 0); - ofVec2f p2 = ofVec2f(ofVec2f(0, ofGetHeight())); - ofVec2f p3 = ofVec2f(ofGetWidth(), ofGetHeight()); - - // Create 3 point for the texture coordinates - ofVec2f t1 = ofVec2f(0.5f, 0); - ofVec2f t2 = ofVec2f(0, 1.0f); - ofVec2f t3 = ofVec2f(1, 1.0f); - - setup( p1, p2, p3, t1, t2, t3, texture ); -} - -void ofxTriangleSurface::setup( ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, ofVec2f t2, ofVec2f t3, ofTexture* texturePtr ) -{ - // Assign texture - texture = texturePtr; - - // Clear mesh - mesh.clear(); - - // Create a surface with the points - mesh.addVertex( p1 ); - mesh.addVertex( p2 ); - mesh.addVertex( p3 ); - - // Add texture coordinates - mesh.addTexCoord(t1); - mesh.addTexCoord(t2); - mesh.addTexCoord(t3); -} - -void ofxTriangleSurface::draw() -{ - texture->bind(); - mesh.draw(); - texture->unbind(); -} - -void ofxTriangleSurface::setVertex(int index, ofVec2f p) -{ - if ( index > 2 ) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - return; - } - - mesh.setVertex(index, p); -} - -void ofxTriangleSurface::setTexCoord(int index, ofVec2f t) -{ - if ( index > 2 ) { - ofLog() << "Texture coordinate with this index does not exist: " << index << endl; - return; - } - - mesh.setTexCoord(index, t); -} - -void ofxTriangleSurface::moveBy(ofVec2f v) -{ - vector& vertices = getVertices(); - for (int i=0; i 2 ) { - ofLog() << "Vertex with this index does not exist: " << index << endl; - throw std::runtime_error("Vertex index out of bounds."); - } - - ofVec3f vert = mesh.getVertex(index); - return ofVec2f(vert.x, vert.y); -} - -ofVec2f ofxTriangleSurface::getTexCoord(int index) -{ - if (index > 2) { - throw std::runtime_error("Texture coordinate index out of bounds."); - } - - return mesh.getTexCoord(index); -} - -ofPolyline ofxTriangleSurface::getHitArea() -{ - ofPolyline line; - line.addVertex( ofPoint( mesh.getVertex(0).x, mesh.getVertex(0).y ) ); - line.addVertex( ofPoint( mesh.getVertex(1).x, mesh.getVertex(1).y ) ); - line.addVertex( ofPoint( mesh.getVertex(2).x, mesh.getVertex(2).y ) ); - line.close(); - - return line; -} - -ofPolyline ofxTriangleSurface::getTextureHitArea() -{ - ofPolyline line; - vector& texCoords = mesh.getTexCoords(); - ofVec2f textureSize = ofVec2f(texture->getWidth(), texture->getHeight()); - for ( int i=0; i& ofxTriangleSurface::getVertices() -{ - // return only joint vertices - return mesh.getVertices(); -} - -vector& ofxTriangleSurface::getTexCoords() -{ - - return mesh.getTexCoords(); -} \ No newline at end of file diff --git a/src/ofxTriangleSurface.h b/src/ofxTriangleSurface.h deleted file mode 100644 index 27d3865..0000000 --- a/src/ofxTriangleSurface.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef H_OFX_TRIANGLE_SURFACE -#define H_OFX_TRIANGLE_SURFACE - -#include "ofMain.h" -#include "ofxBaseSurface.h" -#include "ofxSurfaceType.h" - -class ofxTriangleSurface : public ofxBaseSurface -{ -public: - ofxTriangleSurface(); - ~ofxTriangleSurface(); - - void setup(); - void setup( ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, ofVec2f t2, ofVec2f t3, ofTexture* texturePtr ); - void draw(); - void setVertex( int index, ofVec2f p ); - void setTexCoord( int index, ofVec2f t ); - void moveBy(ofVec2f v); - - int getType(); - bool hitTest(ofVec2f p); - ofVec2f getVertex(int index); - ofVec2f getTexCoord(int index); - ofPolyline getHitArea(); - ofPolyline getTextureHitArea(); - vector& getVertices(); - vector& getTexCoords(); -}; - -#endif \ No newline at end of file diff --git a/src/ui/RadioList.cpp b/src/ui/RadioList.cpp new file mode 100644 index 0000000..c280edc --- /dev/null +++ b/src/ui/RadioList.cpp @@ -0,0 +1,155 @@ +#include "RadioList.h" + +namespace ofx { +namespace piMapper { +RadioList::RadioList() { + storedTitle = ""; + storedSelectedItem = 0; +} + +RadioList::RadioList(vector& labels) { + RadioList(); + setup(labels); +} + +RadioList::RadioList(string title, vector& labels) { + RadioList(); + setup(title, labels); +} + +RadioList::~RadioList() { clear(); } + +void RadioList::setup(vector& labels) { + // Copy incomming labels for later use + storedLabels = labels; + + // Create toggles with labels from the labels arg + int i; + for (i = 0; i < labels.size(); i++) { + ofxToggle* toggle = new ofxToggle(); + toggle->setup(false); + toggle->setName(labels[i]); + toggle->addListener(this, &RadioList::onToggleClicked); + guiGroup.add(toggle); + } + + cout << "num items: " << guiGroup.getNumControls() << endl; +} + +void RadioList::setup(string title, vector& labels) { + // Store title for later use + storedTitle = title; + guiGroup.setName(title); + setup(labels); +} + +void RadioList::draw() { guiGroup.draw(); } + +void RadioList::setTitle(string title) { + storedTitle = title; + guiGroup.setName(title); +} + +void RadioList::setPosition(ofPoint p) { guiGroup.setPosition(p); } + +void RadioList::setPosition(float x, float y) { guiGroup.setPosition(x, y); } + +void RadioList::selectItem(int index) { + if (index >= guiGroup.getNumControls()) { + return; + } + + unselectAll(); + + ofxToggle* toggle = static_cast(guiGroup.getControl(index)); + toggle->removeListener(this, &RadioList::onToggleClicked); + *toggle = true; // Select the specific radio button + toggle->addListener(this, &RadioList::onToggleClicked); + string name = toggle->getName(); + ofNotifyEvent(radioSelectedEvent, name, this); + + storedSelectedItem = index; +} + +void RadioList::enable() { + if (guiGroup.getNumControls() >= 0) { + clear(); + } + + // Rebuild everyting + setup(storedTitle, storedLabels); + + // Select the stored selected item without throwing an event + ofxToggle* toggle = + static_cast(guiGroup.getControl(storedSelectedItem)); + toggle->removeListener(this, &RadioList::onToggleClicked); + *toggle = true; + toggle->addListener(this, &RadioList::onToggleClicked); + + cout << "num items after enable: " << guiGroup.getNumControls() << endl; +} + +void RadioList::disable() { + // Just remove everything + clear(); +} + +void RadioList::clear() { + int i; + for (i = 0; i < guiGroup.getNumControls(); i++) { + ofxToggle* toggle = static_cast(guiGroup.getControl(i)); + toggle->removeListener(this, &RadioList::onToggleClicked); + delete toggle; + } + guiGroup.clear(); +} + +void RadioList::unselectAll() { + int i; + for (i = 0; i < guiGroup.getNumControls(); i++) { + ofxToggle* toggle = static_cast(guiGroup.getControl(i)); + ofParameter* paramPtr = + static_cast*>(&toggle->getParameter()); + toggle->removeListener(this, &RadioList::onToggleClicked); + *toggle = false; + toggle->addListener(this, &RadioList::onToggleClicked); + } +} + +ofPoint RadioList::getPosition() { return guiGroup.getPosition(); } + +float RadioList::getWidth() { return guiGroup.getWidth(); } + +float RadioList::getHeight() { return guiGroup.getHeight(); } + +string RadioList::getTitle() { return guiGroup.getName(); } + +string RadioList::getItemName(int index) { + if (index >= guiGroup.getNumControls()) { + return ""; + } + + ofxToggle* toggle = static_cast(guiGroup.getControl(index)); + return toggle->getName(); +} + +int RadioList::size() { return guiGroup.getNumControls(); } + +void RadioList::onToggleClicked(bool& toggleValue) { + unselectAll(); + + // Search for the actual toggle triggering the event + int i; + for (i = 0; i < guiGroup.getNumControls(); i++) { + ofxToggle* toggle = static_cast(guiGroup.getControl(i)); + ofParameter* paramPtr = + static_cast*>(&toggle->getParameter()); + + if (&(paramPtr->get()) == &toggleValue) { + selectItem(i); + break; + } + } +} +} +} diff --git a/src/ui/RadioList.h b/src/ui/RadioList.h new file mode 100644 index 0000000..45b7327 --- /dev/null +++ b/src/ui/RadioList.h @@ -0,0 +1,51 @@ +#pragma once + +#include "ofGraphics.h" +#include "ofxGuiGroup.h" +#include "ofxToggle.h" +#include "ofxLabel.h" + +namespace ofx { +namespace piMapper { +class RadioList { + public: + RadioList(); + RadioList(vector &labels); + RadioList(string title, vector &labels); + ~RadioList(); + + void setup(vector &labels); + void setup(string title, vector &labels); + void draw(); + void setTitle(string title); + void setPosition(ofPoint p); + void setPosition(float x, float y); + void selectItem(int index); + void enable(); + void disable(); + void clear(); + void unselectAll(); + ofPoint getPosition(); + float getWidth(); + float getHeight(); + string getTitle(); + string getItemName(int index); + int size(); + + // This event notifies about a toggle being selected and passes it's name to + // the listeners. + // Use ofAddListener(RadioListInstance.radioSelectedEvent, listenerClassPtr, + // &listenerClass::listenerMethod) + // to listen to this. Listner method void listenerMethod(string & radioName) + ofEvent radioSelectedEvent; + + private: + vector storedLabels; + string storedTitle; + ofxGuiGroup guiGroup; + int storedSelectedItem; + + void onToggleClicked(bool &toggleValue); +}; +} +} \ No newline at end of file diff --git a/src/ui/ofxRadioList.cpp b/src/ui/ofxRadioList.cpp deleted file mode 100644 index e974284..0000000 --- a/src/ui/ofxRadioList.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include "ofxRadioList.h" - -ofxRadioList::ofxRadioList() -{ - storedTitle = ""; - storedSelectedItem = 0; -} - -ofxRadioList::ofxRadioList(vector &labels) -{ - ofxRadioList(); - setup(labels); -} - -ofxRadioList::ofxRadioList(string title, vector &labels) -{ - ofxRadioList(); - setup(title, labels); -} - -ofxRadioList::~ofxRadioList() -{ - clear(); -} - -void ofxRadioList::setup(vector &labels) -{ - // Copy incomming labels for later use - storedLabels = labels; - - // Create toggles with labels from the labels arg - int i; - for (i = 0; i < labels.size(); i++) { - ofxToggle* toggle = new ofxToggle(); - toggle->setup(false); - toggle->setName(labels[i]); - toggle->addListener(this, &ofxRadioList::onToggleClicked); - guiGroup.add(toggle); - } - - cout << "num items: " << guiGroup.getNumControls() << endl; -} - -void ofxRadioList::setup(string title, vector &labels) -{ - // Store title for later use - storedTitle = title; - guiGroup.setName(title); - setup(labels); -} - -void ofxRadioList::draw() -{ - guiGroup.draw(); -} - -void ofxRadioList::setTitle(string title) -{ - storedTitle = title; - guiGroup.setName(title); -} - -void ofxRadioList::setPosition(ofPoint p) -{ - guiGroup.setPosition(p); -} - -void ofxRadioList::setPosition(float x, float y) -{ - guiGroup.setPosition(x, y); -} - -void ofxRadioList::selectItem(int index) -{ - if (index >= guiGroup.getNumControls()) { - return; - } - - unselectAll(); - - ofxToggle* toggle = static_cast(guiGroup.getControl(index)); - toggle->removeListener(this, &ofxRadioList::onToggleClicked); - *toggle = true; // Select the specific radio button - toggle->addListener(this, &ofxRadioList::onToggleClicked); - string name = toggle->getName(); - ofNotifyEvent(radioSelectedEvent, name, this); - - storedSelectedItem = index; -} - -void ofxRadioList::enable() -{ - if (guiGroup.getNumControls() >= 0) { - clear(); - } - - // Rebuild everyting - setup(storedTitle, storedLabels); - - // Select the stored selected item without throwing an event - ofxToggle* toggle = static_cast(guiGroup.getControl(storedSelectedItem)); - toggle->removeListener(this, &ofxRadioList::onToggleClicked); - *toggle = true; - toggle->addListener(this, &ofxRadioList::onToggleClicked); - - cout << "num items after enable: " << guiGroup.getNumControls() << endl; -} - -void ofxRadioList::disable() -{ - // Just remove everything - clear(); -} - -void ofxRadioList::clear() -{ - int i; - for (i = 0; i < guiGroup.getNumControls(); i++) { - ofxToggle* toggle = static_cast(guiGroup.getControl(i)); - toggle->removeListener(this, &ofxRadioList::onToggleClicked); - delete toggle; - } - guiGroup.clear(); -} - -void ofxRadioList::unselectAll() -{ - int i; - for (i = 0; i < guiGroup.getNumControls(); i++) { - ofxToggle* toggle = static_cast(guiGroup.getControl(i)); - ofParameter* paramPtr = static_cast*>(&toggle->getParameter()); - toggle->removeListener(this, &ofxRadioList::onToggleClicked); - *toggle = false; - toggle->addListener(this, &ofxRadioList::onToggleClicked); - } -} - -ofPoint ofxRadioList::getPosition() -{ - return guiGroup.getPosition(); -} - -float ofxRadioList::getWidth() -{ - return guiGroup.getWidth(); -} - -float ofxRadioList::getHeight() -{ - return guiGroup.getHeight(); -} - -string ofxRadioList::getTitle() -{ - return guiGroup.getName(); -} - -string ofxRadioList::getItemName(int index) -{ - if (index >= guiGroup.getNumControls()) { - return ""; - } - - ofxToggle* toggle = static_cast(guiGroup.getControl(index)); - return toggle->getName(); -} - -int ofxRadioList::size() -{ - return guiGroup.getNumControls(); -} - -void ofxRadioList::onToggleClicked(bool &toggleValue) -{ - unselectAll(); - - // Search for the actual toggle triggering the event - int i; - for (i = 0; i < guiGroup.getNumControls(); i++) { - ofxToggle* toggle = static_cast(guiGroup.getControl(i)); - ofParameter* paramPtr = static_cast*>(&toggle->getParameter()); - - if (&(paramPtr->get()) == &toggleValue) { - selectItem(i); - break; - } - } -} diff --git a/src/ui/ofxRadioList.h b/src/ui/ofxRadioList.h deleted file mode 100644 index 2736352..0000000 --- a/src/ui/ofxRadioList.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "ofGraphics.h" -#include "ofxGuiGroup.h" -#include "ofxToggle.h" -#include "ofxLabel.h" - -class ofxRadioList -{ -public: - ofxRadioList(); - ofxRadioList(vector &labels); - ofxRadioList(string title, vector &labels); - ~ofxRadioList(); - - void setup(vector &labels); - void setup(string title, vector &labels); - void draw(); - void setTitle(string title); - void setPosition(ofPoint p); - void setPosition(float x, float y); - void selectItem(int index); - void enable(); - void disable(); - void clear(); - void unselectAll(); - ofPoint getPosition(); - float getWidth(); - float getHeight(); - string getTitle(); - string getItemName(int index); - int size(); - - // This event notifies about a toggle being selected and passes it's name to the listeners. - // Use ofAddListener(ofxRadioListInstance.radioSelectedEvent, listenerClassPtr, &listenerClass::listenerMethod) - // to listen to this. Listner method void listenerMethod(string & radioName) - ofEvent radioSelectedEvent; - -private: - vector storedLabels; - string storedTitle; - ofxGuiGroup guiGroup; - int storedSelectedItem; - - void onToggleClicked(bool &toggleValue); -}; \ No newline at end of file