aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPushkar Joshi2012-04-17 14:43:37 -0700
committerPushkar Joshi2012-04-17 14:43:37 -0700
commit036cf034e124dbc1f4893e90f7c6d240904a3faf (patch)
treea6ee7524d8904a0945021cdd0e9bcd212904ba6c
parent7c82ee4f217ea86ee4ebee80da29481f31e5019d (diff)
downloadninja-036cf034e124dbc1f4893e90f7c6d240904a3faf.tar.gz
Snapshot for pen tool before merging with master....can draw polylines (no prev, next) handles and hit testing in 3D. Update of the canvas with a transformation on it will modify the canvas incorrectly, and will be completed after merging with master
-rwxr-xr-xjs/lib/geom/sub-path.js21
-rwxr-xr-xjs/tools/PenTool.js76
2 files changed, 58 insertions, 39 deletions
diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js
index 62937461..7e11bb33 100755
--- a/js/lib/geom/sub-path.js
+++ b/js/lib/geom/sub-path.js
@@ -413,19 +413,21 @@ GLSubpath.prototype._checkIntersectionWithSamples = function(startIndex, endInde
413 //will assume that the BBox test is performed outside this function 413 //will assume that the BBox test is performed outside this function
414 if (endIndex<startIndex){ 414 if (endIndex<startIndex){
415 //go from startIndex to the end of the samples 415 //go from startIndex to the end of the samples
416 endIndex = this._Samples.length; 416 endIndex = this._Samples.length-1;
417 } 417 }
418 for (var i=startIndex; i<endIndex-1; i++){ 418 var retParam = null;
419 for (var i=startIndex; i<endIndex; i++){
419 var seg0 = this._Samples[i].slice(0); 420 var seg0 = this._Samples[i].slice(0);
420 var j=i+1; 421 var j=i+1;
421 var seg1 = this._Samples[j].slice(0); 422 var seg1 = this._Samples[j].slice(0);
422 var distToSegment = MathUtils.distPointToSegment(point, seg0, seg1); 423 var distToSegment = MathUtils.distPointToSegment(point, seg0, seg1);
423 if (distToSegment<=radius){ 424 if (distToSegment<=radius){
424 var paramDistance = MathUtils.paramPointProjectionOnSegment(point, seg0, seg1); //TODO Optimize! this function was called in distPointToSegment above 425 var paramDistance = MathUtils.paramPointProjectionOnSegment(point, seg0, seg1); //TODO Optimize! this function was called in distPointToSegment above
425 return this._sampleParam[i] + (this._sampleParam[j] - this._sampleParam[i])*paramDistance; 426 retParam = this._sampleParam[i] + (this._sampleParam[j] - this._sampleParam[i])*paramDistance;
427 break;
426 } 428 }
427 } 429 }
428 return null; 430 return retParam;
429}; 431};
430 432
431GLSubpath.prototype._checkIntersection = function(controlPts, beginParam, endParam, point, radius) { 433GLSubpath.prototype._checkIntersection = function(controlPts, beginParam, endParam, point, radius) {
@@ -589,6 +591,10 @@ GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius, testOnly)
589 selAnchorIndex = anchorAndRetCode[0]; 591 selAnchorIndex = anchorAndRetCode[0];
590 retCode = anchorAndRetCode[1]; 592 retCode = anchorAndRetCode[1];
591 593
594 if (retCode!== this.SEL_NONE){
595 retCode = retCode | this.SEL_PATH; //ensure that path is also selected if anything else is selected
596 }
597
592 //if the location is not close any of the anchors, check if it is close to the curve itself 598 //if the location is not close any of the anchors, check if it is close to the curve itself
593 if (selAnchorIndex===-1) { 599 if (selAnchorIndex===-1) {
594 //first check if the input location is within the bounding box 600 //first check if the input location is within the bounding box
@@ -603,9 +609,11 @@ GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius, testOnly)
603 [this._Anchors[nextIndex].getPosX(),this._Anchors[nextIndex].getPosY(),this._Anchors[nextIndex].getPosZ()]]; 609 [this._Anchors[nextIndex].getPosX(),this._Anchors[nextIndex].getPosY(),this._Anchors[nextIndex].getPosZ()]];
604 var point = [pickX, pickY, pickZ]; 610 var point = [pickX, pickY, pickZ];
605 if (this._isWithinGivenBoundingBox(point, controlPoints, radius)) { 611 if (this._isWithinGivenBoundingBox(point, controlPoints, radius)) {
612 //var intersectParam = this._checkIntersection(controlPoints, 0.0, 1.0, point, radius);
606 var intersectParam = this._checkIntersectionWithSamples(this._anchorSampleIndex[i], this._anchorSampleIndex[nextIndex], point, radius); 613 var intersectParam = this._checkIntersectionWithSamples(this._anchorSampleIndex[i], this._anchorSampleIndex[nextIndex], point, radius);
607 if (intersectParam){ 614 if (intersectParam!==null){
608 selAnchorIndex=i; 615 selAnchorIndex=i;
616 retCode = retCode | this.SEL_PATH;
609 retParam = intersectParam-i; //make the retParam go from 0 to 1 617 retParam = intersectParam-i; //make the retParam go from 0 to 1
610 break; 618 break;
611 } 619 }
@@ -614,9 +622,6 @@ GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius, testOnly)
614 }//if is within bbox 622 }//if is within bbox
615 } 623 }
616 624
617 if (retCode!== this.SEL_NONE)
618 retCode = retCode | this.SEL_PATH; //ensure that path is also selected if anything else is selected
619
620 if (!testOnly){ 625 if (!testOnly){
621 this._selectMode = retCode; 626 this._selectMode = retCode;
622 this._selectedAnchorIndex = selAnchorIndex; 627 this._selectedAnchorIndex = selAnchorIndex;
diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js
index 50fd97d7..0661c3ea 100755
--- a/js/tools/PenTool.js
+++ b/js/tools/PenTool.js
@@ -282,6 +282,13 @@ exports.PenTool = Montage.create(ShapeTool, {
282 // Compute the mouse position in local (selected subpath canvas) space 282 // Compute the mouse position in local (selected subpath canvas) space
283 var globalPos = hitRec.getScreenPoint(); 283 var globalPos = hitRec.getScreenPoint();
284 var localMousePos = ViewUtils.globalToLocal(globalPos, this._selectedSubpathCanvas); 284 var localMousePos = ViewUtils.globalToLocal(globalPos, this._selectedSubpathCanvas);
285 /*
286 CHECK IF THIS IS CORRECT
287 ViewUtils.pushViewportObj
288 var temp ViewUtils.screenToView(localMousePos[0], localMousePos[1], 0) should return a point in view space of canvas
289 ViewUtils.popViewportObj
290 MathUtils.transformPoint(temp, this._selectedSubpathPlaneMat)
291 */
285 292
286 //now perform the hit testing 293 //now perform the hit testing
287 var prevSelectedAnchorIndex = this._selectedSubpath.getSelectedAnchorIndex(); 294 var prevSelectedAnchorIndex = this._selectedSubpath.getSelectedAnchorIndex();
@@ -312,8 +319,13 @@ exports.PenTool = Montage.create(ShapeTool, {
312 //if we have selected the first anchor point, and previously had selected the last anchor point, close the path 319 //if we have selected the first anchor point, and previously had selected the last anchor point, close the path
313 var numAnchors = this._selectedSubpath.getNumAnchors(); 320 var numAnchors = this._selectedSubpath.getNumAnchors();
314 if (numAnchors>1 && !this._selectedSubpath.getIsClosed() && this._selectedSubpath.getSelectedAnchorIndex()===0 && prevSelectedAnchorIndex === numAnchors-1){ 321 if (numAnchors>1 && !this._selectedSubpath.getIsClosed() && this._selectedSubpath.getSelectedAnchorIndex()===0 && prevSelectedAnchorIndex === numAnchors-1){
315 //setting the selection mode to NONE will effectively add a new anchor point at the click location and also give us snapping 322 //insert an anchor temporarily that will get removed in the mouse up handler
316 whichPoint = this._selectedSubpath.SEL_NONE; 323 this._selectedSubpath.addAnchor(new AnchorPoint());
324 var newAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex());
325 newAnchor.setPos(localMousePos[0], localMousePos[1], localMousePos[2]);
326 newAnchor.setPrevPos(localMousePos[0], localMousePos[1], localMousePos[2]);
327 newAnchor.setNextPos(localMousePos[0], localMousePos[1], localMousePos[2]);
328
317 //set the snap target in case the mouse move handler doesn't get called 329 //set the snap target in case the mouse move handler doesn't get called
318 this._snapTargetIndex = 0; 330 this._snapTargetIndex = 0;
319 } 331 }
@@ -489,7 +501,6 @@ exports.PenTool = Montage.create(ShapeTool, {
489 var globalMousePos = hitRec.getScreenPoint(); 501 var globalMousePos = hitRec.getScreenPoint();
490 var localMousePos = ViewUtils.globalToLocal(globalMousePos, drawingCanvas); 502 var localMousePos = ViewUtils.globalToLocal(globalMousePos, drawingCanvas);
491 503
492
493 //var selAnchorRetCode = this._selectedSubpath.pickAnchor(currMousePos[0], currMousePos[1], currMousePos[2], this._PICK_POINT_RADIUS, false); 504 //var selAnchorRetCode = this._selectedSubpath.pickAnchor(currMousePos[0], currMousePos[1], currMousePos[2], this._PICK_POINT_RADIUS, false);
494 //var selAnchorRetCode = this._selectedSubpath.pickAnchor(localMousePos[0], localMousePos[1], localMousePos[2], this._PICK_POINT_RADIUS); 505 //var selAnchorRetCode = this._selectedSubpath.pickAnchor(localMousePos[0], localMousePos[1], localMousePos[2], this._PICK_POINT_RADIUS);
495 var selAnchorAndParamAndCode = this._selectedSubpath.pickPath(localMousePos[0], localMousePos[1], localMousePos[2], this._PICK_POINT_RADIUS, true); 506 var selAnchorAndParamAndCode = this._selectedSubpath.pickPath(localMousePos[0], localMousePos[1], localMousePos[2], this._PICK_POINT_RADIUS, true);
@@ -513,7 +524,6 @@ exports.PenTool = Montage.create(ShapeTool, {
513 this.application.ninja.stage.drawingCanvas.style.cursor = cursor; 524 this.application.ninja.stage.drawingCanvas.style.cursor = cursor;
514 } else if (selAnchorAndParamAndCode[2] & this._selectedSubpath.SEL_PATH) { 525 } else if (selAnchorAndParamAndCode[2] & this._selectedSubpath.SEL_PATH) {
515 //change the cursor 526 //change the cursor
516 STOPPED HERE...why is this case not being hit?
517 var cursor = "url('images/cursors/penCursors/Pen_plus.png') 5 1, default"; 527 var cursor = "url('images/cursors/penCursors/Pen_plus.png') 5 1, default";
518 this.application.ninja.stage.drawingCanvas.style.cursor = cursor; 528 this.application.ninja.stage.drawingCanvas.style.cursor = cursor;
519 } 529 }
@@ -723,20 +733,28 @@ exports.PenTool = Montage.create(ShapeTool, {
723 value: function(){ 733 value: function(){
724 var i=0,d=0; 734 var i=0,d=0;
725 var currAnchor = null; 735 var currAnchor = null;
726 var localPos = [[0,0,0],[0,0,0],[0,0,0]]; 736 var xAdjustment = snapManager.getStageWidth()*0.5;
727 //if there is already is a subpath canvas, it means the anchor points are in local space 737 var yAdjustment = snapManager.getStageHeight()*0.5;
738 var localPos = [[0,0,0,0],[0,0,0,0],[0,0,0,0]];
739 //if there already is a subpath canvas, it means the anchor points are in local space
728 // so convert them to stage world space 740 // so convert them to stage world space
729 var numAnchors = this._selectedSubpath.getNumAnchors(); 741 var numAnchors = this._selectedSubpath.getNumAnchors();
730 if (this._selectedSubpathCanvas) { 742 if (this._selectedSubpathCanvas) {
731 var localToStageWorldMat = ViewUtils.getLocalToStageWorldMatrix(this._selectedSubpathCanvas, true, true); 743 //this transformation will take the path points from local space to stage world space
744 // *without* taking into account the transformation applied to this canvas
745 // (this is because we use the center of the bbox to find a place for the canvas)
746 var localToStageWorldMat = ViewUtils.getLocalToStageWorldMatrix(this._selectedSubpathCanvas, true, false);
732 for (i=0;i<numAnchors;i++){ 747 for (i=0;i<numAnchors;i++){
733 //convert this anchor from local to stage world 748 //convert this anchor from local to stage world
734 var currAnchor = this._selectedSubpath.getAnchor(i); 749 var currAnchor = this._selectedSubpath.getAnchor(i);
735 localPos[0] = [currAnchor.getPrevX(), currAnchor.getPrevY(), currAnchor.getPrevZ()]; 750 localPos[0] = [currAnchor.getPrevX(), currAnchor.getPrevY(), currAnchor.getPrevZ(),1];
736 localPos[1] = [currAnchor.getPosX(), currAnchor.getPosY(), currAnchor.getPosZ()]; 751 localPos[1] = [currAnchor.getPosX(), currAnchor.getPosY(), currAnchor.getPosZ(),1];
737 localPos[2] = [currAnchor.getNextX(), currAnchor.getNextY(), currAnchor.getNextZ()]; 752 localPos[2] = [currAnchor.getNextX(), currAnchor.getNextY(), currAnchor.getNextZ(),1];
738 for (d=0;d<3;d++) { 753 for (d=0;d<3;d++) {
739 localPos[d] = MathUtils.transformAndDivideHomogeneousPoint(localPos[d], localToStageWorldMat); 754 localPos[d] = MathUtils.transformAndDivideHomogeneousPoint(localPos[d], localToStageWorldMat);
755 //add half the stage width and height to the X and Y coord.
756 localPos[d][0]+= xAdjustment;
757 localPos[d][1]+= yAdjustment;
740 } 758 }
741 currAnchor.setPrevPos(localPos[0][0],localPos[0][1],localPos[0][2]); 759 currAnchor.setPrevPos(localPos[0][0],localPos[0][1],localPos[0][2]);
742 currAnchor.setPos(localPos[1][0],localPos[1][1],localPos[1][2]); 760 currAnchor.setPos(localPos[1][0],localPos[1][1],localPos[1][2]);
@@ -751,28 +769,21 @@ exports.PenTool = Montage.create(ShapeTool, {
751 var bboxMax = this._selectedSubpath.getBBoxMax(); 769 var bboxMax = this._selectedSubpath.getBBoxMax();
752 770
753 //check if the last point added made this canvas is now bigger than the max canvas size 771 //check if the last point added made this canvas is now bigger than the max canvas size
754 var needToRemoveLastPoint = false;
755 for (d=0;d<3;d++){ 772 for (d=0;d<3;d++){
756 if (bboxMax[d]-bboxMin[d]>this._MAX_CANVAS_DIMENSION){ 773 if (bboxMax[d]-bboxMin[d]>this._MAX_CANVAS_DIMENSION){
757 needToRemoveLastPoint = true; 774 console.log("PEN: Warning! Ignoring last added point because canvas size too large");
775 this._selectedSubpath.removeAnchor(numAnchors-1);
776 numAnchors--;
777 //recompute the bbox of this subpath
778 this._selectedSubpath.createSamples(true);
779 bboxMin = this._selectedSubpath.getBBoxMin();
780 bboxMax = this._selectedSubpath.getBBoxMax();
781 break;
758 } 782 }
759 } 783 }
760 if (needToRemoveLastPoint){ 784
761 console.log("PEN: Warning! Ignoring last added point because canvas size too large")
762 this._selectedSubpath.removeAnchor(numAnchors-1);
763 numAnchors--;
764 //recompute the bbox of this subpath
765 this._selectedSubpath.createSamples(true);
766 bboxMin = this._selectedSubpath.getBBoxMin();
767 bboxMax = this._selectedSubpath.getBBoxMax();
768 }
769 785
770 this._selectedSubpathCanvasCenter = VecUtils.vecInterpolate(3, bboxMin, bboxMax, 0.5); 786 this._selectedSubpathCanvasCenter = VecUtils.vecInterpolate(3, bboxMin, bboxMax, 0.5);
771 if (this._selectedSubpathCanvas) {
772 //if the canvas does not yet exist, the stage world point already have this stage dimension offset below
773 this._selectedSubpathCanvasCenter[0]+= snapManager.getStageWidth()*0.5;
774 this._selectedSubpathCanvasCenter[1]+= snapManager.getStageHeight()*0.5;
775 }
776 787
777 //update the plane matrix of this subpath by querying the element mediator 788 //update the plane matrix of this subpath by querying the element mediator
778 if (this._selectedSubpathCanvas) {