From f492c816575f990429f4540c9a3eb60c28a89623 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 6 Apr 2012 10:53:27 -0700 Subject: complete version of the code for rendering selected subpath anchor points and path overlay (code needs cleanup)...still buggy if creating new paths --- js/helper-classes/3D/view-utils.js | 71 ++++++++++++ js/tools/PenTool.js | 216 ++++++++++++++++++++++++++++--------- 2 files changed, 237 insertions(+), 50 deletions(-) diff --git a/js/helper-classes/3D/view-utils.js b/js/helper-classes/3D/view-utils.js index f60b953a..35f4a568 100755 --- a/js/helper-classes/3D/view-utils.js +++ b/js/helper-classes/3D/view-utils.js @@ -787,6 +787,7 @@ exports.ViewUtils = Montage.create(Component, { } }, + /* getStageWorldToGlobalMatrix: { value: function() { var stage = this.application.ninja.currentDocument.documentRoot; @@ -820,6 +821,26 @@ exports.ViewUtils = Montage.create(Component, { return mat; } }, + */ + getStageWorldToGlobalMatrix: + { + value: function() + { + var stage = this.application.ninja.currentDocument.documentRoot; + + this.pushViewportObj( stage ); + // put the point into screen space of the stage - requires + // a translation to the top/left only + var cop = this.getCenterOfProjection(); + var v2s = Matrix.Translation([cop[0], cop[1], 0]); + this.popViewportObj(); + + // append the localToGlobal matrix of the stage. + var mat = this.getLocalToGlobalMatrix( stage ); + glmat4.multiply( mat, v2s ); + return mat; + } + }, localScreenToLocalWorld: { value: function( objPt, elt ) { @@ -967,6 +988,56 @@ exports.ViewUtils = Montage.create(Component, { } }, + getLocalToStageWorldMatrix: { + value: function( elt, shouldProject, shouldLocalTransform ) { + var mat = Matrix.I(4); + while (elt) + { + this.pushViewportObj( elt ); + var cop = this.getCenterOfProjection(); + var s2v = Matrix.Translation([-cop[0], -cop[1], 0]); + var objMat = this.getMatrixFromElement( elt ); + var projMat; + if(shouldProject) + { + //projMat = Matrix.I(4).multiply( this.getPerspectiveDistFromElement(elt) ); + var pDist = this.getPerspectiveDistFromElement(elt); + var projMat = glmat4.scale(Matrix.I(4), [pDist,pDist,pDist], []); + projMat[11] = -1; + projMat[15] = 1400; + } + var v2s = Matrix.Translation([cop[0], cop[1], 0]); + this.popViewportObj(); + + // multiply all the matrices together + //mat = s2v.multiply( mat ); + glmat4.multiply( s2v, mat, mat ); + if (elt === this._stageElement) break; + //mat = objMat.multiply( mat ); + if (shouldLocalTransform) { + glmat4.multiply( objMat, mat, mat ); + } + if(shouldProject) + { + //mat = projMat.multiply( mat ); + glmat4.multiply( projMat, mat, mat ); + } + //mat = v2s.multiply( mat ); + glmat4.multiply( v2s, mat, mat ); + + // offset to the parent + var offset = this.getElementOffset( elt ); + var offMat = Matrix.Translation([offset[0], offset[1], 0]); + //mat = offMat.multiply( mat ); + glmat4.multiply( offMat, mat, mat ); + + elt = elt.parentElement; + } + + return mat; + } + }, + getUpVectorFromMatrix: { value: function( mat ) { //var inv = mat.inverse(); diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index 962f178d..32902cea 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -351,6 +351,10 @@ exports.PenTool = Montage.create(ShapeTool, { //make the subpath dirty so it will get re-drawn this._selectedSubpath.makeDirty(); + //this.DrawSubpathSVG(this._selectedSubpath); + } + //todo temp code only...remove this and uncomment the DrawSubpathSVG above + if (this._selectedSubpath){ this.DrawSubpathSVG(this._selectedSubpath); } @@ -825,6 +829,7 @@ exports.PenTool = Montage.create(ShapeTool, { throw ("null drawing context in Pentool::DrawSubpathSVG"); ctx.save(); + /* var horizontalOffset = this.application.ninja.stage.userContentLeft; var verticalOffset = this.application.ninja.stage.userContentTop; //display the subpath as a sequence of cubic beziers @@ -854,34 +859,84 @@ exports.PenTool = Montage.create(ShapeTool, { var p3y = subpath.getAnchor(0).getPosY()+ verticalOffset; ctx.bezierCurveTo(p1x, p1y, p2x, p2y, p3x, p3y); } - ctx.stroke(); + ctx.stroke();*/ //draw the stage world points by projecting them to screen space //get the screen coords of this anchor from its stage world coord - ctx.beginPath(); - ctx.strokeStyle = "red"; + ctx.lineWidth = 1;//TODO replace hardcoded stroke width with some programmatically set value (should not be same as stroke width) + ctx.strokeStyle = "green"; var localToGlobalMat = ViewUtils.getLocalToGlobalMatrix(subpath.getCanvas()); - var currentLTWH = subpath.computeLeftTopWidthHeight(); + + /*var currentLTWH = subpath.computeLeftTopWidthHeight(); var deltaX = currentLTWH[0] - parseInt(ElementMediator.getProperty(subpath.getCanvas(), "left")); - var deltaY = currentLTWH[1] - parseInt(ElementMediator.getProperty(subpath.getCanvas(), "top")); + var deltaY = currentLTWH[1] - parseInt(ElementMediator.getProperty(subpath.getCanvas(), "top"));*/ - var localCoord = subpath.getAnchorLocalCoord(0); - var sp = MathUtils.transformAndDivideHomogeneousPoint(localCoord,localToGlobalMat); + //var localCoord = subpath.getAnchorLocalCoord(0); + //var sp = MathUtils.transformAndDivideHomogeneousPoint(localCoord,localToGlobalMat); //add the difference between the current left and top and the canvas left and top - sp[0]+=deltaX; sp[1]+=deltaY; + //sp[0]+=deltaX; sp[1]+=deltaY; + //ctx.moveTo(sp[0], sp[1]); + + var widthAdjustment = -snapManager.getStageWidth()*0.5; + var heightAdjustment = -snapManager.getStageHeight()*0.5; + /*var stageWorldToGlobalMatrix = ViewUtils.getStageWorldToGlobalMatrix(); + var localToStageWorldMatrix = ViewUtils.getMatrixFromElement(subpath.getCanvas()); + glmat4.multiply(localToStageWorldMatrix, stageWorldToGlobalMatrix, stageWorldToGlobalMatrix);*/ + var localToStageWorldMat = ViewUtils.getLocalToStageWorldMatrix(subpath.getCanvas(), true, false); + var stageWorldToLocalMat = glmat4.inverse(localToStageWorldMat, []); + + var c0=[0,0,0], c1=[0,0,0],c2=[0,0,0], c3=[0,0,0]; //screen coord of the bezier control points + c0 = MathUtils.transformAndDivideHomogeneousPoint( + [subpath.getAnchor(0).getPosX()+widthAdjustment, + subpath.getAnchor(0).getPosY()+heightAdjustment, + subpath.getAnchor(0).getPosZ()], + stageWorldToLocalMat); + c0 = MathUtils.transformAndDivideHomogeneousPoint(c0,localToGlobalMat); //convert from local coord to global (screen) coord + ctx.beginPath(); + ctx.moveTo(c0[0],c0[1]); + var prevAnchor = subpath.getAnchor(0); + var currAnchor = null; + var numBezierCurves = numAnchors; + if (subpath.getIsClosed()){ + numBezierCurves+=1; + } - ctx.moveTo(sp[0],sp[1]); - for (i = 1; i < numAnchors; i++) { - localCoord = subpath.getAnchorLocalCoord(i); + for (i = 1; i < numBezierCurves; i++) { + currAnchor = subpath.getAnchor(i%numAnchors); + /*localCoord = subpath.getAnchorLocalCoord(i); sp = MathUtils.transformAndDivideHomogeneousPoint(localCoord,localToGlobalMat); //add the difference between the current left and top and the canvas left and top - sp[0]+=deltaX; sp[1]+=deltaY; - ctx.lineTo(sp[0],sp[1]); - } - if (subpath.getIsClosed()){ - ctx.closePath(); + sp[0]+=deltaX; sp[1]+=deltaY;*/ + + //ctx.lineTo(sp[0], sp[1]); + + c1 = MathUtils.transformAndDivideHomogeneousPoint( + [prevAnchor.getNextX()+widthAdjustment, + prevAnchor.getNextY()+heightAdjustment, + prevAnchor.getNextZ()], + stageWorldToLocalMat); + c1 = MathUtils.transformAndDivideHomogeneousPoint(c1,localToGlobalMat); //convert from local coord to global (screen) coord + + c2 = MathUtils.transformAndDivideHomogeneousPoint( + [currAnchor.getPrevX()+widthAdjustment, + currAnchor.getPrevY()+heightAdjustment, + currAnchor.getPrevZ()], + stageWorldToLocalMat); + c2 = MathUtils.transformAndDivideHomogeneousPoint(c2,localToGlobalMat); //convert from local coord to global (screen) coord + + c3 = MathUtils.transformAndDivideHomogeneousPoint( + [currAnchor.getPosX()+widthAdjustment, + currAnchor.getPosY()+heightAdjustment, + currAnchor.getPosZ()], + stageWorldToLocalMat); + c3 = MathUtils.transformAndDivideHomogeneousPoint(c3,localToGlobalMat); //convert from local coord to global (screen) coord + + ctx.bezierCurveTo(c1[0], c1[1], c2[0], c2[1], c3[0], c3[1]); + prevAnchor = currAnchor; } + + ctx.stroke(); ctx.restore(); @@ -905,27 +960,43 @@ exports.PenTool = Montage.create(ShapeTool, { var horizontalOffset = this.application.ninja.stage.userContentLeft;//stageManagerModule.stageManager.userContentLeft; var verticalOffset = this.application.ninja.stage.userContentTop;//stageManagerModule.stageManager.userContentTop; + var widthAdjustment = -snapManager.getStageWidth()*0.5; + var heightAdjustment = -snapManager.getStageHeight()*0.5; + var localToGlobalMat = ViewUtils.getLocalToGlobalMatrix(subpath.getCanvas()); - var currentLTWH = subpath.computeLeftTopWidthHeight(); + /*var currentLTWH = subpath.computeLeftTopWidthHeight(); var deltaX = currentLTWH[0] - parseInt(ElementMediator.getProperty(subpath.getCanvas(), "left")); var deltaY = currentLTWH[1] - parseInt(ElementMediator.getProperty(subpath.getCanvas(), "top")); + */ + var localToStageWorldMat = ViewUtils.getLocalToStageWorldMatrix(subpath.getCanvas(), true, false); + var stageWorldToLocalMat = glmat4.inverse(localToStageWorldMat, []); + + //display circles and squares near all control points ctx.fillStyle = "#FFFFFF"; ctx.lineWidth = 1; ctx.strokeStyle = "green"; var anchorDelta = 2; var selAnchorDelta = 4; + var px=0,py=0; + var localCoord = null; + var sp=[0,0,0]; + var currAnchor = null; for (var i = 0; i < numAnchors; i++) { - var px = subpath.getAnchor(i).getPosX()+horizontalOffset; - var py = subpath.getAnchor(i).getPosY()+verticalOffset; - var localCoord = subpath.getAnchorLocalCoord(i); - if (localCoord) { - var sp = MathUtils.transformAndDivideHomogeneousPoint(localCoord,localToGlobalMat); - px = sp[0]; py=sp[1]; - sp[0]+=deltaX; sp[1]+=deltaY; - } + currAnchor = subpath.getAnchor(i); + //px = currAnchor.getPosX()+horizontalOffset; + //py = currAnchor.getPosY()+verticalOffset; + //var localCoordOld = subpath.getAnchorLocalCoord(i); + localCoord = MathUtils.transformAndDivideHomogeneousPoint([currAnchor.getPosX()+widthAdjustment, currAnchor.getPosY()+heightAdjustment, currAnchor.getPosZ()], stageWorldToLocalMat); //convert from stage world to local coord + //localCoord[0]-=snapManager.getStageWidth()*0.5; + //localCoord[1]-=snapManager.getStageHeight()*0.5; + //sp = MathUtils.transformAndDivideHomogeneousPoint(localCoordOld,localToGlobalMat); //convert from local coord to global (screen) coord + sp = MathUtils.transformAndDivideHomogeneousPoint(localCoord,localToGlobalMat); //convert from local coord to global (screen) coord + //sp[0]+=deltaX; sp[1]+=deltaY; + px = sp[0]; py=sp[1]; + ctx.beginPath(); //ctx.arc(px + horizontalOffset, py + verticalOffset, this._DISPLAY_ANCHOR_RADIUS, 0, 2 * Math.PI, false); ctx.moveTo(px-anchorDelta, py-anchorDelta); @@ -935,20 +1006,22 @@ exports.PenTool = Montage.create(ShapeTool, { ctx.closePath(); ctx.fill(); ctx.stroke(); - } //display the hovered over anchor point ctx.lineWidth = 2; if (this._hoveredAnchorIndex>=0 && this._hoveredAnchorIndex