diff options
Diffstat (limited to 'js/lib/geom/sub-path.js')
-rwxr-xr-x | js/lib/geom/sub-path.js | 104 |
1 files changed, 101 insertions, 3 deletions
diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js index ab54d1e9..7046673e 100755 --- a/js/lib/geom/sub-path.js +++ b/js/lib/geom/sub-path.js | |||
@@ -6,7 +6,7 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot | |||
6 | 6 | ||
7 | 7 | ||
8 | var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; | 8 | var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; |
9 | 9 | var CanvasController = require("js/controllers/elements/canvas-controller").CanvasController; | |
10 | var GeomObj = require("js/lib/geom/geom-obj").GeomObj; | 10 | var GeomObj = require("js/lib/geom/geom-obj").GeomObj; |
11 | var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint; | 11 | var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint; |
12 | var MaterialsModel = require("js/models/materials-model").MaterialsModel; | 12 | var MaterialsModel = require("js/models/materials-model").MaterialsModel; |
@@ -61,6 +61,9 @@ var GLSubpath = function GLSubpath() { | |||
61 | //whether or not to use the canvas drawing to stroke/fill | 61 | //whether or not to use the canvas drawing to stroke/fill |
62 | this._useCanvasDrawing = true; | 62 | this._useCanvasDrawing = true; |
63 | 63 | ||
64 | //the canvas that will draw this subpath | ||
65 | this._canvas = null; | ||
66 | |||
64 | //the X and Y location of this subpath's canvas in stage world space of Ninja | 67 | //the X and Y location of this subpath's canvas in stage world space of Ninja |
65 | this._canvasX = 0; | 68 | this._canvasX = 0; |
66 | this._canvasY = 0; | 69 | this._canvasY = 0; |
@@ -73,7 +76,7 @@ var GLSubpath = function GLSubpath() { | |||
73 | this._materialAmbient = [0.2, 0.2, 0.2, 1.0]; | 76 | this._materialAmbient = [0.2, 0.2, 0.2, 1.0]; |
74 | this._materialDiffuse = [0.4, 0.4, 0.4, 1.0]; | 77 | this._materialDiffuse = [0.4, 0.4, 0.4, 1.0]; |
75 | this._materialSpecular = [0.4, 0.4, 0.4, 1.0]; | 78 | this._materialSpecular = [0.4, 0.4, 0.4, 1.0]; |
76 | this._fillColor = [0.4, 0.4, 0.4, 1.0]; | 79 | this._fillColor = [1.0, 1.0, 1.0, 0.0]; |
77 | this._fillMaterial = null; | 80 | this._fillMaterial = null; |
78 | this._DISPLAY_ANCHOR_RADIUS = 5; | 81 | this._DISPLAY_ANCHOR_RADIUS = 5; |
79 | //drawing context | 82 | //drawing context |
@@ -131,6 +134,11 @@ var GLSubpath = function GLSubpath() { | |||
131 | var bboxHeight = bboxMax[1] - bboxMin[1]; | 134 | var bboxHeight = bboxMax[1] - bboxMin[1]; |
132 | var bboxMid = [0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]; | 135 | var bboxMid = [0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]; |
133 | 136 | ||
137 | if (this._canvas) { | ||
138 | CanvasController.setProperty(this._canvas, "width", bboxWidth+"px"); | ||
139 | CanvasController.setProperty(this._canvas, "height", bboxHeight+"px"); | ||
140 | this._canvas.elementModel.shapeModel.GLWorld.setViewportFromCanvas(this._canvas); | ||
141 | } | ||
134 | ctx.clearRect(0, 0, bboxWidth, bboxHeight); | 142 | ctx.clearRect(0, 0, bboxWidth, bboxHeight); |
135 | 143 | ||
136 | ctx.lineWidth = this._strokeWidth; | 144 | ctx.lineWidth = this._strokeWidth; |
@@ -144,6 +152,7 @@ var GLSubpath = function GLSubpath() { | |||
144 | //ctx.fillStyle = MathUtils.colorToHex( this._fillColor ); | 152 | //ctx.fillStyle = MathUtils.colorToHex( this._fillColor ); |
145 | var fillColorStr = "rgba("+parseInt(255*this._fillColor[0])+","+parseInt(255*this._fillColor[1])+","+parseInt(255*this._fillColor[2])+","+this._fillColor[3]+")"; | 153 | var fillColorStr = "rgba("+parseInt(255*this._fillColor[0])+","+parseInt(255*this._fillColor[1])+","+parseInt(255*this._fillColor[2])+","+this._fillColor[3]+")"; |
146 | ctx.fillStyle = fillColorStr; | 154 | ctx.fillStyle = fillColorStr; |
155 | console.log("Fill color:" + fillColorStr); | ||
147 | } | 156 | } |
148 | var lineCap = ['butt','round','square']; | 157 | var lineCap = ['butt','round','square']; |
149 | ctx.lineCap = lineCap[1]; | 158 | ctx.lineCap = lineCap[1]; |
@@ -256,6 +265,10 @@ GLSubpath.prototype = new GeomObj(); | |||
256 | ///////////////////////////////////////////////////////// | 265 | ///////////////////////////////////////////////////////// |
257 | // Property Accessors/Setters | 266 | // Property Accessors/Setters |
258 | ///////////////////////////////////////////////////////// | 267 | ///////////////////////////////////////////////////////// |
268 | GLSubpath.prototype.setCanvas = function (c) { | ||
269 | this._canvas = c; | ||
270 | }; | ||
271 | |||
259 | GLSubpath.prototype.setWorld = function (world) { | 272 | GLSubpath.prototype.setWorld = function (world) { |
260 | this._world = world; | 273 | this._world = world; |
261 | }; | 274 | }; |
@@ -584,6 +597,90 @@ GLSubpath.prototype.pickAnchor = function (pickX, pickY, pickZ, radius) { | |||
584 | return selAnchorIndex; | 597 | return selAnchorIndex; |
585 | }; | 598 | }; |
586 | 599 | ||
600 | GLSubpath.prototype.isWithinBBox =function(x,y,z){ | ||
601 | if (this._BBoxMin[0]>x || this._BBoxMin[1]>y || this._BBoxMin[2]>z){ | ||
602 | return false; | ||
603 | } | ||
604 | if (this._BBoxMax[0]<x || this._BBoxMax[1]<y || this._BBoxMax[2]<z){ | ||
605 | return false; | ||
606 | } | ||
607 | return true; | ||
608 | } | ||
609 | |||
610 | //pick the path point closest to the specified location, return null if some anchor point (or its handles) is within radius, else return the parameter distance | ||
611 | GLSubpath.prototype.pathHitTest = function (pickX, pickY, pickZ, radius) { | ||
612 | var numAnchors = this._Anchors.length; | ||
613 | var selAnchorIndex = -1; | ||
614 | var retParam = null; | ||
615 | var radSq = radius * radius; | ||
616 | var minDistance = Infinity; | ||
617 | |||
618 | //check if the location is close to the currently selected anchor position | ||
619 | if (this._selectedAnchorIndex>=0 && this._selectedAnchorIndex<this._Anchors.length){ | ||
620 | var distSq = this._Anchors[this._selectedAnchorIndex].getDistanceSq(pickX, pickY, pickZ); | ||
621 | //check the anchor point | ||
622 | if (distSq < minDistance && distSq < radSq) { | ||
623 | selAnchorIndex = this._selectedAnchorIndex; | ||
624 | minDistance = distSq; | ||
625 | } | ||
626 | } | ||
627 | //check the prev and next of the selected anchor if the above did not register a hit | ||
628 | if (this._selectedAnchorIndex>=0 && selAnchorIndex === -1) { | ||
629 | var distSq = this._Anchors[this._selectedAnchorIndex].getPrevDistanceSq(pickX, pickY, pickZ); | ||
630 | if (distSq < minDistance && distSq < radSq){ | ||
631 | selAnchorIndex = this._selectedAnchorIndex; | ||
632 | minDistance = distSq; | ||
633 | } else { | ||
634 | //check the next for this anchor point | ||
635 | distSq = this._Anchors[this._selectedAnchorIndex].getNextDistanceSq(pickX, pickY, pickZ); | ||
636 | if (distSq<minDistance && distSq<radSq){ | ||
637 | selAnchorIndex = this._selectedAnchorIndex; | ||
638 | minDistance = distSq; | ||
639 | } | ||
640 | } | ||
641 | } | ||
642 | |||
643 | //now check if the location is close to any anchor position | ||
644 | if (selAnchorIndex===-1) { | ||
645 | for (var i = 0; i < numAnchors; i++) { | ||
646 | var distSq = this._Anchors[i].getDistanceSq(pickX, pickY, pickZ); | ||
647 | //check the anchor point | ||
648 | if (distSq < minDistance && distSq < radSq) { | ||
649 | selAnchorIndex = i; | ||
650 | minDistance = distSq; | ||
651 | } | ||
652 | }//for every anchor i | ||
653 | } | ||
654 | |||
655 | //finally check if the location is close to the curve itself | ||
656 | if (selAnchorIndex===-1) { | ||
657 | //first check if the input location is within the bounding box | ||
658 | if (this.isWithinBBox(pickX,pickY,pickZ)){ | ||
659 | var numSegments = this._isClosed ? numAnchors : numAnchors-1; | ||
660 | for (var i = 0; i < numSegments; i++) { | ||
661 | var nextIndex = (i+1)%numAnchors; | ||
662 | //check if the point is close to the bezier segment between anchor i and anchor nextIndex | ||
663 | var controlPoints = [[this._Anchors[i].getPosX(),this._Anchors[i].getPosY(),this._Anchors[i].getPosZ()], | ||
664 | [this._Anchors[i].getNextX(),this._Anchors[i].getNextY(),this._Anchors[i].getNextZ()], | ||
665 | [this._Anchors[nextIndex].getPrevX(),this._Anchors[nextIndex].getPrevY(),this._Anchors[nextIndex].getPrevZ()], | ||
666 | [this._Anchors[nextIndex].getPosX(),this._Anchors[nextIndex].getPosY(),this._Anchors[nextIndex].getPosZ()]]; | ||
667 | var point = [pickX, pickY, pickZ]; | ||
668 | if (this._isWithinBoundingBox(point, controlPoints, radius)) { | ||
669 | //var intersectParam = this._checkIntersection(controlPoints, 0.0, 1.0, point, radius); | ||
670 | var intersectParam = this._checkIntersectionWithSamples(this._anchorSampleIndex[i], this._anchorSampleIndex[nextIndex], point, radius); | ||
671 | console.log("intersectParam:"+intersectParam); | ||
672 | if (intersectParam){ | ||
673 | selAnchorIndex=i; | ||
674 | retParam = intersectParam-i; //make the retParam go from 0 to 1 | ||
675 | break; | ||
676 | } | ||
677 | } | ||
678 | }//for every anchor i | ||
679 | }//if is within bbox | ||
680 | } | ||
681 | return [selAnchorIndex,retParam]; | ||
682 | } //GLSubpath.pathHitTest function | ||
683 | |||
587 | //pick the path point closest to the specified location, return null if some anchor point (or its handles) is within radius, else return the parameter distance | 684 | //pick the path point closest to the specified location, return null if some anchor point (or its handles) is within radius, else return the parameter distance |
588 | GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius) { | 685 | GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius) { |
589 | var numAnchors = this._Anchors.length; | 686 | var numAnchors = this._Anchors.length; |
@@ -689,6 +786,7 @@ GLSubpath.prototype.getStrokeWidth = function () { | |||
689 | 786 | ||
690 | GLSubpath.prototype.setStrokeWidth = function (w) { | 787 | GLSubpath.prototype.setStrokeWidth = function (w) { |
691 | this._strokeWidth = w; | 788 | this._strokeWidth = w; |
789 | this._dirty=true; | ||
692 | }; | 790 | }; |
693 | 791 | ||
694 | GLSubpath.prototype.getStrokeMaterial = function () { | 792 | GLSubpath.prototype.getStrokeMaterial = function () { |
@@ -1105,7 +1203,7 @@ GLSubpath.prototype.getNearVertex = function( eyePt, dir ){ | |||
1105 | bboxDim[1] = 0.5 * (this._BBoxMax[1] - this._BBoxMin[1]); | 1203 | bboxDim[1] = 0.5 * (this._BBoxMax[1] - this._BBoxMin[1]); |
1106 | bboxMid[1] = 0.5 * (this._BBoxMax[1] + this._BBoxMin[1]); | 1204 | bboxMid[1] = 0.5 * (this._BBoxMax[1] + this._BBoxMin[1]); |
1107 | bboxDim[2] = 0.5 * (this._BBoxMax[2] - this._BBoxMin[2]); | 1205 | bboxDim[2] = 0.5 * (this._BBoxMax[2] - this._BBoxMin[2]); |
1108 | bboxMid[3] = 0.5 * (this._BBoxMax[2] + this._BBoxMin[2]); | 1206 | bboxMid[2] = 0.5 * (this._BBoxMax[2] + this._BBoxMin[2]); |
1109 | 1207 | ||
1110 | // convert the stroke vertices into normalized device coordinates | 1208 | // convert the stroke vertices into normalized device coordinates |
1111 | var world = this.getWorld(); | 1209 | var world = this.getWorld(); |