diff options
Diffstat (limited to 'js/helper-classes/RDGE/GLBrushStroke.js')
-rwxr-xr-x | js/helper-classes/RDGE/GLBrushStroke.js | 74 |
1 files changed, 58 insertions, 16 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 | ||