From 7fed1940bb4f3a333cef92fd51787a29e6dd787b Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Tue, 10 Apr 2012 14:18:02 -0700 Subject: compute and store local coordinates for all anchor points and their control handles separately, AND more hit testing with local coordinates --- js/lib/geom/sub-path.js | 165 ++++++++++++++++++++++++++++++++++++++++-------- js/tools/PenTool.js | 76 +++++++++++----------- 2 files changed, 175 insertions(+), 66 deletions(-) diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js index 33bcfc9a..64f27bd3 100755 --- a/js/lib/geom/sub-path.js +++ b/js/lib/geom/sub-path.js @@ -57,7 +57,7 @@ var GLSubpath = function GLSubpath() { 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._AnchorLocalCoords = []; //local coords for all the anchor points , stored as a triplet of 3D vectors (prev, curr, next, in order) this._UnprojectedAnchors = []; //initially set the _dirty bit so we will construct samples @@ -66,6 +66,9 @@ var GLSubpath = function GLSubpath() { //initially set the local dirty bit so we will construct local coordinates this._isLocalDirty = true; + //initially set the local dirty bit for the anchors so we will construct local coordinates + this._isAnchorLocalDirty = true; + //whether or not to use the canvas drawing to stroke/fill this._useCanvasDrawing = true; @@ -92,8 +95,8 @@ var GLSubpath = function GLSubpath() { //tool that owns this subpath this._drawingTool = null; - this._planeMat = null; - this._planeMatInv = null; + this._planeMat = Matrix.I(4); + this._planeMatInv = Matrix.I(4); this._planeCenter = null; this._dragPlane = null; @@ -498,6 +501,27 @@ GLSubpath.prototype.insertAnchorAtParameter = function(index, param) { this._dirty = true; }; +GLSubpath.prototype._checkIntersectionWithSampleLocalCoord = function(startIndex, endIndex, point, radius){ + //check whether the point is within the radius distance from the curve represented as a polyline in _samples + //return the parametric distance along the curve if there is an intersection, else return null + //will assume that the BBox test is performed outside this function + if (endIndexanchorIndex && this._LocalPoints.length > this._anchorSampleIndex[anchorIndex]) { - var localCoord = this._LocalPoints[this._anchorSampleIndex[anchorIndex]] - var distSq = VecUtils.vecDistSq(3, [pickX, pickY, pickZ], localCoord); + if (useLocal && this._AnchorLocalCoords.length > anchorIndex) {//this._anchorSampleIndex.length>anchorIndex && this._LocalPoints.length > this._anchorSampleIndex[anchorIndex]) { + //var localCoord = this._LocalPoints[this._anchorSampleIndex[anchorIndex]]; + var anchorLocalCoord = this._AnchorLocalCoords[anchorIndex]; + var distSq = VecUtils.vecDistSq(3, [pickX, pickY, pickZ], anchorLocalCoord[1]); //check the anchor point if (distSq < radSq && distSq= this._Anchors.length || index>=this._anchorSampleIndex.length){ + if (index<0 || index>= this._Anchors.length){ + return null; + } + + if (index>= this._AnchorLocalCoords.length || this._isAnchorLocalDirty){ + this._isAnchorLocalDirty = true; + this.buildAnchorLocalCoord(); + } + + return this._AnchorLocalCoords[index]; + /* + if (index>=this._anchorSampleIndex.length){ return null; } var anchorSampleIndex = this._anchorSampleIndex[index]; @@ -1160,6 +1231,55 @@ GLSubpath.prototype.getAnchorLocalCoord = function(index){ } var localCoord = this._LocalPoints[anchorSampleIndex].slice(0); return localCoord; + */ +}; + +GLSubpath.prototype.buildAnchorLocalCoord = function() +{ + if (!this._isAnchorLocalDirty){ + return; //nothing to do + } + var ViewUtils = require("js/helper-classes/3D/view-utils").ViewUtils; + var SnapManager = require("js/helper-classes/3D/snap-manager").SnapManager; + + var widthAdjustment = -SnapManager.getStageWidth()*0.5; + var heightAdjustment = -SnapManager.getStageHeight()*0.5; + + var drawingCanvas = this.getCanvas(); + if (!drawingCanvas){ + drawingCanvas = ViewUtils.getStageElement(); + } + var localToStageWorldMat = ViewUtils.getLocalToStageWorldMatrix(drawingCanvas, true, false); + var stageWorldToLocalMat = glmat4.inverse(localToStageWorldMat, []); + var numAnchors = this._Anchors.length; + this._AnchorLocalCoords = []; + var i=0, currAnchor, prevLocalCoord, currLocalCoord, nextLocalCoord; + for (i=0;i=0 && this._hoveredAnchorIndex=0) { + currAnchorLocalCoord = subpath.getAnchorLocalCoord(this._snapTargetIndex); + sp = MathUtils.transformAndDivideHomogeneousPoint(currAnchorLocalCoord[1],localToGlobalMat); //convert from local coord to global (screen) coordpx = sp[0]; py =sp[1]; ctx.lineWidth = 2; ctx.strokeStyle = "red"; @@ -1166,7 +1164,7 @@ exports.PenTool = Montage.create(ShapeTool, { this._selectedSubpath = null; this._penCanvas = null; this._penPlaneMat = null; - this._snapTarget = null; + this._snapTargetIndex = -1; defaultEventManager.removeEventListener("resetPenTool", this, false); this.application.ninja.elementMediator.deleteDelegate = null; } //if the pen tool was de-selected -- cgit v1.2.3