679 lines
18 KiB
Plaintext
Executable File
679 lines
18 KiB
Plaintext
Executable File
/* Simple vector painter */
|
|
|
|
//OpenGL import
|
|
//import processing.opengl.*;
|
|
|
|
//ControlP5
|
|
import controlP5.*;
|
|
ControlP5 controlP5;
|
|
int uiWidth = 256;
|
|
int uiHeight = 512;
|
|
|
|
//Draw Buffer
|
|
public PGraphics drawBuff;
|
|
public PImage present;
|
|
public PImage undoBuff;
|
|
public PImage region;
|
|
public PImage blendBrush;
|
|
|
|
PImage flowMap; // Declare variable "a" of type PImage
|
|
PImage flowDetail;
|
|
PImage flowBrush;
|
|
|
|
//flowmap path
|
|
String flowMapPath = "";
|
|
|
|
//mouse stuff
|
|
|
|
float oldMX;
|
|
float oldMY;
|
|
int bs = 20;
|
|
boolean bover = false;
|
|
boolean locked = false;
|
|
float bdifx = 0.0;
|
|
float bdify = 0.0;
|
|
|
|
//last normalVec
|
|
float old_nVecX, old_nVecY;
|
|
PVector v2 = new PVector(mouseX, mouseY);
|
|
PVector v4 = new PVector(pmouseX, pmouseY);
|
|
|
|
//FlowMap
|
|
int bmpX = 511;
|
|
int bmpY = 511;
|
|
|
|
//painting params
|
|
int brushSize = 32;
|
|
int flowSpeed = 255;
|
|
int speedScale = 0;
|
|
|
|
|
|
//line history store previous mouse positions
|
|
int lHMax = 5;
|
|
//float lineHistory[][] = new float[lHMax][lHMax];
|
|
ArrayList mPositions = new ArrayList();
|
|
ArrayList leadingEdgeHistory = new ArrayList();
|
|
|
|
color lastColour = color(127, 127, 127, 0);
|
|
|
|
float xBuffer[] = new float[lHMax];
|
|
float yBuffer[] = new float[lHMax];
|
|
|
|
//Painting modes
|
|
//paintSmear 1==paint 0==smear
|
|
boolean paintSmear = true;
|
|
//Draw flow = 1 edges = 0
|
|
boolean flowEdge = false;
|
|
|
|
boolean undo = true;
|
|
|
|
int updateCounter = lHMax;
|
|
|
|
float normColour = 0.003921568627451;
|
|
|
|
int zoom = 1;
|
|
|
|
//////////////////////////////////////////////////////
|
|
//FUNCTIONS//////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
void setup()
|
|
{
|
|
size(bmpX+256, bmpY);
|
|
//frameRate(200);
|
|
background(64);
|
|
|
|
smooth();
|
|
//Controls
|
|
controlP5 = new ControlP5(this);
|
|
|
|
// begin a new group of auto-arranged controllers
|
|
createControlGroup();
|
|
|
|
//drawBuffer
|
|
drawBuff = createGraphics(bmpX+1, bmpY+1, P3D);
|
|
|
|
flowMap = loadImage("X:/gta5/art/Textures/water/CS3_05_WaterMesh02FLOW.bmp"); // Load the image into the program
|
|
flowDetail = loadImage("c:/temp/flowDetail2.tga");
|
|
flowBrush = requestImage("C:/Users/neil.gregory/Documents/Processing/flowPainter/flowBrush.tga");
|
|
|
|
//init line history
|
|
for(int i=0; i<lHMax; i++)
|
|
{
|
|
xBuffer[i] = 0;
|
|
yBuffer[i] = 0;
|
|
}
|
|
|
|
//stick something in the drawBuffer
|
|
drawBuff.beginDraw();
|
|
drawBuff.background(127, 127, 127, 0);
|
|
drawBuff.noStroke();
|
|
//drawBuff.imageMode(CENTER);
|
|
drawBuff.image(flowMap, 0, 0);
|
|
drawBuff.endDraw();
|
|
present = drawBuff.get(0, 0, bmpX, bmpY);
|
|
undoBuff = present.get(0, 0, bmpX, bmpY);
|
|
blendBrush = flowBrush.get(0, 0, brushSize, brushSize);
|
|
|
|
}
|
|
|
|
public void createControlGroup()
|
|
{
|
|
//controlP5.begin(bmpX+10,10);
|
|
|
|
controlP5.ControlGroup grpUI = controlP5.addGroup("Controls", bmpX, 0, uiWidth);
|
|
grpUI.setBackgroundColor(color(64, 64, 64, 0));
|
|
grpUI.hideBar();
|
|
|
|
controlP5.Slider sldBrushSize = controlP5.addSlider("BrushSize", 1, 50);
|
|
sldBrushSize.setPosition( 15, 15 );
|
|
sldBrushSize.setNumberOfTickMarks(10);
|
|
sldBrushSize.showTickMarks(true);
|
|
sldBrushSize.snapToTickMarks(false);
|
|
sldBrushSize.moveTo(grpUI);
|
|
|
|
controlP5.Slider sldFlowSpeed = controlP5.addSlider("FlowSpeed", 1, 255);
|
|
sldFlowSpeed.setPosition( 15, 45 );
|
|
sldFlowSpeed.setNumberOfTickMarks(16);
|
|
sldFlowSpeed.showTickMarks(true);
|
|
sldFlowSpeed.snapToTickMarks(false);
|
|
sldFlowSpeed.moveTo(grpUI);
|
|
|
|
controlP5.Slider sldSpeedScale = controlP5.addSlider("SpeedScale", -30, 30);
|
|
sldSpeedScale.setValue(speedScale);
|
|
sldSpeedScale.setPosition(15, 75);
|
|
//sldSpeedScale.setNumberOfTickMarks(10);
|
|
//sldSpeedScale.showTickMarks(true);
|
|
sldSpeedScale.moveTo(grpUI);
|
|
|
|
//controlP5.addButton("Smear").linebreak();
|
|
controlP5.Toggle tglPaintSmear = controlP5.addToggle("PaintSmear",false, 15, 100, 60, 20);
|
|
tglPaintSmear.setMode(ControlP5.SWITCH);
|
|
tglPaintSmear.moveTo(grpUI);
|
|
|
|
controlP5.Toggle tglFE = controlP5.addToggle("FlowEdging",false, 15, 140, 60, 20);
|
|
tglFE.setMode(ControlP5.SWITCH);
|
|
tglFE.setLabel("Flow / Edging");
|
|
tglFE.moveTo(grpUI);
|
|
|
|
//flowDir
|
|
//controlP5.Knob flowDir = controlP5.addKnob("FlowDir", -360, 360, 180, 150, 160, 60);
|
|
//flowDir.moveTo(grpUI);
|
|
|
|
//Buttons
|
|
//
|
|
controlP5.Bang bngDetail = controlP5.addBang("GenDetailMap", 15, 200, 100, 30);
|
|
bngDetail.setLabel("Generate Detail Map");
|
|
bngDetail.moveTo(grpUI);
|
|
controlP5.Bang bngUndo = controlP5.addBang("Undo", 15, 300, 60, 30);
|
|
bngUndo.moveTo(grpUI);
|
|
controlP5.Bang bngLoad = controlP5.addBang("Load", 15, 350, 60, 30);
|
|
bngLoad.moveTo(grpUI);
|
|
controlP5.Bang bngSave = controlP5.addBang("Save", 15, 400, 60, 30);
|
|
bngSave.moveTo(grpUI);
|
|
controlP5.Bang bngQuit = controlP5.addBang("Quit", 15, 450, 60, 30);
|
|
bngQuit.moveTo(grpUI);
|
|
|
|
//controlP5.end();
|
|
|
|
}
|
|
|
|
void draw()
|
|
{
|
|
// Displays the image at its actual size at point (0,0)
|
|
|
|
image(present, 0, 0);
|
|
|
|
}
|
|
|
|
public void getImageRegion()
|
|
{
|
|
int brushOffset = floor(brushSize/2);
|
|
//int mx = constrain(mouseX, brushOffset, drawBuff.width - brushOffset);
|
|
int mx = mouseX - brushOffset;
|
|
//int my = constrain(mouseY, brushOffset, drawBuff.height - brushOffset);
|
|
int my = mouseY - brushOffset;
|
|
|
|
if(mx > 480)
|
|
{
|
|
mx = 480;
|
|
}
|
|
if(my > 480)
|
|
{
|
|
my = 480;
|
|
}
|
|
//region = drawBuff.get(mx-brushOffset, my-brushOffset, brushSize, brushSize);
|
|
region = drawBuff.get(mx, my, brushSize, brushSize);
|
|
|
|
}
|
|
|
|
public void regionBlend()
|
|
{
|
|
int brushOffset = (brushSize/2);
|
|
//region.blend(flowBrush, 0, 0, brushSize, brushSize, 0, 0, brushSize, brushSize, OVERLAY);
|
|
|
|
//get flow brush and resize
|
|
blendBrush = flowBrush.get(0, 0, flowBrush.width-1, flowBrush.height-1);
|
|
blendBrush.resize(brushSize, 0);
|
|
|
|
//load pixel arrays
|
|
region.loadPixels();
|
|
blendBrush.loadPixels();
|
|
|
|
//blend colours
|
|
for( int i=0; i < region.pixels.length; i++ )
|
|
{
|
|
//println(hex(region.pixels[i]));
|
|
//return;
|
|
//region.pixels[i] = min(region.pixels[i] + blendBrush.pixels[i], 255);
|
|
color srcCol = region.pixels[i];
|
|
float srcColR = srcCol >> 16 & 0xFF;
|
|
float srcColG = srcCol >> 8 & 0xFF;
|
|
float srcColB = srcCol & 0xFF;
|
|
srcColB = constrain(1.0 - (1.0 / srcColB), 0.0, 1.0);
|
|
float vecX = -1.0 + 2.0 * (srcColR / 255.0);
|
|
float vecY = -1.0 + 2.0 * (srcColG / 255.0);
|
|
//float srcColB = srcCol & 0xFF;
|
|
|
|
//float srcColA = alpha(srcCol);
|
|
|
|
color dstCol = blendBrush.pixels[i];
|
|
float dstColA = constrain(1.0 - (1.0 / alpha(dstCol)), 0.0, 1.0);
|
|
if( dstColA > 0.0)
|
|
{
|
|
//println(dstColA);
|
|
//println(srcColR);
|
|
//scale by brush
|
|
//color newCol = color(dstColA * srcColR, dstColA * srcColG, dstColA * srcColB);
|
|
//color newCol = color(srcColR*dstColA, srcColG*dstColA, srcColB*dstColA);
|
|
//float newColR = newCol >> 16 & 0xFF;
|
|
//float newColG = newCol >> 8 & 0xFF;
|
|
//float newColB = newCol & 0xFF;
|
|
//add to colour
|
|
//float addCol = constrain(5.0 * dstColA, 0.0, 5.0);
|
|
float addColR = (vecX * speedScale)*dstColA;
|
|
float addColG = (vecY * speedScale)*dstColA;
|
|
//println(addColR);
|
|
//println(addColG);
|
|
//println(addCol);
|
|
//color newCol = color((srcColR*dstColA)+addCol, (srcColG*dstColA)+addCol, 127);
|
|
//color newCol = color();
|
|
//check limits
|
|
//if( srcColR < 255 && srcColG < 255 )
|
|
//{
|
|
color newCol = color(srcColR+addColR, srcColG+addColG, 127);
|
|
region.pixels[i] = newCol;
|
|
//}
|
|
}
|
|
|
|
}
|
|
|
|
region.updatePixels();
|
|
//blendBrush.updatePixels();
|
|
|
|
//blendBrush.blend(region, 0, 0, brushSize, brushSize, 0, 0, brushSize, brushSize, OVERLAY);
|
|
//image(region, 0, 0);
|
|
//region.blend(flowBrush, 0, 0, flowBrush.width, flowBrush.height, 0, 0, brushSize, brushSize, ADD);
|
|
//region.blend(flowBrush, brushOffset, brushOffset, brushSize, brushSize, 0, 0, brushSize, brushSize, ADD);
|
|
//region.blend(flowBrush, brushOffset, brushOffset, brushSize, brushSize, 0, 0, brushSize, brushSize, LIGHTEST);
|
|
//region.blend(region, 0, 0, brushSize, brushSize, 0, 0, brushSize, brushSize, MULTIPLY);
|
|
//region.blend(region, 0, 0, brushSize, brushSize, 0, 0, brushSize, brushSize, ADD);
|
|
|
|
}
|
|
|
|
void mousePressed()
|
|
{
|
|
//Cursor change
|
|
cursor(CROSS);
|
|
|
|
//clear the mouse positions ArrayList
|
|
mPositions.clear();
|
|
|
|
//Store the current image in the undo buffer
|
|
undoBuff = drawBuff.get(0, 0, bmpX, bmpY);
|
|
//undoBuff = flowMap.get(0, 0, flowMap.width, flowMap.height);
|
|
//undoBuff.loadPixels();
|
|
//undoBuff.updatePixels();
|
|
}
|
|
|
|
void mouseDragged()
|
|
{
|
|
//undoBuff = drawBuff.get(0, 0, drawBuff.width, drawBuff.height);
|
|
//mouse history average
|
|
float mAvgX = 0.0;
|
|
float mAvgY = 0.0;
|
|
|
|
for(int i=0; i < mPositions.size(); i++)
|
|
{
|
|
float mPos[] = (float[])mPositions.get(i);
|
|
mAvgX += mPos[0];
|
|
mAvgY += mPos[1];
|
|
}
|
|
mAvgX = mAvgX / (float)lHMax;
|
|
mAvgY = mAvgY / (float)lHMax;
|
|
|
|
//what kinda paintin' we doin'
|
|
//
|
|
|
|
//grab under the mouse
|
|
getImageRegion();
|
|
//Now blend with the brush
|
|
regionBlend();
|
|
|
|
//stuff back in the image
|
|
|
|
//drawBuff.imageMode(CENTER);
|
|
int brushOffset = brushSize/2;
|
|
drawBuff.set(mouseX-brushOffset, mouseY-brushOffset, region);
|
|
//drawBuff.blend(flowBrush, mouseX, mouseY, brushSize, brushSize, drawBuff.width, drawBuff.height, 10, 10, DIFFERENCE);
|
|
//drawBuff.tint(255, 0, 0);
|
|
//region.blend(drawBuff, 0, 0, brushSize, brushSize, mouseX - (brushSize/2), mouseY - (brushSize/2), region.width, region.height, BLEND);
|
|
//drawBuff.image(region, mouseX - floor(brushSize/2), mouseY - floor(brushSize/2), brushSize, brushSize);
|
|
|
|
//drawBuff.image(region, mouseX, mouseY, brushSize, brushSize);
|
|
//drawBuff.set(region, mouseX, mouseY);
|
|
|
|
|
|
if( updateCounter == lHMax )
|
|
{
|
|
//reset counter
|
|
updateCounter = 0;
|
|
/*
|
|
PVector mouseVec = new PVector(mouseX, mouseY);
|
|
PVector pmouseVec = new PVector(oldMX, oldMY);
|
|
PVector flowVec = PVector.sub(mouseVec, pmouseVec);
|
|
|
|
//normalize
|
|
flowVec.normalize();
|
|
|
|
//normal vec to flowVec
|
|
PVector flowNormal = new PVector( flowVec.y, -flowVec.x );
|
|
//PVector flowNormalNeg = PVector.mult(flowNormal, -1);
|
|
PVector flowNormalNeg = new PVector(-flowVec.x, -flowVec.y);
|
|
//scale by brushSize
|
|
flowNormal.mult(brushSize);
|
|
flowNormalNeg.mult(brushSize);
|
|
|
|
//vertex positions
|
|
//
|
|
// v5------v0------v1
|
|
// | | |
|
|
// v4-------v3-----v2
|
|
//
|
|
|
|
PVector v1 = new PVector( mouseX + flowNormal.x, mouseY + flowNormal.y);
|
|
//PVector v2 = new PVector( oldMX + flowNormal.x, oldMY + flowNormal.y);
|
|
//PVector v4 = new PVector( oldMX - flowNormal.x, oldMY - flowNormal.y);
|
|
PVector v5 = new PVector( mouseX - flowNormal.x, mouseY - flowNormal.y);
|
|
|
|
//colour scaling factor
|
|
//float vScale = 0.1 * vecMag;
|
|
|
|
float r = 127 + (127*flowVec.x);
|
|
float g = 127 + (127*flowVec.y);
|
|
float b = 127;
|
|
|
|
if (flowEdge == true) //Draw flows
|
|
{
|
|
drawBuff.beginDraw();
|
|
drawBuff.pushMatrix();
|
|
/*
|
|
drawBuff.beginShape(LINES);
|
|
drawBuff.stroke(255, 255, 255, 255);
|
|
drawBuff.vertex(v1.x, v1.y, 0.0);
|
|
drawBuff.vertex(v5.x, v5.y, 0.0);
|
|
drawBuff.endShape();
|
|
|
|
drawBuff.beginShape(QUADS);
|
|
//quad1
|
|
drawBuff.fill(r, g, b, 255);
|
|
drawBuff.vertex(mouseX, mouseY, 0.0);
|
|
drawBuff.fill(lastColour);
|
|
drawBuff.vertex(oldMX, oldMY, 0.0);
|
|
drawBuff.fill(127, 127, 127, 0);
|
|
drawBuff.vertex( v2.x, v2.y, 0.0);
|
|
drawBuff.vertex( v1.x, v1.y, 0.0);
|
|
//quad2
|
|
drawBuff.fill(r, g, b, 255);
|
|
drawBuff.vertex(mouseX, mouseY, 0.0);
|
|
drawBuff.fill(lastColour);
|
|
drawBuff.vertex(oldMX, oldMY, 0.0);
|
|
drawBuff.fill(127, 127, 127, 0);
|
|
drawBuff.vertex( v4.x, v4.y, 0.0);
|
|
drawBuff.vertex( v5.x, v5.y, 0.0);
|
|
drawBuff.endShape();
|
|
|
|
drawBuff.popMatrix();
|
|
drawBuff.endDraw();
|
|
}
|
|
|
|
else if(flowEdge == false) //Draw edges
|
|
{
|
|
drawBuff.beginDraw();
|
|
drawBuff.pushMatrix();
|
|
drawBuff.beginShape(QUADS);
|
|
drawBuff.fill(r, g, b, 255);
|
|
drawBuff.vertex(mouseX, mouseY, 0.0);
|
|
drawBuff.fill(lastColour);
|
|
drawBuff.vertex(oldMX, oldMY, 0.0);
|
|
drawBuff.fill(127, 127, 127, 0);
|
|
drawBuff.vertex( v2.x, v2.y, 0.0);
|
|
drawBuff.vertex( v1.x, v1.y, 0.0);
|
|
drawBuff.endShape();
|
|
drawBuff.popMatrix();
|
|
drawBuff.endDraw();
|
|
}
|
|
|
|
//present the buffer
|
|
//present = drawBuff.get(0, 0, drawBuff.width, drawBuff.height);
|
|
//present.blend(drawBuff, 0, 0, drawBuff.width, drawBuff.height, 0, 0, present.width, present.height, BLEND);
|
|
//present.blend(flowMap, 0, 0, flowMap.width, flowMap.height, 0, 0, present.width, present.height, OVERLAY);
|
|
|
|
//copy new normal vec to old
|
|
v2 = v1;
|
|
v4 = v5;
|
|
|
|
//Add mouseXY to mPositions
|
|
float mPos[] = new float[2];
|
|
mPos[0] = mouseX;
|
|
mPos[1] = mouseY;
|
|
mPositions.add(mPos);
|
|
|
|
//trim to size
|
|
if( mPositions.size() > lHMax )
|
|
{
|
|
mPositions.remove(0);
|
|
}
|
|
*/
|
|
|
|
|
|
//update lastColour with the current one
|
|
//lastColour = color(r, g, b, 255);
|
|
|
|
}
|
|
|
|
//increment counter
|
|
updateCounter += 1;
|
|
//Add leading edges corner vert positions
|
|
//float v1Pos[] = new float[2];
|
|
//v1Pos[0] =
|
|
//bmpX = (int)(bmpX * (1.0 / zoom));
|
|
//bmpY = (int)(bmpY * (1.0 / zoom));
|
|
//present.blend(drawBuff, 0, 0, drawBuff.width, drawBuff.height, 0, 0, present.width, present.height, BLEND);
|
|
present = drawBuff.get(0, 0, bmpX, bmpY);
|
|
//present = region.get(0, 0, brushSize, brushSize);
|
|
|
|
}
|
|
|
|
void mouseReleased()
|
|
{
|
|
//println(mPositions.size());
|
|
//println(mPositions.get(1));
|
|
//Cursor change
|
|
cursor(ARROW);
|
|
|
|
}
|
|
|
|
//////////////////////////////
|
|
//Key pressed functions
|
|
//////////////////////////////
|
|
|
|
void keyPressed()
|
|
{
|
|
if( key == 'c') //clear screen
|
|
{
|
|
background(127);
|
|
//image(flowMap, 0, 0);
|
|
}
|
|
|
|
if( key == '.') //increase brush size
|
|
{
|
|
brushSize += 1;
|
|
strokeWeight(brushSize);
|
|
}
|
|
|
|
if( key == ',') //decrease brush size
|
|
{
|
|
brushSize -= 1;
|
|
if( brushSize <= 1 )
|
|
{
|
|
brushSize = 1;
|
|
}
|
|
strokeWeight(brushSize);
|
|
}
|
|
|
|
if( key == 'u') //undo hotkey
|
|
{
|
|
drawBuff.set(0, 0, undoBuff);
|
|
present = undoBuff.get(0, 0, bmpX, bmpY);
|
|
image(present, 0, 0);
|
|
}
|
|
|
|
if( key == 'z' ) //Zoom in
|
|
{
|
|
zoom += 1;
|
|
println(zoom);
|
|
}
|
|
|
|
if( key == 'x' ) //Zoom out
|
|
{
|
|
zoom -= 1;
|
|
}
|
|
}
|
|
|
|
/////////////////////
|
|
//ControlP5 events
|
|
////////////////////
|
|
|
|
public void BrushSize(int v)
|
|
{
|
|
brushSize = v;
|
|
}
|
|
|
|
public void FlowSpeed(int v)
|
|
{
|
|
flowSpeed = v;
|
|
}
|
|
|
|
public void SpeedScale(int v)
|
|
{
|
|
speedScale = v;
|
|
}
|
|
|
|
public void FlowEdging(boolean mode)
|
|
{
|
|
if (mode == true)
|
|
{
|
|
flowEdge = true;
|
|
}
|
|
else if (mode == false)
|
|
{
|
|
flowEdge = false;
|
|
}
|
|
|
|
}
|
|
|
|
//Generate a detail flow map from the flowDetail and flowmap
|
|
public void GenDetailMap()
|
|
{
|
|
//create a new PImage
|
|
//PImage detailMap = createImage(flowDetail.width, flowDetail.height, RGB);
|
|
//Process the pixels from flowDetail
|
|
flowDetail.loadPixels();
|
|
flowMap.loadPixels();
|
|
//detailMap.loadPixels();
|
|
int width = flowDetail.width;
|
|
|
|
for(int x=0; x < flowDetail.width; x++)
|
|
{
|
|
for(int y=0; y < flowDetail.height; y++)
|
|
{
|
|
//y = abs(y - flowDetail.height);
|
|
//get colour from detail map as a vector
|
|
color detailCol = flowDetail.pixels[(width-y-1)*width+x]; //y-flip
|
|
|
|
//check for non null colour to process otherwise move on
|
|
if( detailCol != -8355712 )
|
|
{
|
|
//println(detailCol);
|
|
float detailCol_R = detailCol >> 16 & 0xFF;
|
|
float detailCol_G = detailCol >> 8 & 0xFF;
|
|
float detailCol_B = detailCol & 0xFF;
|
|
//Create vec, making sure to remap colour range into cartesian space (-127)
|
|
PVector detailVec = new PVector(detailCol_R - 127, detailCol_G - 127, 0);
|
|
detailVec.normalize();
|
|
//println(detailVec);
|
|
|
|
//get flowmap colour
|
|
color flowMapCol = flowMap.pixels[y*width+x];
|
|
float flowMapCol_R = flowMapCol >> 16 & 0xFF;
|
|
float flowMapCol_G = flowMapCol >> 8 & 0xFF;
|
|
float flowMapCol_B = flowMapCol & 0xFF;
|
|
//Create vec, making sure to remap colour range into cartesian space (-127)
|
|
PVector flowMapVec = new PVector(flowMapCol_R - 127, flowMapCol_G - 127, 0);
|
|
flowMapVec.normalize();
|
|
|
|
//dot of two colour vecs
|
|
float flowProduct = PVector.dot(detailVec, flowMapVec);
|
|
//println(flowProduct);
|
|
//flowProduct = flowProduct - 1.0;
|
|
//println(flowProduct);
|
|
PVector newFlowVec = PVector.sub(flowMapVec, detailVec);
|
|
newFlowVec.normalize();
|
|
//0-1 -> 0-255
|
|
newFlowVec.mult(255);
|
|
//Now blend based on the dot, -ve values opposing flow are strong
|
|
//+ve values are weaken flow
|
|
//0 value has no effect
|
|
|
|
//float diffR = flowMapCol_R + (127 - detailCol_R); //looks promising
|
|
//float diffG = flowMapCol_G - (127 - detailCol_G);
|
|
|
|
float diffR = constrain(flowMapCol_R + (0.5*(newFlowVec.x * flowProduct)), 0, 255);
|
|
float diffG = constrain(flowMapCol_G + (0.5*(newFlowVec.y * flowProduct)), 0, 255);
|
|
//if(flowProduct
|
|
//color newFlow = color(diffR * flowProduct, diffG * flowProduct, flowMapCol_B);
|
|
//color newFlow = color(flowMapCol_R, flowMapCol_G, 127.0);
|
|
//color newFlow = color(flowMapCol_R, flowMapCol_G, 127.0);
|
|
//color newFlow = color(detailCol_R, detailCol_G, 127.0);
|
|
//color result = lerpColor(flowMapCol, newFlow, flowProduct);
|
|
//color newFlow = color(newFlowVec.x * flowProduct, newFlowVec.y * flowProduct, flowMapCol_B);
|
|
color newFlow = color(diffR, diffG, flowMapCol_B);
|
|
color result = newFlow;
|
|
|
|
|
|
flowMap.pixels[y*width+x] = result;
|
|
}
|
|
}
|
|
}
|
|
|
|
//update flowmap
|
|
flowMap.updatePixels();
|
|
|
|
//show it
|
|
present = flowMap.get(0, 0, flowMap.width, flowMap.height);
|
|
}
|
|
|
|
//Load a flowmap to work on
|
|
public void Load()
|
|
{
|
|
String flowMapPath = selectInput("Select FlowMap");
|
|
if( flowMapPath != null )
|
|
{
|
|
println(flowMapPath);
|
|
flowMap = loadImage(flowMapPath);
|
|
drawBuff.set(0, 0, flowMap);
|
|
//image(flowMap, 0, 0);
|
|
}
|
|
return;
|
|
}
|
|
|
|
//Save a modified flowmap
|
|
public void Save()
|
|
{
|
|
String outputPath = selectOutput("Select Save Path");
|
|
if( outputPath != null )
|
|
{
|
|
println(outputPath);
|
|
flowMap.save(outputPath);
|
|
}
|
|
|
|
//bngDetail.setValue(false);
|
|
|
|
}
|
|
|
|
//Undo Event
|
|
public void Undo()
|
|
{
|
|
present = undoBuff.get(0, 0, bmpX, bmpY);
|
|
drawBuff.set(0, 0, undoBuff);
|
|
image(undoBuff, 0, 0);
|
|
}
|
|
|
|
//Quit Event
|
|
public void Quit()
|
|
{
|
|
//Check for save changes
|
|
|
|
//Exit
|
|
exit();
|
|
} |