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.js830
1 files changed, 284 insertions, 546 deletions
diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js
index 7046673e..7e11bb33 100755
--- a/js/lib/geom/sub-path.js
+++ b/js/lib/geom/sub-path.js
@@ -11,29 +11,6 @@ var 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;
13 13
14// TODO Those function do not seems to be used. We should remove them
15function SubpathOffsetPoint(pos, mapPos) {
16 this.Pos = [pos[0],pos[1],pos[2]];
17 this.CurveMapPos = [mapPos[0], mapPos[1], mapPos[2]];
18}
19
20function SubpathOffsetTriangle(v0, v1, v2) {
21 this.v0 = v0;
22 this.v1 = v1;
23 this.v2 = v2;
24 this.n = [0,0,1]; //replace with the actual cross product later
25}
26
27function sortNumberAscending(a,b){
28 return a-b;
29}
30function sortNumberDescending(a,b){
31 return b-a;
32}
33function SegmentIntersections(){
34 this.paramArray = [];
35}
36
37/////////////////////////////////////////////////////////////////////// 14///////////////////////////////////////////////////////////////////////
38// Class GLSubpath 15// Class GLSubpath
39// representation a sequence of cubic bezier curves. 16// representation a sequence of cubic bezier curves.
@@ -44,49 +21,40 @@ var GLSubpath = function GLSubpath() {
44 /////////////////////////////////////////////////// 21 ///////////////////////////////////////////////////
45 // Instance variables 22 // Instance variables
46 /////////////////////////////////////////////////// 23 ///////////////////////////////////////////////////
24
25 // NOTE:
26 // This class contains functionality to store piecewise cubic bezier paths.
27 // The coordinates of the paths are always in local, canvas space.
28 // That is, the Z coordinate can be ignored (for now), and the paths are essentially in 2D.
29 // All coordinates of the '_Samples' should lie within [0,0] and [width, height],
30 // where width and height refer to the dimensions of the canvas for this path.
31 // Whenever the the canvas dimensions change, the coordinates of the anchor points
32 // and _Samples must be re-computed.
33
47 this._Anchors = []; 34 this._Anchors = [];
48 this._BBoxMin = [0, 0, 0]; 35 this._BBoxMin = [0, 0, 0];
49 this._BBoxMax = [0, 0, 0]; 36 this._BBoxMax = [0, 0, 0];
50 this._isClosed = false; 37 this._isClosed = false;
51 38
52 this._samples = []; //polyline representation of this curve 39 this._Samples = []; //polyline representation of this curve in canvas space
53 this._sampleParam = []; //parametric distance of samples, within [0, N], where N is # of Bezier curves (=# of anchor points if closed, =#anchor pts -1 if open) 40 this._sampleParam = []; //parametric distance of samples, within [0, N], where N is # of Bezier curves (=# of anchor points if closed, =#anchor pts -1 if open)
54 this._anchorSampleIndex = []; //index within _samples corresponding to anchor points 41 this._anchorSampleIndex = []; //index within _Samples corresponding to anchor points
55
56 this._UnprojectedAnchors = [];
57 42
58 //initially set the _dirty bit so we will construct samples 43 //initially set the _dirty bit so we will re-construct _Anchors and _Samples
59 this._dirty = true; 44 this._dirty = true;
60 45
61 //whether or not to use the canvas drawing to stroke/fill
62 this._useCanvasDrawing = true;
63
64 //the canvas that will draw this subpath
65 this._canvas = null;
66
67 //the X and Y location of this subpath's canvas in stage world space of Ninja
68 this._canvasX = 0;
69 this._canvasY = 0;
70
71 //stroke information 46 //stroke information
72 this._strokeWidth = 0.0; 47 this._strokeWidth = 1.0;
73 this._strokeColor = [0.4, 0.4, 0.4, 1.0]; 48 this._strokeColor = [0.4, 0.4, 0.4, 1.0];
74 this._strokeMaterial = null
75 this._strokeStyle = "Solid";
76 this._materialAmbient = [0.2, 0.2, 0.2, 1.0];
77 this._materialDiffuse = [0.4, 0.4, 0.4, 1.0];
78 this._materialSpecular = [0.4, 0.4, 0.4, 1.0];
79 this._fillColor = [1.0, 1.0, 1.0, 0.0]; 49 this._fillColor = [1.0, 1.0, 1.0, 0.0];
80 this._fillMaterial = null;
81 this._DISPLAY_ANCHOR_RADIUS = 5; 50 this._DISPLAY_ANCHOR_RADIUS = 5;
51
82 //drawing context 52 //drawing context
83 this._world = null; 53 this._world = null;
54 this._canvas = null; //todo this might be unnecessary (but faster) since we can get it from the world
84 55
85 //tool that owns this subpath 56 //tool that owns this subpath
86 this._drawingTool = null; 57 this._drawingTool = null;
87 this._planeMat = null;
88 this._planeMatInv = null;
89 this._planeCenter = null;
90 58
91 //used to query what the user selected, OR-able for future extensions 59 //used to query what the user selected, OR-able for future extensions
92 this.SEL_NONE = 0; //nothing was selected 60 this.SEL_NONE = 0; //nothing was selected
@@ -98,8 +66,6 @@ var GLSubpath = function GLSubpath() {
98 this._selectedAnchorIndex = -1; 66 this._selectedAnchorIndex = -1;
99 67
100 this._SAMPLING_EPSILON = 0.5; //epsilon used for sampling the curve 68 this._SAMPLING_EPSILON = 0.5; //epsilon used for sampling the curve
101 this._DEFAULT_STROKE_WIDTH = 20; //use only if stroke width not specified
102 this._MAX_OFFSET_ANGLE = 10; //max angle (in degrees) between consecutive vectors from curve to offset path
103 69
104 // (current GeomObj complains if buildBuffers/render is added to GLSubpath prototype) 70 // (current GeomObj complains if buildBuffers/render is added to GLSubpath prototype)
105 //buildBuffers 71 //buildBuffers
@@ -115,36 +81,34 @@ var GLSubpath = function GLSubpath() {
115 // get the world 81 // get the world
116 var world = this.getWorld(); 82 var world = this.getWorld();
117 if (!world) throw( "null world in subpath render" ); 83 if (!world) throw( "null world in subpath render" );
118 84 if (!this._canvas){
119 // get the context 85 //set the canvas by querying the world
86 this._canvas = this.getWorld().getCanvas();
87 }
88 // get the context
120 var ctx = world.get2DContext(); 89 var ctx = world.get2DContext();
121 if (!ctx) throw ("null context in subpath render") 90 if (!ctx) throw ("null context in subpath render");
122 91
123 var numAnchors = this.getNumAnchors(); 92 var numAnchors = this.getNumAnchors();
124 if (numAnchors === 0) { 93 if (numAnchors === 0) {
125 return; //nothing to do for empty paths 94 return; //nothing to do for empty paths
126 } 95 }
96 this.createSamples(false); //dirty bit checked in this function...will generate a polyline representation
127 97
128 ctx.save(); 98 //figure the size of the area we will draw into
99 var bboxWidth=0, bboxHeight=0;
100 bboxWidth = this._BBoxMax[0] - this._BBoxMin[0];
101 bboxHeight = this._BBoxMax[1] - this._BBoxMin[1];
129 102
130 this.createSamples(); //dirty bit checked in this function...will generate a polyline representation 103 ctx.save();
131 var bboxMin = this.getBBoxMin();
132 var bboxMax = this.getBBoxMax();
133 var bboxWidth = bboxMax[0] - bboxMin[0];
134 var bboxHeight = bboxMax[1] - bboxMin[1];
135 var bboxMid = [0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])];
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 }
142 ctx.clearRect(0, 0, bboxWidth, bboxHeight); 104 ctx.clearRect(0, 0, bboxWidth, bboxHeight);
143 105
144 ctx.lineWidth = this._strokeWidth; 106 ctx.lineWidth = this._strokeWidth;
145 ctx.strokeStyle = "black"; 107 ctx.strokeStyle = "black";
146 if (this._strokeColor) { 108 if (this._strokeColor) {
147 ctx.strokeStyle = MathUtils.colorToHex( this._strokeColor ); 109 //ctx.strokeStyle = MathUtils.colorToHex( this._strokeColor );
110 var strokeColorStr = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+","+this._strokeColor[3]+")";
111 ctx.strokeStyle = strokeColorStr;
148 } 112 }
149 113
150 ctx.fillStyle = "white"; 114 ctx.fillStyle = "white";
@@ -152,14 +116,15 @@ var GLSubpath = function GLSubpath() {
152 //ctx.fillStyle = MathUtils.colorToHex( this._fillColor ); 116 //ctx.fillStyle = MathUtils.colorToHex( this._fillColor );
153 var fillColorStr = "rgba("+parseInt(255*this._fillColor[0])+","+parseInt(255*this._fillColor[1])+","+parseInt(255*this._fillColor[2])+","+this._fillColor[3]+")"; 117 var fillColorStr = "rgba("+parseInt(255*this._fillColor[0])+","+parseInt(255*this._fillColor[1])+","+parseInt(255*this._fillColor[2])+","+this._fillColor[3]+")";
154 ctx.fillStyle = fillColorStr; 118 ctx.fillStyle = fillColorStr;
155 console.log("Fill color:" + fillColorStr);
156 } 119 }
157 var lineCap = ['butt','round','square']; 120 var lineCap = ['butt','round','square'];
158 ctx.lineCap = lineCap[1]; 121 ctx.lineCap = lineCap[1];
159 ctx.beginPath(); 122 var lineJoin = ['round','bevel','miter'];
123 ctx.lineJoin = lineJoin[0];
160 124
161 /* 125 /*
162 commenting this out for now because of Chrome bug where coincident endpoints of bezier curve cause the curve to not be rendered 126 commenting this out for now because of Chrome bug where coincident endpoints of bezier curve cause the curve to not be rendered
127 ctx.beginPath();
163 var prevAnchor = this.getAnchor(0); 128 var prevAnchor = this.getAnchor(0);
164 ctx.moveTo(prevAnchor.getPosX()-bboxMin[0],prevAnchor.getPosY()-bboxMin[1]); 129 ctx.moveTo(prevAnchor.getPosX()-bboxMin[0],prevAnchor.getPosY()-bboxMin[1]);
165 for (var i = 1; i < numAnchors; i++) { 130 for (var i = 1; i < numAnchors; i++) {
@@ -176,13 +141,14 @@ var GLSubpath = function GLSubpath() {
176 */ 141 */
177 142
178 143
179 var numPoints = this._samples.length/3; 144 ctx.beginPath();
180 ctx.moveTo(this._samples[0]-bboxMin[0],this._samples[1]-bboxMin[1]); 145 var numPoints = this._Samples.length;
146 ctx.moveTo(this._Samples[0][0],this._Samples[0][1]);
181 for (var i=0;i<numPoints;i++){ 147 for (var i=0;i<numPoints;i++){
182 ctx.lineTo(this._samples[3*i]-bboxMin[0],this._samples[3*i + 1]-bboxMin[1]); 148 ctx.lineTo(this._Samples[i][0],this._Samples[i][1]);
183 } 149 }
184 if (this._isClosed === true) { 150 if (this._isClosed === true) {
185 ctx.lineTo(this._samples[0]-bboxMin[0],this._samples[1]-bboxMin[1]); 151 ctx.lineTo(this._Samples[0][0],this._Samples[0][1]);
186 } 152 }
187 ctx.fill(); 153 ctx.fill();
188 ctx.stroke(); 154 ctx.stroke();
@@ -265,18 +231,21 @@ GLSubpath.prototype = new GeomObj();
265///////////////////////////////////////////////////////// 231/////////////////////////////////////////////////////////
266// Property Accessors/Setters 232// Property Accessors/Setters
267///////////////////////////////////////////////////////// 233/////////////////////////////////////////////////////////
268GLSubpath.prototype.setCanvas = function (c) {
269 this._canvas = c;
270};
271
272GLSubpath.prototype.setWorld = function (world) { 234GLSubpath.prototype.setWorld = function (world) {