1 /**
2 * @author zz85 / http://www.lab4games.net/zz85/blog
3 * Defines a 2d shape plane using paths.
4 **/
5
6 // STEP 1 Create a path.
7 // STEP 2 Turn path into shape.
8 // STEP 3 ExtrudeGeometry takes in Shape/Shapes
9 // STEP 3a - Extract points from each shape, turn to vertices
10 // STEP 3b - Triangulate each shape, add faces.
11
12 /**@constructor*/
13 THREE.Shape = function ( ) {
14
15 THREE.Path.apply( this, arguments );
16 this.holes = [];
17
18 };
19
20 THREE.Shape.prototype = Object.create( THREE.Path.prototype );
21
22 // Convenience method to return ExtrudeGeometry
23
24 THREE.Shape.prototype.extrude = function ( options ) {
25
26 var extruded = new THREE.ExtrudeGeometry( this, options );
27 return extruded;
28
29 };
30
31 // Convenience method to return ShapeGeometry
32
33 THREE.Shape.prototype.makeGeometry = function ( options ) {
34
35 var geometry = new THREE.ShapeGeometry( this, options );
36 return geometry;
37
38 };
39
40 // Get points of holes
41
42 THREE.Shape.prototype.getPointsHoles = function ( divisions ) {
43
44 var i, il = this.holes.length, holesPts = [];
45
46 for ( i = 0; i < il; i ++ ) {
47
48 holesPts[ i ] = this.holes[ i ].getTransformedPoints( divisions, this.bends );
49
50 }
51
52 return holesPts;
53
54 };
55
56 // Get points of holes (spaced by regular distance)
57
58 THREE.Shape.prototype.getSpacedPointsHoles = function ( divisions ) {
59
60 var i, il = this.holes.length, holesPts = [];
61
62 for ( i = 0; i < il; i ++ ) {
63
64 holesPts[ i ] = this.holes[ i ].getTransformedSpacedPoints( divisions, this.bends );
65
66 }
67
68 return holesPts;
69
70 };
71
72
73 // Get points of shape and holes (keypoints based on segments parameter)
74
75 THREE.Shape.prototype.extractAllPoints = function ( divisions ) {
76
77 return {
78
79 shape: this.getTransformedPoints( divisions ),
80 holes: this.getPointsHoles( divisions )
81
82 };
83
84 };
85
86 THREE.Shape.prototype.extractPoints = function ( divisions ) {
87
88 if (this.useSpacedPoints) {
89 return this.extractAllSpacedPoints(divisions);
90 }
91
92 return this.extractAllPoints(divisions);
93
94 };
95
96 //
97 // THREE.Shape.prototype.extractAllPointsWithBend = function ( divisions, bend ) {
98 //
99 // return {
100 //
101 // shape: this.transform( bend, divisions ),
102 // holes: this.getPointsHoles( divisions, bend )
103 //
104 // };
105 //
106 // };
107
108 // Get points of shape and holes (spaced by regular distance)
109
110 THREE.Shape.prototype.extractAllSpacedPoints = function ( divisions ) {
111
112 return {
113
114 shape: this.getTransformedSpacedPoints( divisions ),
115 holes: this.getSpacedPointsHoles( divisions )
116
117 };
118
119 };
120
121 /**************************************************************
122 * Utils
123 **************************************************************/
124
125 THREE.Shape.Utils = {
126
127 /*
128 contour - array of vector2 for contour
129 holes - array of array of vector2
130 */
131
132 removeHoles: function ( contour, holes ) {
133
134 var shape = contour.concat(); // work on this shape
135 var allpoints = shape.concat();
136
137 /* For each isolated shape, find the closest points and break to the hole to allow triangulation */
138
139
140 var prevShapeVert, nextShapeVert,
141 prevHoleVert, nextHoleVert,
142 holeIndex, shapeIndex,
143 shapeId, shapeGroup,
144 h, h2,
145 hole, shortest, d,
146 p, pts1, pts2,
147 tmpShape1, tmpShape2,
148 tmpHole1, tmpHole2,
149 verts = [];
150
151 for ( h = 0; h < holes.length; h ++ ) {
152
153 hole = holes[ h ];
154
155 /*
156 shapeholes[ h ].concat(); // preserves original
157 holes.push( hole );
158 */
159
160 Array.prototype.push.apply( allpoints, hole );
161
162 shortest = Number.POSITIVE_INFINITY;
163
164
165 // Find the shortest pair of pts between shape and hole
166
167 // Note: Actually, I'm not sure now if we could optimize this to be faster than O(m*n)
168 // Using distanceToSquared() intead of distanceTo() should speed a little
169 // since running square roots operations are reduced.
170
171 for ( h2 = 0; h2 < hole.length; h2 ++ ) {
172
173 pts1 = hole[ h2 ];
174 var dist = [];
175
176 for ( p = 0; p < shape.length; p++ ) {
177
178 pts2 = shape[ p ];
179 d = pts1.distanceToSquared( pts2 );
180 dist.push( d );
181
182 if ( d < shortest ) {
183
184 shortest = d;
185 holeIndex = h2;
186 shapeIndex = p;
187
188 }
189
190 }
191
192 }
193
194 //console.log("shortest", shortest, dist);
195
196 prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
197 prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
198
199 var areaapts = [
200
201 hole[ holeIndex ],
202 shape[ shapeIndex ],
203 shape[ prevShapeVert ]
204
205 ];
206
207 var areaa = THREE.FontUtils.Triangulate.area( areaapts );
208
209 var areabpts = [
210
211 hole[ holeIndex ],
212 hole[ prevHoleVert ],
213 shape[ shapeIndex ]
214
215 ];
216
217 var areab = THREE.FontUtils.Triangulate.area( areabpts );
218
219 var shapeOffset = 1;
220 var holeOffset = -1;
221
222 var oldShapeIndex = shapeIndex, oldHoleIndex = holeIndex;
223 shapeIndex += shapeOffset;
224 holeIndex += holeOffset;
225
226 if ( shapeIndex < 0 ) { shapeIndex += shape.length; }
227 shapeIndex %= shape.length;
228
229 if ( holeIndex < 0 ) { holeIndex += hole.length; }
230 holeIndex %= hole.length;
231
232 prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
233 prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
234
235 areaapts = [
236
237 hole[ holeIndex ],
238 shape[ shapeIndex ],
239 shape[ prevShapeVert ]
240
241 ];
242
243 var areaa2 = THREE.FontUtils.Triangulate.area( areaapts );
244
245 areabpts = [
246
247 hole[ holeIndex ],
248 hole[ prevHoleVert ],
249 shape[ shapeIndex ]
250
251 ];
252
253 var areab2 = THREE.FontUtils.Triangulate.area( areabpts );
254 //console.log(areaa,areab ,areaa2,areab2, ( areaa + areab ), ( areaa2 + areab2 ));
255
256 if ( ( areaa + areab ) > ( areaa2 + areab2 ) ) {
257
258 // In case areas are not correct.
259 //console.log("USE THIS");
260
261 shapeIndex = oldShapeIndex;
262 holeIndex = oldHoleIndex ;
263
264 if ( shapeIndex < 0 ) { shapeIndex += shape.length; }
265 shapeIndex %= shape.length;
266
267 if ( holeIndex < 0 ) { holeIndex += hole.length; }
268 holeIndex %= hole.length;
269
270 prevShapeVert = ( shapeIndex - 1 ) >= 0 ? shapeIndex - 1 : shape.length - 1;
271 prevHoleVert = ( holeIndex - 1 ) >= 0 ? holeIndex - 1 : hole.length - 1;
272
273 } else {
274
275 //console.log("USE THAT ")
276
277 }
278
279 tmpShape1 = shape.slice( 0, shapeIndex );
280 tmpShape2 = shape.slice( shapeIndex );
281 tmpHole1 = hole.slice( holeIndex );
282 tmpHole2 = hole.slice( 0, holeIndex );
283
284 // Should check orders here again?
285
286 var trianglea = [
287
288 hole[ holeIndex ],
289 shape[ shapeIndex ],
290 shape[ prevShapeVert ]
291
292 ];
293
294 var triangleb = [
295
296 hole[ holeIndex ] ,
297 hole[ prevHoleVert ],
298 shape[ shapeIndex ]
299
300 ];
301
302 verts.push( trianglea );
303 verts.push( triangleb );
304
305 shape = tmpShape1.concat( tmpHole1 ).concat( tmpHole2 ).concat( tmpShape2 );
306
307 }
308
309 return {
310
311 shape:shape, /* shape with no holes */
312 isolatedPts: verts, /* isolated faces */
313 allpoints: allpoints
314
315 }
316
317
318 },
319
320 triangulateShape: function ( contour, holes ) {
321
322 var shapeWithoutHoles = THREE.Shape.Utils.removeHoles( contour, holes );
323
324 var shape = shapeWithoutHoles.shape,
325 allpoints = shapeWithoutHoles.allpoints,
326 isolatedPts = shapeWithoutHoles.isolatedPts;
327
328 var triangles = THREE.FontUtils.Triangulate( shape, false ); // True returns indices for points of spooled shape
329
330 // To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first.
331
332 //console.log( "triangles",triangles, triangles.length );
333 //console.log( "allpoints",allpoints, allpoints.length );
334
335 var i, il, f, face,
336 key, index,
337 allPointsMap = {},
338 isolatedPointsMap = {};
339
340 // prepare all points map
341
342 for ( i = 0, il = allpoints.length; i < il; i ++ ) {
343
344 key = allpoints[ i ].x + ":" + allpoints[ i ].y;
345
346 if ( allPointsMap[ key ] !== undefined ) {
347
348 console.log( "Duplicate point", key );
349
350 }
351
352 allPointsMap[ key ] = i;
353
354 }
355
356 // check all face vertices against all points map
357
358 for ( i = 0, il = triangles.length; i < il; i ++ ) {
359
360 face = triangles[ i ];
361
362 for ( f = 0; f < 3; f ++ ) {
363
364 key = face[ f ].x + ":" + face[ f ].y;
365
366 index = allPointsMap[ key ];
367
368 if ( index !== undefined ) {
369
370 face[ f ] = index;
371
372 }
373
374 }
375
376 }
377
378 // check isolated points vertices against all points map
379
380 for ( i = 0, il = isolatedPts.length; i < il; i ++ ) {
381
382 face = isolatedPts[ i ];
383
384 for ( f = 0; f < 3; f ++ ) {
385
386 key = face[ f ].x + ":" + face[ f ].y;
387
388 index = allPointsMap[ key ];
389
390 if ( index !== undefined ) {
391
392 face[ f ] = index;
393
394 }
395
396 }
397
398 }
399
400 return triangles.concat( isolatedPts );
401
402 }, // end triangulate shapes
403
404 /*
405 triangulate2 : function( pts, holes ) {
406
407 // For use with Poly2Tri.js
408
409 var allpts = pts.concat();
410 var shape = [];
411 for (var p in pts) {
412 shape.push(new js.poly2tri.Point(pts[p].x, pts[p].y));
413 }
414
415 var swctx = new js.poly2tri.SweepContext(shape);
416
417 for (var h in holes) {
418 var aHole = holes[h];
419 var newHole = []
420 for (i in aHole) {
421 newHole.push(new js.poly2tri.Point(aHole[i].x, aHole[i].y));
422 allpts.push(aHole[i]);
423 }
424 swctx.AddHole(newHole);
425 }
426
427 var find;
428 var findIndexForPt = function (pt) {
429 find = new THREE.Vector2(pt.x, pt.y);
430 var p;
431 for (p=0, pl = allpts.length; p<pl; p++) {
432 if (allpts[p].equals(find)) return p;
433 }
434 return -1;
435 };
436
437 // triangulate
438 js.poly2tri.sweep.Triangulate(swctx);
439
440 var triangles = swctx.GetTriangles();
441 var tr ;
442 var facesPts = [];
443 for (var t in triangles) {
444 tr = triangles[t];
445 facesPts.push([
446 findIndexForPt(tr.GetPoint(0)),
447 findIndexForPt(tr.GetPoint(1)),
448 findIndexForPt(tr.GetPoint(2))
449 ]);
450 }
451
452
453 // console.log(facesPts);
454 // console.log("triangles", triangles.length, triangles);
455
456 // Returns array of faces with 3 element each
457 return facesPts;
458 },
459 */
460
461 isClockWise: function ( pts ) {
462
463 return THREE.FontUtils.Triangulate.area( pts ) < 0;
464
465 },
466
467 // Bezier Curves formulas obtained from
468 // http://en.wikipedia.org/wiki/B%C3%A9zier_curve
469
470 // Quad Bezier Functions
471
472 b2p0: function ( t, p ) {
473
474 var k = 1 - t;
475 return k * k * p;
476
477 },
478
479 b2p1: function ( t, p ) {
480
481 return 2 * ( 1 - t ) * t * p;
482
483 },
484
485 b2p2: function ( t, p ) {
486
487 return t * t * p;
488
489 },
490
491 b2: function ( t, p0, p1, p2 ) {
492
493 return this.b2p0( t, p0 ) + this.b2p1( t, p1 ) + this.b2p2( t, p2 );
494
495 },
496
497 // Cubic Bezier Functions
498
499 b3p0: function ( t, p ) {
500
501 var k = 1 - t;
502 return k * k * k * p;
503
504 },
505
506 b3p1: function ( t, p ) {
507
508 var k = 1 - t;
509 return 3 * k * k * t * p;
510
511 },
512
513 b3p2: function ( t, p ) {
514
515 var k = 1 - t;
516 return 3 * k * t * t * p;
517
518 },
519
520 b3p3: function ( t, p ) {
521
522 return t * t * t * p;
523
524 },
525
526 b3: function ( t, p0, p1, p2, p3 ) {
527
528 return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) + this.b3p3( t, p3 );
529
530 }
531
532 };
533
534
nike free rn
new balance hombre baratas
cinturones gucci
ugg rebajas
cinturon gucci
ray ban baratas
nike cortez
peuterey mujer
christian louboutin madrid
mbt zapatos
gafas ray ban baratas
mbt ofertas
air max blancas
mbt barcelona
nike air max 90
woolrich barcelona
nike mujer
botas ugg
gafas de sol carrera aratas
air max 2016 baratas
oakley baratas
nike air max 2016