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

357 lines
8.7 KiB

#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 == 0){
return;
}
// update surface if one of the joints is being dragged
ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(),
surface->getSource()->getTexture()->getHeight());
// Get selected joint index
int selectedJointIndex = 0;
bool bJointSelected = false;
for(int i = 0; i < joints.size(); i++){
if(joints[i]->isDragged() || joints[i]->isSelected()){
selectedJointIndex = i;
bJointSelected = true;
break;
}
} // for
// Constrain quad texture selection
if(joints.size() == 4){
if(bJointSelected){
constrainJointsToQuad(selectedJointIndex);
if(surface->getType() == SurfaceType::GRID_WARP_SURFACE){
GridWarpSurface * s = (GridWarpSurface *)surface;
vector <ofVec2f> & texCoords = surface->getTexCoords();
ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(),
surface->getSource()->getTexture()->getHeight());
int rows = s->getGridRows();
int cols = s->getGridCols();
int vertsPerRow = cols + 1;
int vertsPerCol = rows + 1;
int a = 0;
int b = cols;
int c = (rows * vertsPerRow) + (vertsPerRow - 1);
int d = (rows * vertsPerRow);
// Distance between horizontal tex coords
float sx = joints[0]->position.x / textureSize.x;
float ex = joints[1]->position.x / textureSize.x;
float dx = (ex - sx) / (float)cols;
// Distance between vertical tex coords
float sy = joints[0]->position.y / textureSize.y;
float ey = joints[2]->position.y / textureSize.y;
float dy = (ey - sy) / (float)rows;
int i = 0;
for(int iy = 0; iy <= rows; ++iy){
for(int ix = 0; ix <= cols; ++ix){
ofVec2f t;
t.x = sx + dx * ix;
t.y = sy + dy * iy;
surface->setTexCoord(i, t);
++i;
}
}
}else{
for(int i = 0; i < joints.size(); i++){
surface->setTexCoord(i, joints[i]->position / textureSize);
}
}
} // if
}else{
if(bJointSelected){
surface->setTexCoord(selectedJointIndex, joints[selectedJointIndex]->position / textureSize);
}
} // else
}
void TextureEditor::keyPressed(ofKeyEventArgs & args){
int key = args.key;
float moveStep;
if(bShiftKeyDown){
moveStep = 10.0f;
}else{
moveStep = 0.5f;
}
switch(key){
case OF_KEY_LEFT:
moveSelection(ofVec2f(-moveStep, 0.0f));
break;
case OF_KEY_RIGHT:
moveSelection(ofVec2f(moveStep, 0.0f));
break;
case OF_KEY_UP:
moveSelection(ofVec2f(0.0f, -moveStep));
break;
case OF_KEY_DOWN:
moveSelection(ofVec2f(0.0f, moveStep));
break;
case OF_KEY_SHIFT:
bShiftKeyDown = true;
break;
}
}
void TextureEditor::keyReleased(ofKeyEventArgs & args){
int key = args.key;
switch(key){
case OF_KEY_SHIFT:
bShiftKeyDown = false;
break;
}
}
void TextureEditor::draw(){
if(surface == 0){
return;
}
// Reset default color to white
ofSetColor(255, 255, 255, 255);
drawJoints();
}
void TextureEditor::drawJoints(){
for(int i = 0; i < joints.size(); i++){
joints[i]->draw();
}
}
void TextureEditor::setSurface(BaseSurface * newSurface){
surface = newSurface;
createJoints();
}
void TextureEditor::clear(){
surface = 0;
clearJoints();
}
void TextureEditor::createJoints(){
if(surface == 0){
return;
}
clearJoints();
vector <ofVec2f> & texCoords = surface->getTexCoords();
ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(),
surface->getSource()->getTexture()->getHeight());
// Select joints depending on the surface type
vector <ofVec2f> tc;
if(surface->getType() == SurfaceType::TRIANGLE_SURFACE){
tc = texCoords;
}else if(surface->getType() == SurfaceType::QUAD_SURFACE){
tc = texCoords;
}else if(surface->getType() == SurfaceType::GRID_WARP_SURFACE){
GridWarpSurface * s = (GridWarpSurface *)surface;
int rows = s->getGridRows();
int cols = s->getGridCols();
int vertsPerRow = cols + 1;
int vertsPerCol = rows + 1;
int a = 0;
int b = cols;
int c = (rows * vertsPerRow) + (vertsPerRow - 1);
int d = (rows * vertsPerRow);
tc.push_back(texCoords[a]);
tc.push_back(texCoords[b]);
tc.push_back(texCoords[c]);
tc.push_back(texCoords[d]);
}
for(int i = 0; i < tc.size(); i++){
joints.push_back(new CircleJoint());
joints.back()->position = tc[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 == 0){
return;
}
vector <ofVec2f> & texCoords = surface->getTexCoords();
ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(),
surface->getSource()->getTexture()->getHeight());
if(surface->getType() == SurfaceType::GRID_WARP_SURFACE){
GridWarpSurface * s = (GridWarpSurface *)surface;
int rows = s->getGridRows();
int cols = s->getGridCols();
int vertsPerRow = cols + 1;
int vertsPerCol = rows + 1;
int a = 0;
int b = cols;
int c = (rows * vertsPerRow) + (vertsPerRow - 1);
int d = (rows * vertsPerRow);
// Distance between horizontal tex coords
float sx = joints[0]->position.x / textureSize.x;
float ex = joints[1]->position.x / textureSize.x;
float dx = (ex - sx) / (float)cols;
// Distance between vertical tex coords
float sy = joints[0]->position.y / textureSize.y;
float ey = joints[2]->position.y / textureSize.y;
float dy = (ey - sy) / (float)rows;
int i = 0;
for(int iy = 0; iy <= rows; ++iy){
for(int ix = 0; ix <= cols; ++ix){
ofVec2f t;
t.x = sx + dx * ix;
t.y = sy + dy * iy;
surface->setTexCoord(i, t);
++i;
}
}
}else{
for(int i = 0; i < texCoords.size(); i++){
joints[i]->position += by;
surface->setTexCoord(i, joints[i]->position / textureSize);
}
}
}
void TextureEditor::stopDragJoints(){
for(int i = 0; i < joints.size(); i++){
joints[i]->stopDrag();
}
}
void TextureEditor::moveSelection(ofVec2f by){
// check if joints selected
bool bJointSelected = false;
BaseJoint * selectedJoint;
for(int i = 0; i < joints.size(); i++){
if(joints[i]->isSelected()){
bJointSelected = true;
selectedJoint = joints[i];
break;
}
}
if(bJointSelected){
selectedJoint->position += by;
}else{
moveTexCoords(by);
}
}
void TextureEditor::constrainJointsToQuad(int selectedJointIndex){
switch(selectedJointIndex){
case 0:
joints[1]->position = ofVec2f(joints[1]->position.x, joints[0]->position.y);
joints[2]->position = ofVec2f(joints[1]->position.x, joints[3]->position.y);
joints[3]->position = ofVec2f(joints[0]->position.x, joints[3]->position.y);
break;
case 1:
joints[0]->position = ofVec2f(joints[0]->position.x, joints[1]->position.y);
joints[2]->position = ofVec2f(joints[1]->position.x, joints[2]->position.y);
joints[3]->position = ofVec2f(joints[0]->position.x, joints[2]->position.y);
break;
case 2:
joints[1]->position = ofVec2f(joints[2]->position.x, joints[1]->position.y);
joints[3]->position = ofVec2f(joints[3]->position.x, joints[2]->position.y);
joints[0]->position = ofVec2f(joints[3]->position.x, joints[1]->position.y);
break;
case 3:
joints[0]->position = ofVec2f(joints[3]->position.x, joints[0]->position.y);
joints[2]->position = ofVec2f(joints[2]->position.x, joints[3]->position.y);
joints[1]->position = ofVec2f(joints[2]->position.x, joints[0]->position.y);
break;
} // switch
}
CircleJoint * TextureEditor::hitTestJoints(ofVec2f pos){
for(int i = 0; i < joints.size(); i++){
if(joints[i]->hitTest(pos)){
return joints[i];
}
}
return 0;
}
vector <CircleJoint *> & TextureEditor::getJoints(){
return joints;
}
} // namespace piMapper
} // namespace ofx