aboutsummaryrefslogtreecommitdiff
path: root/js/helper-classes/RDGE/GLSubpath.js
diff options
context:
space:
mode:
authorPierre Frisch2011-12-22 07:25:50 -0800
committerValerio Virgillito2012-01-27 11:18:17 -0800
commitb89a7ee8b956c96a1dcee995ea840feddc5d4b27 (patch)
tree0f3136ab0ecdbbbed6a83576581af0a53124d6f1 /js/helper-classes/RDGE/GLSubpath.js
parent2401f05d1f4b94d45e4568b81fc73e67b969d980 (diff)
downloadninja-b89a7ee8b956c96a1dcee995ea840feddc5d4b27.tar.gz
First commit of Ninja to ninja-internal
Signed-off-by: Valerio Virgillito <rmwh84@motorola.com>
Diffstat (limited to 'js/helper-classes/RDGE/GLSubpath.js')
-rw-r--r--js/helper-classes/RDGE/GLSubpath.js1671
1 files changed, 1671 insertions, 0 deletions
diff --git a/js/helper-classes/RDGE/GLSubpath.js b/js/helper-classes/RDGE/GLSubpath.js
new file mode 100644
index 00000000..25b12093
--- /dev/null
+++ b/js/helper-classes/RDGE/GLSubpath.js
@@ -0,0 +1,1671 @@
1/* <copyright>
2This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5</copyright> */
6
7var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils;
8
9
10function SubpathOffsetPoint(pos, mapPos) {
11 this.Pos = Vector.create([pos[0],pos[1],pos[2]]);
12 this.CurveMapPos = Vector.create([mapPos[0], mapPos[1], mapPos[2]]);
13}
14
15function SubpathOffsetTriangle(v0, v1, v2) {
16 this.v0 = v0;
17 this.v1 = v1;
18 this.v2 = v2;
19 this.n = Vector.create([0,0,1]); //replace with the actual cross product later
20}
21
22function sortNumberAscending(a,b){
23 return a-b;
24}
25function sortNumberDescending(a,b){
26 return b-a;
27}
28function SegmentIntersections(){
29 this.paramArray = [];
30}
31
32///////////////////////////////////////////////////////////////////////
33// Class GLSubpath
34// representation a sequence of cubic bezier curves.
35// Derived from class GLGeomObj
36///////////////////////////////////////////////////////////////////////
37function GLSubpath() {
38 ///////////////////////////////////////////////////
39 // Instance variables
40 ///////////////////////////////////////////////////
41 this._Anchors = [];
42 this._BBoxMin = [0, 0, 0];
43 this._BBoxMax = [0, 0, 0];
44 this._isClosed = false;
45
46 this._samples = []; //polyline representation of this curve
47 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)
48 this._anchorSampleIndex = []; //index within _samples corresponding to anchor points
49
50 this._UnprojectedAnchors = [];
51
52 //offset path samples and the points on the input path they map to
53 this._offsetPointsLeft = [];
54 this._offsetPointsRight = [];
55
56 //triangles determined by the offset points
57 this._offsetTrianglesLeft = [];
58 this._offsetTrianglesRight = [];
59
60 //initially set the _dirty bit so we will construct samples
61 this._dirty = true;
62
63 //whether or not to use the canvas drawing to stroke/fill
64 this._useCanvasDrawing = true;
65
66 //the X and Y location of this subpath's canvas in stage world space of Ninja
67 this._canvasX = 0;
68 this._canvasY = 0;
69
70 //stroke information
71 this._strokeWidth = 0.0;
72 this._strokeColor = [0.4, 0.4, 0.4, 1.0];
73 this._strokeMaterial;
74 this._strokeStyle = "Solid";
75 this._materialAmbient = [0.2, 0.2, 0.2, 1.0];
76 this._materialDiffuse = [0.4, 0.4, 0.4, 1.0];
77 this._materialSpecular = [0.4, 0.4, 0.4, 1.0];
78 this._fillColor = [0.4, 0.4, 0.4, 1.0];
79 this._fillMaterial;
80 this._DISPLAY_ANCHOR_RADIUS = 5;
81 //drawing context
82 this._world = null;
83
84 //tool that owns this subpath
85 this._drawingTool = null;
86 this._planeMat = null;
87 this._planeMatInv = null;
88 this._planeCenter = null;
89
90 // initialize the inherited members
91 this.inheritedFrom = GLGeomObj;
92 this.inheritedFrom();
93
94 //used to query what the user selected, OR-able for future extensions
95 this.SEL_NONE = 0; //nothing was selected
96 this.SEL_ANCHOR = 1; //anchor point was selected
97 this.SEL_PREV = 2; //previous handle of anchor point was selected
98 this.SEL_NEXT = 4; //next handle of anchor point was selected
99 this.SEL_PATH = 8; //the path itself was selected
100 this._selectMode = this.SEL_NONE;
101 this._selectedAnchorIndex = -1;
102
103 this._SAMPLING_EPSILON = 0.5; //epsilon used for sampling the curve
104 this._DEFAULT_STROKE_WIDTH = 20; //use only if stroke width not specified
105 this._MAX_OFFSET_ANGLE = 10; //max angle (in degrees) between consecutive vectors from curve to offset path
106
107 /////////////////////////////////////////////////////////
108 // Property Accessors/Setters
109 /////////////////////////////////////////////////////////
110 this.setWorld = function (world) { this._world = world; }
111 this.getWorld = function () { return this._world; }
112 this.makeDirty = function () {this._dirty = true;}
113 this.geomType = function () { return this.GEOM_TYPE_CUBIC_BEZIER; }
114 this.setDrawingTool = function (tool) {this._drawingTool = tool;}
115 this.getDrawingTool = function () {return this._drawingTool;}
116 this.setPlaneMatrix = function(planeMat){this._planeMat = planeMat;}
117 this.setPlaneMatrixInverse = function(planeMatInv){this._planeMatInv = planeMatInv;}
118 this.setPlaneCenter = function(pc){this._planeCenter = pc;}
119
120 this.getCanvasX = function(){return this._canvasX;}
121 this.getCanvasY = function(){return this._canvasY;}
122 this.setCanvasX = function(cx){this._canvasX=cx;}
123 this.setCanvasY = function(cy){this._canvasY=cy;}
124
125 this.getIsClosed = function () {return this._isClosed;}
126 this.setIsClosed = function (isClosed) {
127 if (this._isClosed !== isClosed) {
128 this._isClosed = isClosed;
129 this._dirty = true;
130 }
131 }
132 this.getNumAnchors = function () { return this._Anchors.length; }
133 this.getAnchor = function (index) { return this._Anchors[index]; }
134 this.addAnchor = function (anchorPt) {
135 this._Anchors.push(anchorPt);
136 this._selectedAnchorIndex = this._Anchors.length-1;
137 this._dirty = true;
138 }
139
140 this.insertAnchor = function(anchorPt, index){
141 this._Anchors.splice(index, 0, anchorPt);
142 }
143
144 //remove and return anchor at specified index, return null on error
145 this.removeAnchor = function (index) {
146 var retAnchor = null;
147 if (index < this._Anchors.length) {
148 retAnchor = this._Anchors.splice(index, 1);
149 this._dirty = true;
150 }
151 //deselect the removed anchor if necessary
152 if (this._selectedAnchorIndex === index){
153 this._selectedAnchorIndex = -1;
154 }
155 return retAnchor;
156 }
157
158 //remove all the anchor points
159 this.clearAllAnchors = function () {
160 this._Anchors = [];
161 this._isClosed = false;
162 this._dirty = true;
163 }
164
165 this.insertAnchorAtParameter = function(index, param) {
166 if (index+1 >= this._Anchors.length && !this._isClosed) {
167 return;
168 }
169 //insert an anchor after the specified index using the parameter, using De Casteljau subdivision
170 var nextIndex = (index+1)%this._Anchors.length;
171
172 //build the De Casteljau points
173 var P0P1 = VecUtils.vecInterpolate(3, this._Anchors[index].getPos(), this._Anchors[index].getNext(), param);
174 var P1P2 = VecUtils.vecInterpolate(3, this._Anchors[index].getNext(), this._Anchors[nextIndex].getPrev(), param);
175 var P2P3 = VecUtils.vecInterpolate(3, this._Anchors[nextIndex].getPrev(), this._Anchors[nextIndex].getPos(), param);
176
177 var P0P1P2 = VecUtils.vecInterpolate(3, P0P1, P1P2, param);
178 var P1P2P3 = VecUtils.vecInterpolate(3, P1P2, P2P3, param);
179 var anchorPos = VecUtils.vecInterpolate(3, P0P1P2, P1P2P3, param);
180
181
182 //update the next of the anchor at index and prev of anchor at nextIndex
183 var isPrevCoincident = false;
184 var isNextCoincident = false;
185 if (VecUtils.vecDist( 3, P0P1, this._Anchors[index].getNext()) < this._SAMPLING_EPSILON) {
186 //no change to the next point
187 isPrevCoincident = true;
188 } else {
189 this._Anchors[index].setNextPos(P0P1[0], P0P1[1], P0P1[2]);
190 }
191
192 if (VecUtils.vecDist( 3, P2P3, this._Anchors[nextIndex].getPrev()) < this._SAMPLING_EPSILON) {
193 //no change to the prev point
194 isNextCoincident = true;
195 } else {
196 this._Anchors[nextIndex].setPrevPos(P2P3[0], P2P3[1], P2P3[2]);
197 }
198
199 //create a new anchor point
200 var newAnchor = new GLAnchorPoint();
201
202 if (isPrevCoincident && isNextCoincident){
203 anchorPos[0]=P1P2[0];anchorPos[1]=P1P2[1];anchorPos[2]=P1P2[2];
204 newAnchor.setPos(anchorPos[0],anchorPos[1],anchorPos[2]);
205 newAnchor.setPrevPos(anchorPos[0],anchorPos[1],anchorPos[2]);
206 newAnchor.setNextPos(anchorPos[0],anchorPos[1],anchorPos[2]);
207 } else {
208 newAnchor.setPrevPos(P0P1P2[0], P0P1P2[1], P0P1P2[2]);
209 newAnchor.setNextPos(P1P2P3[0], P1P2P3[1], P1P2P3[2]);
210 newAnchor.setPos(anchorPos[0], anchorPos[1], anchorPos[2]);
211 }
212
213 //insert the new anchor point at the correct index and set it as the selected anchor
214 this._Anchors.splice(nextIndex, 0, newAnchor);
215 this._selectedAnchorIndex = nextIndex;
216 this._dirty = true;
217 }
218
219 this._checkIntersectionWithSamples = function(startIndex, endIndex, point, radius){
220 //check whether the point is within the radius distance from the curve represented as a polyline in _samples
221 //return the parametric distance along the curve if there is an intersection, else return null
222 //will assume that the BBox test is performed outside this function
223
224 for (var i=startIndex; i<endIndex; i++){
225