aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xjs/helper-classes/RDGE/GLBrushStroke.js74
-rw-r--r--js/tools/BrushTool.js12
2 files changed, 65 insertions, 21 deletions
diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js
index 8fb6ab25..52ac79f5 100755
--- a/js/helper-classes/RDGE/GLBrushStroke.js
+++ b/js/helper-classes/RDGE/GLBrushStroke.js
@@ -34,6 +34,9 @@ function GLBrushStroke() {
34 this._strokeMaterial; 34 this._strokeMaterial;
35 this._strokeStyle = "Solid"; 35 this._strokeStyle = "Solid";
36 36
37 //the wetness of the brush (currently this is multiplied to the square of the stroke width, but todo should be changed
38 this._WETNESS_FACTOR = 0.010625;//0.0625;
39
37 //drawing context 40 //drawing context
38 this._world = null; 41 this._world = null;
39 42
@@ -69,21 +72,23 @@ function GLBrushStroke() {
69 this.getPoint = function (index) { return this._Points[index]; } 72 this.getPoint = function (index) { return this._Points[index]; }
70 this.addPoint = function (pt) 73 this.addPoint = function (pt)
71 { 74 {
72 //add the point if it is some epsilon away from the previous point 75 //add the point only if it is some epsilon away from the previous point
73 var doAddPoint=true;
74 var numPoints = this._Points.length; 76 var numPoints = this._Points.length;
75 if (numPoints>0) { 77 if (numPoints>0) {
78 var threshold = this._WETNESS_FACTOR*this._strokeWidth*this._strokeWidth;
76 var prevPt = this._Points[numPoints-1]; 79 var prevPt = this._Points[numPoints-1];
77 var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; 80 var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]];
78 var diffPtMag = diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]; 81 var diffPtMag = diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1];
79 if (diffPtMag<16)//TODO hook this up to the variable that measures flow/wetness of the paint brush...a smaller number-> more samples 82 if (diffPtMag>threshold){
80 doAddPoint=false; 83 this._Points.push(pt);
81 } 84 this._dirty=true;
82 if (doAddPoint) { 85 }
86 }else{
83 this._Points.push(pt); 87 this._Points.push(pt);
84 this._dirty=true; 88 this._dirty=true;
85 } 89 }
86 } 90 }
91
87 this.insertPoint = function(pt, index){ this._Points.splice(index, 0, pt); this._dirty=true;} 92 this.insertPoint = function(pt, index){ this._Points.splice(index, 0, pt); this._dirty=true;}
88 this.isDirty = function(){return this._dirty;} 93 this.isDirty = function(){return this._dirty;}
89 this.makeDirty = function(){this._dirty=true;} 94 this.makeDirty = function(){this._dirty=true;}
@@ -127,10 +132,39 @@ function GLBrushStroke() {
127 132
128 this.computeMetaGeometry = function(){ 133 this.computeMetaGeometry = function(){
129 if (this._dirty){ 134 if (this._dirty){
135 var numPoints = this._Points.length;
136
137 //**** add samples to the path if needed...linear interpolation for now
138 if (numPoints>1) {
139 var threshold = this._WETNESS_FACTOR*this._strokeWidth*this._strokeWidth;
140 var prevPt = this._Points[0];
141 var prevIndex = 0;
142 for (var i=1;i<numPoints;i++){
143 var pt = this._Points[i];
144 var diff = [pt[0]-prevPt[0], pt[1]-prevPt[1]];
145 var distance = Math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]);
146 if (distance>threshold){
147 //insert points along the prev. to current point
148 var numNewPoints = Math.floor(distance/threshold);
149 for (var j=0;j<numNewPoints;j++){
150 var param = (j+1)/(numNewPoints+1);
151 var newpt = [prevPt[0]+ diff[0]*param, prevPt[1]+ diff[1]*param];
152 //insert new point before point i
153 this._Points.splice(i, 0, [newpt[0], newpt[1], 0]);
154 i++;
155 }
156 this._dirty=true;
157 }
158 prevPt=pt;
159 //update numPoints to match the new length
160 numPoints = this._Points.length;
161 }
162 }
163
130 // *** compute the bounding box ********* 164 // *** compute the bounding box *********
131 this._BBoxMin = [Infinity, Infinity, Infinity]; 165 this._BBoxMin = [Infinity, Infinity, Infinity];
132 this._BBoxMax = [-Infinity, -Infinity, -Infinity]; 166 this._BBoxMax = [-Infinity, -Infinity, -Infinity];
133 var numPoints = this._Points.length; 167 numPoints = this._Points.length;
134 if (numPoints === 0) { 168 if (numPoints === 0) {
135 this._BBoxMin = [0, 0, 0]; 169 this._BBoxMin = [0, 0, 0];
136 this._BBoxMax = [0, 0, 0]; 170 this._BBoxMax = [0, 0, 0];
@@ -204,6 +238,7 @@ function GLBrushStroke() {
204 ctx.stroke(); 238 ctx.stroke();
205 */ 239 */
206 240
241 /*
207 var isDebug = false; 242 var isDebug = false;
208 var prevPt = this._Points[0]; 243 var prevPt = this._Points[0];
209 var prevX = prevPt[0]-bboxMin[0]; 244 var prevX = prevPt[0]-bboxMin[0];
@@ -284,9 +319,9 @@ function GLBrushStroke() {
284 } 319 }
285 ctx.stroke(); 320 ctx.stroke();
286 } 321 }
322 */
287 323
288 324
289 /*
290 var R2 = this._strokeWidth; 325 var R2 = this._strokeWidth;
291 var R = R2*0.5; 326 var R = R2*0.5;
292 var hardness = 0.25; //for a pencil, this is always 1 //TODO get hardness parameter from user interface 327 var hardness = 0.25; //for a pencil, this is always 1 //TODO get hardness parameter from user interface
@@ -294,23 +329,30 @@ function GLBrushStroke() {
294 if (innerRadius<1) 329 if (innerRadius<1)
295 innerRadius=1; 330 innerRadius=1;
296 331
332 var r = ctx.createRadialGradient(0,0,innerRadius, 0,0,R);
333 //r.addColorStop(0, 'rgba(255,0,0,0.5)');
334 var midColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",0.5)";
335 r.addColorStop(0, midColor);
336 //r.addColorStop(0.5, 'rgba(255,0,0,0.5)'); // prevent aggregation of semi-opaque pixels
337 //r.addColorStop(1, 'rgba(255,0,0,0.0)');
338 var endColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",0.0)";
339 r.addColorStop(1, endColor);
340 ctx.fillStyle = r;
341
297 for (var i = 0; i < numPoints; i++) { 342 for (var i = 0; i < numPoints; i++) {
298 var pt = this._Points[i]; 343 var pt = this._Points[i];
299 ctx.globalCompositeOperation = 'source-over'; 344 ctx.globalCompositeOperation = 'source-over';
300 var x = pt[0]-bboxMin[0]; 345 var x = pt[0]-bboxMin[0];
301 var y = pt[1]-bboxMin[1]; 346 var y = pt[1]-bboxMin[1];
302 var r = ctx.createRadialGradient(x, y, innerRadius, x, y, R); 347 ctx.save();
303 r.addColorStop(0, 'rgba(255,0,0,0.5)'); 348 ctx.translate(x,y);
304 //r.addColorStop(0.5, 'rgba(255,0,0,0.5)'); // prevent aggregation of semi-opaque pixels 349 ctx.arc(0, 0, R, 0, 2 * Math.PI, false);
305 r.addColorStop(1, 'rgba(255,0,0,0.0)');
306 ctx.fillStyle = r;
307 //ctx.fillRect(x-R, y-R, R2, R2);
308 ctx.arc(x, y, R, 0, 2 * Math.PI, false);
309 ctx.fill(); 350 ctx.fill();
351 ctx.restore();
310 //ctx.globalCompositeOperation = 'source-in'; 352 //ctx.globalCompositeOperation = 'source-in';
311 //ctx.rect(x-R, y-R, R2, R2); 353 //ctx.rect(x-R, y-R, R2, R2);
312 } 354 }
313 */ 355
314 ctx.restore(); 356 ctx.restore();
315 } //render() 357 } //render()
316 358
diff --git a/js/tools/BrushTool.js b/js/tools/BrushTool.js
index 9a0ad583..776d914c 100644
--- a/js/tools/BrushTool.js
+++ b/js/tools/BrushTool.js
@@ -64,6 +64,11 @@ exports.BrushTool = Montage.create(ShapeTool, {
64 //start a new brush stroke 64 //start a new brush stroke
65 if (this._selectedBrushStroke === null){ 65 if (this._selectedBrushStroke === null){
66 this._selectedBrushStroke = new GLBrushStroke(); 66 this._selectedBrushStroke = new GLBrushStroke();
67 if (this.application.ninja.colorController.colorToolbar.stroke.webGlColor){
68 this._selectedBrushStroke.setStrokeColor(this.application.ninja.colorController.colorToolbar.stroke.webGlColor);
69 }
70 //TODO get these values from the options
71 this._selectedBrushStroke.setStrokeWidth(20);
67 } 72 }
68 NJevent("enableStageMove");//stageManagerModule.stageManager.enableMouseMove(); 73 NJevent("enableStageMove");//stageManagerModule.stageManager.enableMouseMove();
69 } //value: function (event) { 74 } //value: function (event) {
@@ -132,10 +137,7 @@ exports.BrushTool = Montage.create(ShapeTool, {
132 this._isDrawing = false; 137 this._isDrawing = false;
133 this._hasDraw = false; 138 this._hasDraw = false;
134 139
135 //TODO get these values from the options 140
136 if (this._selectedBrushStroke){
137 this._selectedBrushStroke.setStrokeWidth(20);
138 }
139 //display the previously drawn stroke in a separate canvas 141 //display the previously drawn stroke in a separate canvas
140 this.RenderCurrentBrushStroke(); 142 this.RenderCurrentBrushStroke();
141 143
@@ -150,7 +152,7 @@ exports.BrushTool = Montage.create(ShapeTool, {
150 //clear the canvas before we draw anything else 152 //clear the canvas before we draw anything else
151 this.application.ninja.stage.clearDrawingCanvas(); 153 this.application.ninja.stage.clearDrawingCanvas();
152 if (this._selectedBrushStroke && this._selectedBrushStroke.getNumPoints()>0){ 154 if (this._selectedBrushStroke && this._selectedBrushStroke.getNumPoints()>0){
153 this._selectedBrushStroke.computeMetaGeometry(); 155 //this._selectedBrushStroke.computeMetaGeometry();
154 var ctx = this.application.ninja.stage.drawingContext;//stageManagerModule.stageManager.drawingContext; 156 var ctx = this.application.ninja.stage.drawingContext;//stageManagerModule.stageManager.drawingContext;
155 if (ctx === null) 157 if (ctx === null)
156 throw ("null drawing context in Brushtool::ShowCurrentBrushStrokeOnStage"); 158 throw ("null drawing context in Brushtool::ShowCurrentBrushStrokeOnStage");