aboutsummaryrefslogtreecommitdiff
path: root/js/lib/geom/sub-path.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/lib/geom/sub-path.js')
-rwxr-xr-xjs/lib/geom/sub-path.js104
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
8var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; 8var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils;
9 9var CanvasController = require("js/controllers/elements/canvas-controller").CanvasController;
10var GeomObj = require("js/lib/geom/geom-obj").GeomObj; 10var GeomObj = require("js/lib/geom/geom-obj").GeomObj;
11var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint; 11var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint;
12var MaterialsModel = require("js/models/materials-model").MaterialsModel; 12var 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/////////////////////////////////////////////////////////
268GLSubpath.prototype.setCanvas = function (c) {
269 this._canvas = c;
270};
271
259GLSubpath.prototype.setWorld = function (world) { 272GLSubpath.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
600GLSubpath.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
611GLSubpath.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
588GLSubpath.prototype.pickPath = function (pickX, pickY, pickZ, radius) { 685GLSubpath.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
690GLSubpath.prototype.setStrokeWidth = function (w) { 787GLSubpath.prototype.setStrokeWidth = function (w) {
691 this._strokeWidth = w; 788 this._strokeWidth = w;
789 this._dirty=true;
692}; 790};
693 791
694GLSubpath.prototype.getStrokeMaterial = function () { 792GLSubpath.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();