aboutsummaryrefslogtreecommitdiff
path: root/js/helper-classes
diff options
context:
space:
mode:
Diffstat (limited to 'js/helper-classes')
-rwxr-xr-xjs/helper-classes/RDGE/GLBrushStroke.js175
1 files changed, 163 insertions, 12 deletions
diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js
index fdf1595c..5d773c2d 100755
--- a/js/helper-classes/RDGE/GLBrushStroke.js
+++ b/js/helper-classes/RDGE/GLBrushStroke.js
@@ -34,6 +34,13 @@ 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 to not depend on stroke width entirely
38 //smaller value means more samples for the path
39 this._WETNESS_FACTOR = 0.25;
40
41 //prevent extremely long paths that can take a long time to render
42 this._MAX_ALLOWED_SAMPLES = 500;
43
37 //drawing context 44 //drawing context
38 this._world = null; 45 this._world = null;
39 46
@@ -67,7 +74,25 @@ function GLBrushStroke() {
67 74
68 this.getNumPoints = function () { return this._Points.length; } 75 this.getNumPoints = function () { return this._Points.length; }
69 this.getPoint = function (index) { return this._Points[index]; } 76 this.getPoint = function (index) { return this._Points[index]; }
70 this.addPoint = function (anchorPt) { this._Points.push(anchorPt); this._dirty=true; } 77 this.addPoint = function (pt)
78 {
79 //add the point only if it is some epsilon away from the previous point
80 var numPoints = this._Points.length;
81 if (numPoints>0) {
82 var threshold = this._WETNESS_FACTOR*this._strokeWidth;
83 var prevPt = this._Points[numPoints-1];
84 var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]];
85 var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]);
86 if (diffPtMag>threshold){
87 this._Points.push(pt);
88 this._dirty=true;
89 }
90 }else{
91 this._Points.push(pt);
92 this._dirty=true;
93 }
94 }
95
71 this.insertPoint = function(pt, index){ this._Points.splice(index, 0, pt); this._dirty=true;} 96 this.insertPoint = function(pt, index){ this._Points.splice(index, 0, pt); this._dirty=true;}
72 this.isDirty = function(){return this._dirty;} 97 this.isDirty = function(){return this._dirty;}
73 this.makeDirty = function(){this._dirty=true;} 98 this.makeDirty = function(){this._dirty=true;}
@@ -111,10 +136,45 @@ function GLBrushStroke() {
111 136
112 this.computeMetaGeometry = function(){ 137 this.computeMetaGeometry = function(){
113 if (this._dirty){ 138 if (this._dirty){
139 var numPoints = this._Points.length;
140
141 //**** add samples to the path if needed...linear interpolation for now
142 if (numPoints>1) {
143 var threshold = this._WETNESS_FACTOR*this._strokeWidth;
144 var prevPt = this._Points[0];
145 var prevIndex = 0;
146 for (var i=1;i<numPoints;i++){
147 var pt = this._Points[i];
148 var diff = [pt[0]-prevPt[0], pt[1]-prevPt[1]];
149 var distance = Math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]);
150 if (distance>threshold){
151 //insert points along the prev. to current point
152 var numNewPoints = Math.floor(distance/threshold);
153 for (var j=0;j<numNewPoints;j++){
154 var param = (j+1)/(numNewPoints+1);
155 var newpt = [prevPt[0]+ diff[0]*param, prevPt[1]+ diff[1]*param];
156 //insert new point before point i
157 this._Points.splice(i, 0, [newpt[0], newpt[1], 0]);
158 i++;
159 }
160 this._dirty=true;
161 }
162 prevPt=pt;
163 //update numPoints to match the new length
164 numPoints = this._Points.length;
165
166 //end this function if the numPoints has gone above the max. size specified
167 if (numPoints> this._MAX_ALLOWED_SAMPLES){
168 console.log("leaving the resampling because numPoints is greater than limit:"+this._MAX_ALLOWED_SAMPLES);
169 break;
170 }
171 }
172 }
173
114 // *** compute the bounding box ********* 174 // *** compute the bounding box *********
115 this._BBoxMin = [Infinity, Infinity, Infinity]; 175 this._BBoxMin = [Infinity, Infinity, Infinity];
116 this._BBoxMax = [-Infinity, -Infinity, -Infinity]; 176 this._BBoxMax = [-Infinity, -Infinity, -Infinity];
117 var numPoints = this._Points.length; 177 numPoints = this._Points.length;
118 if (numPoints === 0) { 178 if (numPoints === 0) {
119 this._BBoxMin = [0, 0, 0]; 179 this._BBoxMin = [0, 0, 0];
120 this._BBoxMax = [0, 0, 0]; 180 this._BBoxMax = [0, 0, 0];
@@ -167,7 +227,8 @@ function GLBrushStroke() {
167 var bboxWidth = bboxMax[0] - bboxMin[0]; 227 var bboxWidth = bboxMax[0] - bboxMin[0];
168 var bboxHeight = bboxMax[1] - bboxMin[1]; 228 var bboxHeight = bboxMax[1] - bboxMin[1];
169 ctx.clearRect(0, 0, bboxWidth, bboxHeight); 229 ctx.clearRect(0, 0, bboxWidth, bboxHeight);
170/* 230
231 /*
171 ctx.lineWidth = this._strokeWidth; 232 ctx.lineWidth = this._strokeWidth;
172 ctx.strokeStyle = "black"; 233 ctx.strokeStyle = "black";
173 if (this._strokeColor) 234 if (this._strokeColor)
@@ -185,30 +246,120 @@ function GLBrushStroke() {
185 ctx.lineTo(pt[0]-bboxMin[0], pt[1]-bboxMin[1]); 246 ctx.lineTo(pt[0]-bboxMin[0], pt[1]-bboxMin[1]);
186 } 247 }
187 ctx.stroke(); 248 ctx.stroke();
188 */ 249 */
250
251 /*
252 var isDebug = false;
253 var prevPt = this._Points[0];
254 var prevX = prevPt[0]-bboxMin[0];
255 var prevY = prevPt[1]-bboxMin[1];
256 prevPt = [prevX,prevY];
257 for (var i = 1; i < numPoints; i++) {
258 var pt = this._Points[i];
259 ctx.globalCompositeOperation = 'source-over';
260 var x = pt[0]-bboxMin[0];
261 var y = pt[1]-bboxMin[1];
262 pt = [x,y];
263
264 //vector from prev to current pt
265 var seg = VecUtils.vecSubtract(2, pt, prevPt);
266 var segDir = VecUtils.vecNormalize(2, seg, 1.0);
267
268 var segMidPt = VecUtils.vecInterpolate(2, pt, prevPt, 0.5);
269 var w2 = this._strokeWidth*0.5;
270 var segDirOrtho = [w2*segDir[1], -w2*segDir[0]];
271
272 //add half the strokewidth to the segMidPt
273 var lgStart = VecUtils.vecAdd(2, segMidPt, segDirOrtho);
274 var lgEnd = VecUtils.vecSubtract(2, segMidPt, segDirOrtho);
275
276 ctx.save();
277 ctx.beginPath();
278
279 if (isDebug) {
280 ctx.strokeStyle="black";
281 ctx.lineWidth = 1;
282
283 ctx.moveTo(lgStart[0], lgStart[1]);
284 ctx.lineTo(lgEnd[0], lgEnd[1]);
285 ctx.stroke();
286 }
287
288 var lg = ctx.createLinearGradient(lgStart[0], lgStart[1], lgEnd[0], lgEnd[1]);
289 lg.addColorStop(1, 'rgba(0,0,0,0.0)');
290 lg.addColorStop(0.5,'rgba(255,0,0,1.0)');
291 lg.addColorStop(0, 'rgba(0,0,0,0.0)');
292 ctx.fillStyle = lg;
293
294 if (isDebug){
295 ctx.strokeStyle="blue";
296 ctx.lineWidth=0.5;
297 }
298 ctx.moveTo(prevX-w2, prevY);
299 ctx.lineTo(prevX+w2, prevY);
300 ctx.lineTo(x+w2, y);
301 ctx.lineTo(x-w2, y);
302 ctx.lineTo(prevX-w2, prevY);
303 ctx.fill();
304 ctx.closePath();
305
306 ctx.restore();
307
308 prevPt = pt;
309 prevX = x;
310 prevY = y;
311 }
312
313
314 if (isDebug)
315 ctx.stroke();
316
317 if (isDebug){
318 //draw the skeleton of this stroke
319 ctx.lineWidth = 1;
320 ctx.strokeStyle = "black";
321 var pt = this._Points[0];
322 ctx.beginPath();
323 ctx.moveTo(pt[0]-bboxMin[0],pt[1]-bboxMin[1]);
324 for (var i = 1; i < numPoints; i++) {
325 pt = this._Points[i];
326 var x = pt[0]-bboxMin[0];
327 var y = pt[1]-bboxMin[1];
328 ctx.lineTo(x,y);
329 }
330 ctx.stroke();
331 }
332 */
333
334
189 var R2 = this._strokeWidth; 335 var R2 = this._strokeWidth;
190 var R = R2*0.5; 336 var R = R2*0.5;
191 var hardness = 0.25; //for a pencil, this is always 1 //TODO get hardness parameter from user interface 337 var hardness = 0; //for a pencil, this is always 1 //TODO get hardness parameter from user interface
192 var innerRadius = (hardness*R)-1; 338 var innerRadius = (hardness*R)-1;
193 if (innerRadius<1) 339 if (innerRadius<1)
194 innerRadius=1; 340 innerRadius=1;
195 341
342 var r = ctx.createRadialGradient(0,0,innerRadius, 0,0,R);
343 var midColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",1)";
344 r.addColorStop(0, midColor);
345 var endColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",0.0)";
346 r.addColorStop(1, endColor);
347 ctx.fillStyle = r;
348
196 for (var i = 0; i < numPoints; i++) { 349 for (var i = 0; i < numPoints; i++) {
197 var pt = this._Points[i]; 350 var pt = this._Points[i];
198 ctx.globalCompositeOperation = 'source-over'; 351 ctx.globalCompositeOperation = 'source-over';
199 var x = pt[0]-bboxMin[0]; 352 var x = pt[0]-bboxMin[0];