From 878743cbbb75f2fc84855ca27779597b67ab1a95 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Mon, 2 Apr 2012 15:25:00 -0700 Subject: render the pen path with local coordinates, but use stage world coordinates to position the canvas on which the path is rendered AND add data-montage- to the ids in the pen and brush reels AND fix a bug with pen stroke transparency not working --- .../brush-properties.reel/brush-properties.html | 2 +- .../pen-properties.reel/pen-properties.html | 2 +- js/helper-classes/3D/view-utils.js | 1 - js/lib/geom/brush-stroke.js | 2 +- js/lib/geom/sub-path.js | 264 +++++++++++++++++++-- js/tools/PenTool.js | 44 ++-- 6 files changed, 269 insertions(+), 46 deletions(-) diff --git a/js/components/tools-properties/brush-properties.reel/brush-properties.html b/js/components/tools-properties/brush-properties.reel/brush-properties.html index 98442164..d9c35dc2 100755 --- a/js/components/tools-properties/brush-properties.reel/brush-properties.html +++ b/js/components/tools-properties/brush-properties.reel/brush-properties.html @@ -84,7 +84,7 @@ -
+
diff --git a/js/components/tools-properties/pen-properties.reel/pen-properties.html b/js/components/tools-properties/pen-properties.reel/pen-properties.html index 74a3a747..acbedcac 100755 --- a/js/components/tools-properties/pen-properties.reel/pen-properties.html +++ b/js/components/tools-properties/pen-properties.reel/pen-properties.html @@ -39,7 +39,7 @@ -
+
diff --git a/js/helper-classes/3D/view-utils.js b/js/helper-classes/3D/view-utils.js index a72b7906..f60b953a 100755 --- a/js/helper-classes/3D/view-utils.js +++ b/js/helper-classes/3D/view-utils.js @@ -242,7 +242,6 @@ exports.ViewUtils = Montage.create(Component, { var worldPt = MathUtils.transformPoint( viewPt, mat ); var stageWorldPt = this.postViewToStageWorld( worldPt, elt ); this.popViewportObj(); - return stageWorldPt; } }, diff --git a/js/lib/geom/brush-stroke.js b/js/lib/geom/brush-stroke.js index 22209815..e93c9382 100755 --- a/js/lib/geom/brush-stroke.js +++ b/js/lib/geom/brush-stroke.js @@ -413,7 +413,7 @@ var BrushStroke = function GLBrushStroke() { this._LocalPoints[i][1]+= halfheight; //store the original points - this._OrigLocalPoints .push([this._LocalPoints[i][0],this._LocalPoints[i][1],this._LocalPoints[i][2]]); + this._OrigLocalPoints.push([this._LocalPoints[i][0],this._LocalPoints[i][1],this._LocalPoints[i][2]]); } //update the bbox with the same adjustment as was made for the local points above this._BBoxMax[0]+= halfwidth;this._BBoxMin[0]+= halfwidth; diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js index 9bd9ad9a..19a1da3b 100755 --- a/js/lib/geom/sub-path.js +++ b/js/lib/geom/sub-path.js @@ -12,6 +12,7 @@ var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint; var MaterialsModel = require("js/models/materials-model").MaterialsModel; // TODO Those function do not seems to be used. We should remove them +/* function SubpathOffsetPoint(pos, mapPos) { this.Pos = [pos[0],pos[1],pos[2]]; this.CurveMapPos = [mapPos[0], mapPos[1], mapPos[2]]; @@ -33,7 +34,7 @@ function sortNumberDescending(a,b){ function SegmentIntersections(){ this.paramArray = []; } - +*/ /////////////////////////////////////////////////////////////////////// // Class GLSubpath // representation a sequence of cubic bezier curves. @@ -49,15 +50,22 @@ var GLSubpath = function GLSubpath() { this._BBoxMax = [0, 0, 0]; this._isClosed = false; - this._samples = []; //polyline representation of this curve - this._sampleParam = []; //parametric distance of samples, within [0, N], where N is # of Bezier curves (=# of anchor points if closed, =#anchor pts -1 if open) + this._samples = []; //polyline representation of this curve in stage world space + this._sampleParam = []; //parametric distance of samples, within [0, N], where N is # of Bezier curves (=# of anchor points if closed, =#anchor pts -1 if open) this._anchorSampleIndex = []; //index within _samples corresponding to anchor points - + + this._LocalPoints = []; //polyline representation of this curve in canvas space + this._LocalBBoxMin = [0,0,0]; //bbox min point of _LocalPoints + this._LocalBBoxMax = [0,0,0]; //bbox max point of _LocalPoints + this._UnprojectedAnchors = []; //initially set the _dirty bit so we will construct samples this._dirty = true; + //initially set the local dirty bit so we will construct local coordinates + this._isLocalDirty = true; + //whether or not to use the canvas drawing to stroke/fill this._useCanvasDrawing = true; @@ -69,7 +77,7 @@ var GLSubpath = function GLSubpath() { this._canvasY = 0; //stroke information - this._strokeWidth = 0.0; + this._strokeWidth = 1.0; this._strokeColor = [0.4, 0.4, 0.4, 1.0]; this._strokeMaterial = null this._strokeStyle = "Solid"; @@ -109,6 +117,13 @@ var GLSubpath = function GLSubpath() { // return; //no need to do anything for now }; + this._offsetLocalCoord = function(deltaW, deltaH){ + var numPoints = this._LocalPoints.length; + for (var i=0;i pt[d]) { + bboxMin[d] = pt[d]; + } + if (bboxMax[d] < pt[d]) { + bboxMax[d] = pt[d]; + } + } + } + //save the center of the bbox for later use (while constructing the canvas) + var stageWorldCenter = VecUtils.vecInterpolate(3, bboxMin, bboxMax, 0.5); + + // ***** center the input stageworld data about the center of the bbox ***** + this._LocalPoints = []; + for (i=0;i== 2) { + //compute the //re-compute the bounding box (this also accounts for stroke width, so assume the stroke width is set) this.computeBoundingBox(true); + //set the local dirty bit so we will re-create the local coords before rendering + this._isLocalDirty = true; } //if (this._dirty) this._dirty = false; }; +GLSubpath.prototype.getLocalBBoxMidInStageWorld = function() { + var ViewUtils = require("js/helper-classes/3D/view-utils").ViewUtils; + //compute the plane center as the midpoint of the local bbox converted to stage world space + var bboxWidth=0, bboxHeight=0; + var bboxMid=[0,0,0]; + bboxWidth = this._LocalBBoxMax[0] - this._LocalBBoxMin[0]; + bboxHeight = this._LocalBBoxMax[1] - this._LocalBBoxMin[1]; + bboxMid = [0.5 * (this._LocalBBoxMax[0] + this._LocalBBoxMin[0]), 0.5 * (this._LocalBBoxMax[1] + this._LocalBBoxMin[1]), 0.5 * (this._LocalBBoxMax[2] + this._LocalBBoxMin[2])]; + var planeCenter = ViewUtils.localToStageWorld(bboxMid, this._canvas); + planeCenter[0]+=400; planeCenter[1]+=300; //todo replace these lines with the correct call for the offset + console.log("PEN: local midPt: "+ bboxMid +", stageWorld midPt: "+planeCenter); + return planeCenter; +} + +GLSubpath.prototype._computeLocalBoundingBox = function() { + this._LocalBBoxMin = [Infinity, Infinity, Infinity]; + this._LocalBBoxMax = [-Infinity, -Infinity, -Infinity]; + var numPoints = this._LocalPoints.length; + if (numPoints === 0) { + this._LocalBBoxMin = [0, 0, 0]; + this._LocalBBoxMax = [0, 0, 0]; + } else { + for (var i=0;i pt[d]) { + this._LocalBBoxMin[d] = pt[d]; + } + if (this._LocalBBoxMax[d] < pt[d]) { + this._LocalBBoxMax[d] = pt[d]; + } + }//for every dimension d from 0 to 2 + } + } + + //increase the bbox given the stroke width + var halfSW = this._strokeWidth*0.5; + this._LocalBBoxMin[0]-= halfSW;this._LocalBBoxMin[1]-= halfSW; + this._LocalBBoxMax[0]+= halfSW;this._LocalBBoxMax[1]+= halfSW; +}; + GLSubpath.prototype.computeBoundingBox = function(useSamples){ this._BBoxMin = [Infinity, Infinity, Infinity]; this._BBoxMax = [-Infinity, -Infinity, -Infinity]; @@ -1102,7 +1314,7 @@ GLSubpath.prototype.computeBoundingBox = function(useSamples){ for (var d = 0; d < 3; d++) { this._BBoxMin[d]-= this._strokeWidth/2; this._BBoxMax[d]+= this._strokeWidth/2; - }//for every dimension d from 0 to 2 + }//for every dimension d from 0 to 3 }; //returns v such that it is in [min,max] diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index 31dadb80..98423113 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -416,18 +416,30 @@ exports.PenTool = Montage.create(ShapeTool, { ShowSelectedSubpath:{ value: function() { if (this._selectedSubpath){ + this._selectedSubpath.setPlaneMatrix(this._penPlaneMat); + var planeMatInv = glmat4.inverse( this._penPlaneMat, [] ); + this._selectedSubpath.setPlaneMatrixInverse(planeMatInv); + this._selectedSubpath.createSamples(); //dirty bit is checked here - var bboxMin = this._selectedSubpath.getBBoxMin(); - var bboxMax = this._selectedSubpath.getBBoxMax(); + this._selectedSubpath.buildLocalCoord(); //local dirty bit is checked here + + //build the width and height of this canvas by looking at local coordinates (X and Y needed only) + var bboxMin = this._selectedSubpath.getLocalBBoxMin(); + var bboxMax = this._selectedSubpath.getLocalBBoxMax(); var bboxWidth = bboxMax[0] - bboxMin[0]; var bboxHeight = bboxMax[1] - bboxMin[1]; + + //build the 3D position of the plane center of this canvas by looking at midpoint of the bounding box in stage world coords + bboxMin = this._selectedSubpath.getBBoxMin(); + bboxMax = this._selectedSubpath.getBBoxMax(); var bboxMid = [0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]; + this._selectedSubpath.setPlaneCenter(bboxMid); this._selectedSubpath.setCanvasX(bboxMid[0]); this._selectedSubpath.setCanvasY(bboxMid[1]); //call render shape with the bbox width and height - this.RenderShape(bboxWidth, bboxHeight, this._penPlaneMat, bboxMid, this._penCanvas); + this.RenderShape(bboxWidth, bboxHeight, bboxMid, this._penPlaneMat, this._penCanvas); } } }, @@ -592,7 +604,7 @@ exports.PenTool = Montage.create(ShapeTool, { }, RenderShape: { - value: function (w, h, planeMat, midPt, canvas) { + value: function (w, h, midPt, planeMat, canvas) { if ((Math.floor(w) === 0) || (Math.floor(h) === 0)) { return; } @@ -614,10 +626,6 @@ exports.PenTool = Montage.create(ShapeTool, { var subpath = this._selectedSubpath; //new GLSubpath(); subpath.setWorld(world); subpath.setCanvas(newCanvas); - subpath.setPlaneMatrix(planeMat); - var planeMatInv = glmat4.inverse( planeMat, [] ); - subpath.setPlaneMatrixInverse(planeMatInv); - subpath.setPlaneCenter(midPt); world.addObject(subpath); world.render(); @@ -662,11 +670,19 @@ exports.PenTool = Montage.create(ShapeTool, { if (this._entryEditMode !== this.ENTRY_SELECT_CANVAS){ //update the left and top of the canvas element var canvasArray=[canvas]; - ElementMediator.setProperty(canvasArray, "left", [parseInt(left)+"px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "left", parseInt(left) + "px"); - ElementMediator.setProperty(canvasArray, "top", [parseInt(top) + "px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "top", parseInt(top) + "px"); + w= Math.round(w); + h = Math.round(h); ElementMediator.setProperty(canvasArray, "width", [w+"px"], "Changing", "penTool");//canvas.width = w; ElementMediator.setProperty(canvasArray, "height", [h+"px"], "Changing", "penTool");//canvas.height = h; - //update the viewport and projection to reflect the new canvas width and height + + //var bboxMid = this._selectedSubpath.getLocalBBoxMidInStageWorld(); + //left = Math.round(bboxMid[0] - 0.5 * w); + //top = Math.round(bboxMid[1] - 0.5 * h); + + ElementMediator.setProperty(canvasArray, "left", [left+"px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "left", parseInt(left) + "px"); + ElementMediator.setProperty(canvasArray, "top", [top + "px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "top", parseInt(top) + "px"); + + //update the viewport and projection to reflect the new canvas width and height (todo might be unnecessary since we don't use RDGE for now) world.setViewportFromCanvas(canvas); if (this._useWebGL){ var cam = world.renderer.cameraManager().getActiveCamera(); @@ -677,10 +693,6 @@ exports.PenTool = Montage.create(ShapeTool, { var subpath = this._selectedSubpath; subpath.setDrawingTool(this); - subpath.setPlaneMatrix(planeMat); - var planeMatInv = glmat4.inverse( planeMat, [] ); - subpath.setPlaneMatrixInverse(planeMatInv); - subpath.setPlaneCenter(midPt); subpath.setWorld(world); world.addIfNewObject(subpath); @@ -829,6 +841,7 @@ exports.PenTool = Montage.create(ShapeTool, { ctx.strokeStyle = "green"; //if (subpath.getStrokeColor()) // ctx.strokeStyle = MathUtils.colorToHex( subpath.getStrokeColor() ); + ctx.beginPath(); var p0x = subpath.getAnchor(0).getPosX()+ horizontalOffset; var p0y = subpath.getAnchor(0).getPosY()+ verticalOffset; @@ -881,7 +894,6 @@ exports.PenTool = Montage.create(ShapeTool, { ctx.strokeStyle = "green"; var anchorDelta = 2; var selAnchorDelta = 4; - for (var i = 0; i < numAnchors; i++) { var px = subpath.getAnchor(i).getPosX(); var py = subpath.getAnchor(i).getPosY(); -- cgit v1.2.3