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.
 
 

249 lines
6.0 KiB

#include "GridWarpSurface.h"
namespace ofx {
namespace piMapper {
GridWarpSurface::GridWarpSurface(){
_gridCols = 2;
_gridRows = 2;
createGridMesh();
}
void GridWarpSurface::draw(){
if(source->getTexture() == 0){
return;
}
if(!source->getTexture()->isAllocated()){
return;
}
bool normalizedTexCoords = ofGetUsingNormalizedTexCoords();
ofEnableNormalizedTexCoords();
source->getTexture()->bind();
mesh.draw();
source->getTexture()->unbind();
if(!normalizedTexCoords){
ofDisableNormalizedTexCoords();
}
}
void GridWarpSurface::moveBy(Vec3 v){
for(int i = 0; i < mesh.getVertices().size(); i++){
mesh.getVertices()[i] += v.toOf();
}
setMoved(true);
std::vector<Vec3> vertices = Vec3::fromOf(mesh.getVertices());
ofNotifyEvent(verticesChangedEvent, vertices, this);
}
int GridWarpSurface::getType(){
return SurfaceType::GRID_WARP_SURFACE;
}
int GridWarpSurface::getGridRows(){
return _gridRows;
}
int GridWarpSurface::getGridCols(){
return _gridCols;
}
int GridWarpSurface::setGridRows(int r){
_gridRows = r;
createGridMesh();
}
int GridWarpSurface::setGridCols(int c){
_gridCols = c;
createGridMesh();
}
bool GridWarpSurface::hitTest(Vec2 p){
ofPolyline pl;
int vertsPerRow = _gridCols + 1;
for(int iy = 0; iy < _gridRows; ++iy){
for(int ix = 0; ix < _gridCols; ++ix){
int a = (iy * vertsPerRow) + ix;
int b = (iy * vertsPerRow) + ix + 1;
int c = ((iy + 1) * vertsPerRow) + ix + 1;
int d = ((iy + 1) * vertsPerRow) + ix;
pl.clear();
pl.addVertex(mesh.getVertex(a));
pl.addVertex(mesh.getVertex(b));
pl.addVertex(mesh.getVertex(c));
pl.addVertex(mesh.getVertex(d));
pl.close();
if(pl.inside(p.x, p.y)){
return true;
}
}
}
return false;
}
ofPolyline GridWarpSurface::getHitArea(){
ofPolyline pl;
int vertsPerRow = _gridCols + 1;
// Get the top border
for(int ix = 0; ix <= _gridCols; ++ix){
pl.addVertex(mesh.getVertex(ix));
}
// Get right border from top down
for(int iy = 1; iy <= _gridRows; ++iy){
int i = iy * vertsPerRow + vertsPerRow - 1;
pl.addVertex(mesh.getVertex(i));
}
// Get bottom border from right to left
for(int ix = _gridCols; ix >= 0; --ix){
int i = _gridRows * vertsPerRow + vertsPerRow - 2;
pl.addVertex(mesh.getVertex(i));
}
// Get left border from bottom to top
for(int iy = _gridRows; iy > 0; --iy){
int i = iy * vertsPerRow;
pl.addVertex(mesh.getVertex(i));
}
pl.close();
return pl;
}
ofPolyline GridWarpSurface::getTextureHitArea(){
ofPolyline line;
Vec2 textureSize = Vec2(source->getTexture()->getWidth(), source->getTexture()->getHeight());
int vertsPerRow = _gridCols + 1;
int vertsPerCol = _gridRows + 1;
int a = 0;
int b = _gridCols;
int c = (_gridRows * vertsPerRow) + (vertsPerRow - 1);
int d = (_gridRows * vertsPerRow);
line.addVertex(ofPoint(mesh.getTexCoords()[a] * textureSize.toOf()));
line.addVertex(ofPoint(mesh.getTexCoords()[b] * textureSize.toOf()));
line.addVertex(ofPoint(mesh.getTexCoords()[c] * textureSize.toOf()));
line.addVertex(ofPoint(mesh.getTexCoords()[d] * textureSize.toOf()));
line.close();
return line;
}
void GridWarpSurface::setVertex(int index, Vec3 vert){
if(index >= mesh.getVertices().size()){
throw runtime_error("Vertex with provided index does not exist");
}
mesh.setVertex(index, vert.toOf());
ofNotifyEvent(vertexChangedEvent, index, this);
}
void GridWarpSurface::setVertices(std::vector<Vec3> v){
if(v.size() != mesh.getVertices().size()){
throw runtime_error("Wrong number of vertices");
}
for(int i = 0; i < v.size(); ++i){
mesh.setVertex(i, v[i].toOf());
}
std::vector<Vec3> vertices = Vec3::fromOf(mesh.getVertices());
ofNotifyEvent(verticesChangedEvent, vertices, this);
}
void GridWarpSurface::setTexCoord(int index, Vec2 t){
if(index >= mesh.getVertices().size()){
throw runtime_error("Texture coordinate with provided index does not exist");
}
mesh.setTexCoord(index, t.toOf());
}
void GridWarpSurface::setTexCoords(std::vector<Vec2> t){
if(t.size() != mesh.getVertices().size()){
throw runtime_error("Wrong number of texture coordinates");
}
for(int i = 0; i < t.size(); ++i){
mesh.setTexCoord(i, t[i].toOf());
}
}
std::vector<Vec3> GridWarpSurface::getVertices(){
return Vec3::fromOf(mesh.getVertices());
}
std::vector<Vec2> GridWarpSurface::getTexCoords(){
return Vec2::fromOf(mesh.getTexCoords());
}
void GridWarpSurface::createGridMesh(){
mesh.clear();
float margin = 100.0f;
float surfaceWidth = (float)ofGetWidth() - margin * 2.0f;
float surfaceHeight = (float)ofGetHeight() - margin * 2.0f;
float vertexDistanceX = surfaceWidth / (float)_gridCols;
float vertexDistanceY = surfaceHeight / (float)_gridRows;
// Add vertices for each col and row
for(int iy = 0; iy <= _gridRows; ++iy){
for(int ix = 0; ix <= _gridCols; ++ix){
mesh.addVertex(Vec3(
margin + (vertexDistanceX * (float)ix),
margin + (vertexDistanceY * (float)iy),
0.0f).toOf());
}
}
int vertsPerCol = _gridRows + 1;
int vertsPerRow = _gridCols + 1;
// Form triangles for all grid cols and rows
for(int iy = 0; iy < _gridRows; ++iy){
for(int ix = 0; ix < _gridCols; ++ix){
int a = (iy * vertsPerRow) + ix;
int b = (iy * vertsPerRow) + ix + 1;
int c = ((iy + 1) * vertsPerRow) + ix + 1;
int d = ((iy + 1) * vertsPerRow) + ix;
mesh.addTriangle(a, b, c);
mesh.addTriangle(a, c, d);
}
}
// Add texture coordinates for each of the vertices
for(int iy = 0; iy <= _gridRows; ++iy){
for(int ix = 0; ix <= _gridCols; ++ix){
float xc = (ix == 0) ? 0.0f : (float)ix / (float)_gridCols;
float yc = (iy == 0) ? 0.0f : (float)iy / (float)_gridRows;
mesh.addTexCoord(Vec2(xc, yc).toOf());
}
}
std::vector<Vec3> vertices = Vec3::fromOf(mesh.getVertices());
ofNotifyEvent(verticesChangedEvent, vertices, this);
}
BaseSurface * GridWarpSurface::clone(){
GridWarpSurface * s = new GridWarpSurface();
s->setVertices(getVertices());
s->setTexCoords(getTexCoords());
BaseSource * src = getSource();
src->referenceCount++;
s->setSource(src);
return s;
}
} // namespace piMapper
} // namespace ofx