From 353bfa04a6153b0146a0c73b6e6bb0e5f4b23194 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Tue, 6 Mar 2012 17:40:22 -0800 Subject: merge Valerio's architecture changes --- js/lib/geom/brush-stroke.js | 177 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 172 insertions(+), 5 deletions(-) (limited to 'js/lib/geom/brush-stroke.js') diff --git a/js/lib/geom/brush-stroke.js b/js/lib/geom/brush-stroke.js index 9a934928..39af5c5c 100755 --- a/js/lib/geom/brush-stroke.js +++ b/js/lib/geom/brush-stroke.js @@ -32,6 +32,8 @@ var BrushStroke = function GLBrushStroke() { //stroke information this._strokeWidth = 0.0; this._strokeColor = [0.4, 0.4, 0.4, 1.0]; + this._secondStrokeColor = this._strokeColor; + this._strokeHardness = 100; this._strokeMaterial = null; this._strokeStyle = "Solid"; @@ -114,7 +116,7 @@ var BrushStroke = function GLBrushStroke() { //add the point only if it is some epsilon away from the previous point var numPoints = this._Points.length; if (numPoints>0) { - var threshold = this._WETNESS_FACTOR*this._strokeWidth; + var threshold = 1;//this._WETNESS_FACTOR*this._strokeWidth; var prevPt = this._Points[numPoints-1]; var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]); @@ -173,6 +175,14 @@ var BrushStroke = function GLBrushStroke() { this._strokeColor = c; }; + this.setSecondStrokeColor = function(c){ + this._secondStrokeColor=c; + } + + this.setStrokeHardness = function(h){ + this._strokeHardness=h; + } + this.getStrokeStyle = function () { return this._strokeStyle; }; @@ -219,7 +229,8 @@ var BrushStroke = function GLBrushStroke() { var numPoints = this._Points.length; //**** add samples to the path if needed...linear interpolation for now - if (numPoints>1) { + //if (numPoints>1) { + if (0){ var threshold = this._WETNESS_FACTOR*this._strokeWidth; var prevPt = this._Points[0]; var prevIndex = 0; @@ -250,6 +261,44 @@ var BrushStroke = function GLBrushStroke() { } } } + //**** add samples to the long sections of the path --- Catmull-Rom spline interpolation + if (numPoints>1) { + var numInsertedPoints = 0; + var threshold = 5;//0.25*this._strokeWidth; //this determines whether a segment between two sample is too long + var prevPt = this._Points[0]; + for (var i=1;ithreshold){ + //build the control polygon for the Catmull-Rom spline (prev. 2 points and next 2 points) + var prev = (i===1) ? i-1 : i-2; + var next = (i===numPoints-1) ? i : i+1; + var ctrlPts = [this._Points[prev], this._Points[i-1], this._Points[i], this._Points[next]]; + //insert points along the prev. to current point + var numNewPoints = Math.floor(distance/threshold); + for (var j=0;j this._MAX_ALLOWED_SAMPLES){ + console.log("leaving the resampling because numPoints is greater than limit:"+this._MAX_ALLOWED_SAMPLES); + break; + } + } + console.log("Inserted "+numInsertedPoints+" additional CatmullRom points"); + } // *** compute the bounding box ********* this._BBoxMin = [Infinity, Infinity, Infinity]; @@ -412,7 +461,7 @@ var BrushStroke = function GLBrushStroke() { } */ - + /* var R2 = this._strokeWidth; var R = R2*0.5; var hardness = 0; //for a pencil, this is always 1 //TODO get hardness parameter from user interface @@ -440,6 +489,109 @@ var BrushStroke = function GLBrushStroke() { //ctx.globalCompositeOperation = 'source-in'; //ctx.rect(x-R, y-R, R2, R2); } + */ + + /* + //build the stamp for the brush stroke + //todo get this directly from the UI + var t=0; + var numTraces = this._strokeWidth; + var halfNumTraces = numTraces/2; + var startPos = [-this._strokeWidth/2,0]; + var brushStamp = []; + + //build an angled (calligraphic) brush stamp + var deltaDisplacement = [1,1];//[this._strokeWidth/numTraces, 0]; //a horizontal line brush + for (t=0;t1) { + if (this._strokeDoSmoothing && numPoints>1) { var numInsertedPoints = 0; var threshold = 5;//0.25*this._strokeWidth; //this determines whether a segment between two sample is too long var prevPt = this._Points[0]; @@ -507,35 +512,6 @@ var BrushStroke = function GLBrushStroke() { brushStamp.push(brushPt); } - - //make a circular brush stamp - brushStamp=[]; - numTraces = this._strokeWidth*Math.PI; //figure out how to - var radius = this._strokeWidth/2; - for (t=0;t0) { - var threshold = 1;//this._WETNESS_FACTOR*this._strokeWidth; + var threshold = 2;//this._WETNESS_FACTOR*this._strokeWidth; var prevPt = this._Points[numPoints-1]; var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]); @@ -188,6 +190,14 @@ var BrushStroke = function GLBrushStroke() { this._strokeDoSmoothing = s; } + this.setStrokeUseCalligraphic = function(c){ + this._strokeUseCalligraphic = c; + } + + this.setStrokeAngle = function(a){ + this._strokeAngle = a; + } + this.getStrokeStyle = function () { return this._strokeStyle; }; @@ -266,6 +276,8 @@ var BrushStroke = function GLBrushStroke() { } } } + //todo 4-point subdivision iterations over continuous regions of 'long' segments + // look at http://www.gvu.gatech.edu/~jarek/Split&Tweak/ for formula //**** add samples to the long sections of the path --- Catmull-Rom spline interpolation if (this._strokeDoSmoothing && numPoints>1) { var numInsertedPoints = 0; @@ -496,75 +508,84 @@ var BrushStroke = function GLBrushStroke() { } */ - /* - //build the stamp for the brush stroke - //todo get this directly from the UI - var t=0; - var numTraces = this._strokeWidth; - var halfNumTraces = numTraces/2; - var startPos = [-this._strokeWidth/2,0]; - var brushStamp = []; - - //build an angled (calligraphic) brush stamp - var deltaDisplacement = [1,1];//[this._strokeWidth/numTraces, 0]; //a horizontal line brush - for (t=0;t0) { + alphaVal = 1.0 - distFromOpaqueRegion/maxTransparentRegionHalfWidth; + } + + ctx.save(); + ctx.lineWidth=this._strokeWidth/10;//todo figure out the correct formula for the line width + if (ctx.lineWidth<2) + ctx.lineWidth=2; + if (t===numTraces-1){ + ctx.lineWidth = 1; + } + ctx.lineJoin="bevel"; + ctx.lineCap="butt"; + ctx.globalAlpha = this._strokeColor[3]; + + //if (t0) { - var threshold = 2;//this._WETNESS_FACTOR*this._strokeWidth; + var threshold = this._MIN_SAMPLE_DISTANCE_THRESHOLD;//this._WETNESS_FACTOR*this._strokeWidth; var prevPt = this._Points[numPoints-1]; var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]); @@ -276,13 +282,16 @@ var BrushStroke = function GLBrushStroke() { } } } + //todo 4-point subdivision iterations over continuous regions of 'long' segments // look at http://www.gvu.gatech.edu/~jarek/Split&Tweak/ for formula //**** add samples to the long sections of the path --- Catmull-Rom spline interpolation if (this._strokeDoSmoothing && numPoints>1) { var numInsertedPoints = 0; - var threshold = 5;//0.25*this._strokeWidth; //this determines whether a segment between two sample is too long + var newPoints = []; + var threshold = this._MAX_SAMPLE_DISTANCE_THRESHOLD;//this determines whether a segment between two sample is long enough to warrant checking for angle var prevPt = this._Points[0]; + newPoints.push(this._Points[0]); for (var i=1;i0) { alphaVal = 1.0 - distFromOpaqueRegion/maxTransparentRegionHalfWidth; + alphaVal *= 1.0/ctx.lineWidth; //factor that accounts for lineWidth !== 1 } ctx.save(); - ctx.lineWidth=this._strokeWidth/10;//todo figure out the correct formula for the line width - if (ctx.lineWidth<2) - ctx.lineWidth=2; - if (t===numTraces-1){ - ctx.lineWidth = 1; - } - ctx.lineJoin="bevel"; - ctx.lineCap="butt"; - ctx.globalAlpha = this._strokeColor[3]; - - //if (t0) { - var threshold = this._MIN_SAMPLE_DISTANCE_THRESHOLD;//this._WETNESS_FACTOR*this._strokeWidth; + var threshold = this._MIN_SAMPLE_DISTANCE_THRESHOLD; var prevPt = this._Points[numPoints-1]; var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]); @@ -196,6 +193,10 @@ var BrushStroke = function GLBrushStroke() { this._strokeDoSmoothing = s; } + this.setSmoothingAmount = function(a){ + this._strokeAmountSmoothing = a; + } + this.setStrokeUseCalligraphic = function(c){ this._strokeUseCalligraphic = c; } @@ -252,7 +253,7 @@ var BrushStroke = function GLBrushStroke() { //**** add samples to the path if needed...linear interpolation for now //if (numPoints>1) { if (0){ - var threshold = this._WETNESS_FACTOR*this._strokeWidth; + var threshold = this._MAX_SAMPLE_DISTANCE_THRESHOLD; var prevPt = this._Points[0]; var prevIndex = 0; for (var i=1;i1) { @@ -330,7 +331,7 @@ var BrushStroke = function GLBrushStroke() { console.log("Inserted "+numInsertedPoints+" additional CatmullRom points"); //now do 3-4 iterations of Laplacian smoothing (setting the points to the average of their neighbors) - var numLaplacianIterations = 3; //todo figure out the proper number of Laplacian iterations (perhaps as a function of stroke width) + var numLaplacianIterations = this._strokeAmountSmoothing; for (var n=0;n1) { - if (0){ - var threshold = this._MAX_SAMPLE_DISTANCE_THRESHOLD; - var prevPt = this._Points[0]; - var prevIndex = 0; - for (var i=1;ithreshold){ - //insert points along the prev. to current point - var numNewPoints = Math.floor(distance/threshold); - for (var j=0;j this._MAX_ALLOWED_SAMPLES){ - console.log("leaving the resampling because numPoints is greater than limit:"+this._MAX_ALLOWED_SAMPLES); - break; + var numPoints = this._Points.length; + if (this._addedSamples === false){ + //**** add samples to the long sections of the path --- Catmull-Rom spline interpolation ***** + // instead of the following, may use 4-point subdivision iterations over continuous regions of 'long' segments + // look at http://www.gvu.gatech.edu/~jarek/Split&Tweak/ for formula + + var numInsertedPoints = 0; + var newSampledPoints = []; + var threshold = this._MAX_SAMPLE_DISTANCE_THRESHOLD;//this determines whether a segment between two sample is long enough to warrant checking for angle + var prevPt = this._Points[0]; + newSampledPoints.push(this._Points[0]); + for (var i=1;ithreshold){ + //build the control polygon for the Catmull-Rom spline (prev. 2 points and next 2 points) + var prev = (i===1) ? i-1 : i-2; + var next = (i===numPoints-1) ? i : i+1; + var ctrlPts = [this._Points[prev], this._Points[i-1], this._Points[i], this._Points[next]]; + //insert points along the prev. to current point + var numNewPoints = Math.floor(distance/threshold); + for (var j=0;j this._MAX_ALLOWED_SAMPLES){ + // console.log("leaving the resampling because numPoints is greater than limit:"+this._MAX_ALLOWED_SAMPLES); + // break; + //} } + this._Points = newSampledPoints.slice(0); + newSampledPoints = []; + console.log("Inserted "+numInsertedPoints+" additional CatmullRom points"); + this._addedSamples = true; + this._dirty=true; + } + //build a copy of the original points...this should be done only once + if (this._storedOrigPoints === false) { + this._OrigPoints = this._Points.slice(0); + this._storedOrigPoints = true; + } - //instead of the following, may use 4-point subdivision iterations over continuous regions of 'long' segments - // look at http://www.gvu.gatech.edu/~jarek/Split&Tweak/ for formula - //**** add samples to the long sections of the path --- Catmull-Rom spline interpolation + if (this._dirty) { + this._Points = this._OrigPoints.slice(0); + numPoints = this._Points.length; if (this._strokeDoSmoothing && numPoints>1) { - var numInsertedPoints = 0; - var newPoints = []; - var threshold = this._MAX_SAMPLE_DISTANCE_THRESHOLD;//this determines whether a segment between two sample is long enough to warrant checking for angle - var prevPt = this._Points[0]; - newPoints.push(this._Points[0]); - for (var i=1;ithreshold){ - //build the control polygon for the Catmull-Rom spline (prev. 2 points and next 2 points) - var prev = (i===1) ? i-1 : i-2; - var next = (i===numPoints-1) ? i : i+1; - var ctrlPts = [this._Points[prev], this._Points[i-1], this._Points[i], this._Points[next]]; - //insert points along the prev. to current point - var numNewPoints = Math.floor(distance/threshold); - for (var j=0;j this._MAX_ALLOWED_SAMPLES){ - console.log("leaving the resampling because numPoints is greater than limit:"+this._MAX_ALLOWED_SAMPLES); - break; - } - } - this._Points = newPoints; - numPoints = this._Points.length; - console.log("Inserted "+numInsertedPoints+" additional CatmullRom points"); - - //now do 3-4 iterations of Laplacian smoothing (setting the points to the average of their neighbors) - var numLaplacianIterations = this._strokeAmountSmoothing; + //iterations of Laplacian smoothing (setting the points to the average of their neighbors) + var numLaplacianIterations = this._strokeAmountSmoothing; for (var n=0;n */ -// Todo: This entire class should be converted to a module var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; var GeomObj = require("js/lib/geom/geom-obj").GeomObj; +var CanvasController = require("js/controllers/elements/canvas-controller").CanvasController; + +// Todo: This entire class should be converted to a module /////////////////////////////////////////////////////////////////////// // Class GLBrushStroke @@ -28,7 +30,10 @@ var BrushStroke = function GLBrushStroke() { //whether or not to use the canvas drawing to stroke/fill this._useCanvasDrawing = true; - //the X and Y location of this subpath's canvas in stage world space of Ninja + //the HTML5 canvas that holds this brush stroke + this._canvas = null; + + //the X and Y location of this brush stroke canvas in stage world space of Ninja this._canvasX = 0; this._canvasY = 0; @@ -65,6 +70,10 @@ var BrushStroke = function GLBrushStroke() { ///////////////////////////////////////////////////////// // Property Accessors/Setters ///////////////////////////////////////////////////////// + this.setCanvas = function(c) { + this._canvas = c; + } + this.setWorld = function (world) { this._world = world; }; @@ -195,6 +204,9 @@ var BrushStroke = function GLBrushStroke() { this._dirty = true; } } + this.getStrokeHardness = function(){ + return this._strokeHardness; + } this.setDoSmoothing = function(s){ if (this._strokeDoSmoothing!==s) { @@ -203,12 +215,19 @@ var BrushStroke = function GLBrushStroke() { } } + this.getDoSmoothing = function(){ + return this._strokeDoSmoothing; + } + this.setSmoothingAmount = function(a){ if (this._strokeAmountSmoothing!==a) { this._strokeAmountSmoothing = a; this._dirty = true; } + } + this.getSmoothingAmount = function(){ + return this._strokeAmountSmoothing; } this.setStrokeUseCalligraphic = function(c){ @@ -225,6 +244,14 @@ var BrushStroke = function GLBrushStroke() { }; } + this.getStrokeUseCalligraphic = function(){ + return this._strokeUseCalligraphic; + } + + this.getStrokeAngle = function(){ + this._strokeAngle = a; + } + this.getStrokeStyle = function () { return this._strokeStyle; }; @@ -301,12 +328,13 @@ var BrushStroke = function GLBrushStroke() { console.log("Inserted "+numInsertedPoints+" additional CatmullRom points"); this._addedSamples = true; this._dirty=true; - } + } //if we need to add samples to this curve (done only once) + //build a copy o