aboutsummaryrefslogtreecommitdiff
path: root/js/lib/geom/brush-stroke.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/lib/geom/brush-stroke.js')
-rwxr-xr-xjs/lib/geom/brush-stroke.js482
1 files changed, 482 insertions, 0 deletions
diff --git a/js/lib/geom/brush-stroke.js b/js/lib/geom/brush-stroke.js
new file mode 100755
index 00000000..9a934928
--- /dev/null
+++ b/js/lib/geom/brush-stroke.js
@@ -0,0 +1,482 @@
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
7// Todo: This entire class should be converted to a module
8var VecUtils = require("js/helper-classes/3D/vec-utils").VecUtils;
9var GeomObj = require("js/lib/geom/geom-obj").GeomObj;
10
11///////////////////////////////////////////////////////////////////////
12// Class GLBrushStroke
13// representation a sequence points (polyline) created by brush tool.
14// Derived from class GLGeomObj
15///////////////////////////////////////////////////////////////////////
16var BrushStroke = function GLBrushStroke() {
17 ///////////////////////////////////////////////////
18 // Instance variables
19 ///////////////////////////////////////////////////
20 this._Points = [];
21 this._BBoxMin = [0, 0, 0];
22 this._BBoxMax = [0, 0, 0];
23 this._dirty = true;
24
25 //whether or not to use the canvas drawing to stroke/fill
26 this._useCanvasDrawing = true;
27
28 //the X and Y location of this subpath's canvas in stage world space of Ninja
29 this._canvasX = 0;
30 this._canvasY = 0;
31
32 //stroke information
33 this._strokeWidth = 0.0;
34 this._strokeColor = [0.4, 0.4, 0.4, 1.0];
35 this._strokeMaterial = null;
36 this._strokeStyle = "Solid";
37
38 //the wetness of the brush (currently this is multiplied to the square of the stroke width, but todo should be changed to not depend on stroke width entirely
39 //smaller value means more samples for the path
40 this._WETNESS_FACTOR = 0.25;
41
42 //prevent extremely long paths that can take a long time to render
43 this._MAX_ALLOWED_SAMPLES = 500;
44
45 //drawing context
46 this._world = null;
47
48 //tool that owns this brushstroke
49 this._drawingTool = null;
50 this._planeMat = null;
51 this._planeMatInv = null;
52 this._planeCenter = null;
53
54 /////////////////////////////////////////////////////////
55 // Property Accessors/Setters
56 /////////////////////////////////////////////////////////
57 this.setWorld = function (world) {
58 this._world = world;
59 };
60
61 this.getWorld = function () {
62 return this._world;
63 };
64
65 this.geomType = function () {
66 return this.GEOM_TYPE_CUBIC_BEZIER;
67 };
68
69 this.setDrawingTool = function (tool) {
70 this._drawingTool = tool;
71 };
72
73 this.getDrawingTool = function () {
74 return this._drawingTool;
75 };
76
77 this.setPlaneMatrix = function(planeMat){
78 this._planeMat = planeMat;
79 };
80
81 this.setPlaneMatrixInverse = function(planeMatInv){
82 this._planeMatInv = planeMatInv;
83 };
84
85 this.setPlaneCenter = function(pc){
86 this._planeCenter = pc;
87 };
88
89 this.getCanvasX = function(){
90 return this._canvasX;
91 };
92
93 this.getCanvasY = function(){
94 return this._canvasY;
95 };
96
97 this.setCanvasX = function(cx){
98 this._canvasX=cx;
99 };
100
101 this.setCanvasY = function(cy){
102 this._canvasY=cy;
103 };
104
105 this.getNumPoints = function () {
106 return this._Points.length;
107 };
108
109 this.getPoint = function (index) {
110 return this._Points[index];
111 };
112
113 this.addPoint = function (pt) {
114 //add the point only if it is some epsilon away from the previous point
115 var numPoints = this._Points.length;
116 if (numPoints>0) {
117 var threshold = this._WETNESS_FACTOR*this._strokeWidth;
118 var prevPt = this._Points[numPoints-1];
119 var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]];
120 var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]);
121 if (diffPtMag>threshold){
122 this._Points.push(pt);
123 this._dirty=true;
124 }
125 } else {
126 this._Points.push(pt);
127 this._dirty=true;
128 }
129 };
130
131 this.insertPoint = function(pt, index){
132 this._Points.splice(index, 0, pt); this._dirty=true;
133 };
134
135 this.isDirty = function(){
136 return this._dirty;
137 };
138
139 this.makeDirty = function(){
140 this._dirty=true;
141 };
142
143 this.getBBoxMin = function () {
144 return this._BBoxMin;
145 };
146
147 this.getBBoxMax = function () {
148 return this._BBoxMax;
149 };
150
151 this.getStrokeWidth = function () {
152 return this._strokeWidth;
153 };
154
155 this.setStrokeWidth = function (w) {
156 this._strokeWidth = w;
157 this._dirty=true;
158 };
159
160 this.getStrokeMaterial = function () {
161 return this._strokeMaterial;
162 };
163
164 this.setStrokeMaterial = function (m) {
165 this._strokeMaterial = m;
166 };
167
168 this.getStrokeColor = function () {
169 return this._strokeColor;
170 };
171
172 this.setStrokeColor = function (c) {
173 this._strokeColor = c;
174 };
175
176 this.getStrokeStyle = function () {
177 return this._strokeStyle;
178 };
179
180 this.setStrokeStyle = function (s) {
181 this._strokeStyle = s;
182 };
183
184 this.setWidth = function () {
185
186 };//NO-OP for now
187
188 this.setHeight = function () {
189
190 };//NO-OP for now
191
192
193 //remove and return anchor at specified index, return null on error
194 this.removePoint = function (index) {
195 var retAnchor = null;
196 if (index < this._Points.length) {
197 retPt = this._Points.splice(index, 1);
198 this._dirty=true;
199 }
200 return retPoint;
201 };
202
203 //remove all the points
204 this.clear = function () {
205 this._Points = [];
206 this._dirty=true;
207 }
208
209 this.translate = function (tx, ty, tz) {
210 for (var i=0;i<this._Points.length;i++){
211 this._Points[i][0]+=tx;
212 this._Points[i][1]+=ty;
213 this._Points[i][2]+=tz;
214 }
215 };
216
217 this.computeMetaGeometry = function() {
218 if (this._dirty) {
219 var numPoints = this._Points.length;
220
221 //**** add samples to the path if needed...linear interpolation for now
222 if (numPoints>1) {
223 var threshold = this._WETNESS_FACTOR*this._strokeWidth;
224 var prevPt = this._Points[0];
225 var prevIndex = 0;
226 for (var i=1;i<numPoints;i++){
227 var pt = this._Points[i];
228 var diff = [pt[0]-prevPt[0], pt[1]-prevPt[1]];
229 var distance = Math.sqrt(diff[0]*diff[0]+diff[1]*diff[1]);
230 if (distance>threshold){
231 //insert points along the prev. to current point
232 var numNewPoints = Math.floor(distance/threshold);
233 for (var j=0;j<numNewPoints;j++){
234 var param = (j+1)/(numNewPoints+1);
235 var newpt = [prevPt[0]+ diff[0]*param, prevPt[1]+ diff[1]*param];
236 //insert new point before point i
237 this._Points.splice(i, 0, [newpt[0], newpt[1], 0]);
238 i++;
239 }
240 this._dirty=true;
241 }
242 prevPt=pt;
243 //update numPoints to match the new length
244 numPoints = this._Points.length;
245
246 //end this function if the numPoints has gone above the max. size specified
247 if (numPoints> this._MAX_ALLOWED_SAMPLES){
248 console.log("leaving the resampling because numPoints is greater than limit:"+this._MAX_ALLOW