ExtrudeGeometry.js 17.4 KB
Newer Older
1 2
/**
 * @author zz85 / http://www.lab4games.net/zz85/blog
3
 *
Z
zz85 已提交
4
 * Creates extruded geometry from a path shape.
5 6
 *
 * parameters = {
A
alteredq 已提交
7
 *
8
 *  curveSegments: <int>, // number of points on the curves
D
dubejf 已提交
9
 *  steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
10
 *  depth: <float>, // Depth to extrude the shape
11
 *
12
 *  bevelEnabled: <bool>, // turn on bevel
13 14
 *  bevelThickness: <float>, // how deep into the original shape bevel goes
 *  bevelSize: <float>, // how far from shape outline is bevel
15
 *  bevelSegments: <int>, // number of bevel layers
16
 *
M
Mugen87 已提交
17
 *  extrudePath: <THREE.Curve> // curve to extrude shape along
A
alteredq 已提交
18
 *
19
 *  UVGenerator: <Object> // object that provides UV generator functions
A
alteredq 已提交
20
 *
21
 * }
M
Mugen87 已提交
22 23
 */

B
bentok 已提交
24 25 26 27 28 29
import { Geometry } from '../core/Geometry.js';
import { BufferGeometry } from '../core/BufferGeometry.js';
import { Float32BufferAttribute } from '../core/BufferAttribute.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { ShapeUtils } from '../extras/ShapeUtils.js';
M
Mugen87 已提交
30 31

// ExtrudeGeometry
32

M
Mr.doob 已提交
33
function ExtrudeGeometry( shapes, options ) {
34

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
	Geometry.call( this );

	this.type = 'ExtrudeGeometry';

	this.parameters = {
		shapes: shapes,
		options: options
	};

	this.fromBufferGeometry( new ExtrudeBufferGeometry( shapes, options ) );
	this.mergeVertices();

}

ExtrudeGeometry.prototype = Object.create( Geometry.prototype );
ExtrudeGeometry.prototype.constructor = ExtrudeGeometry;

52 53 54 55 56 57 58 59 60 61 62
ExtrudeGeometry.prototype.toJSON = function () {

	var data = Geometry.prototype.toJSON.call( this );

	var shapes = this.parameters.shapes;
	var options = this.parameters.options;

	return toJSON( shapes, options, data );

};

M
Mugen87 已提交
63
// ExtrudeBufferGeometry
64 65 66

function ExtrudeBufferGeometry( shapes, options ) {

G
cleanup  
gero3 已提交
67
	BufferGeometry.call( this );
68

69
	this.type = 'ExtrudeBufferGeometry';
70

M
Mugen87 已提交
71 72 73
	this.parameters = {
		shapes: shapes,
		options: options
G
gero3 已提交
74 75
	};

M
Mugen87 已提交
76
	shapes = Array.isArray( shapes ) ? shapes : [ shapes ];
G
gero3 已提交
77

M
Mugen87 已提交
78
	var scope = this;
G
gero3 已提交
79

M
Mugen87 已提交
80 81
	var verticesArray = [];
	var uvArray = [];
A
alteredq 已提交
82

M
Mugen87 已提交
83
	for ( var i = 0, l = shapes.length; i < l; i ++ ) {
G
gero3 已提交
84

M
Mugen87 已提交
85
		var shape = shapes[ i ];
G
gero3 已提交
86
		addShape( shape );
G
gero3 已提交
87

88
	}
G
cleanup  
gero3 已提交
89

M
Mugen87 已提交
90
	// build geometry
G
gero3 已提交
91

M
Mugen87 已提交
92 93
	this.addAttribute( 'position', new Float32BufferAttribute( verticesArray, 3 ) );
	this.addAttribute( 'uv', new Float32BufferAttribute( uvArray, 2 ) );
94

M
Mugen87 已提交
95
	this.computeVertexNormals();
G
gero3 已提交
96

M
Mugen87 已提交
97
	// functions
G
cleanup  
gero3 已提交
98

M
Mugen87 已提交
99
	function addShape( shape ) {
G
gero3 已提交
100

M
Mugen87 已提交
101
		var placeholder = [];
102

M
Mugen87 已提交
103
		// options
104

M
Mugen87 已提交
105 106
		var curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
		var steps = options.steps !== undefined ? options.steps : 1;
107
		var depth = options.depth !== undefined ? options.depth : 100;
108

M
Mugen87 已提交
109 110 111 112
		var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
		var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6;
		var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2;
		var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
113

M
Mugen87 已提交
114
		var extrudePath = options.extrudePath;
115

M
Mugen87 已提交
116
		var uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator;
117

118 119 120 121 122 123 124 125 126
		// deprecated options

		if ( options.amount !== undefined ) {

			console.warn( 'THREE.ExtrudeBufferGeometry: amount has been renamed to depth.' );
			depth = options.amount;

		}

M
Mugen87 已提交
127
		//
128

M
Mugen87 已提交
129 130
		var extrudePts, extrudeByPath = false;
		var splineTube, binormal, normal, position2;
A
alteredq 已提交
131

M
Mugen87 已提交
132
		if ( extrudePath ) {
133

M
Mugen87 已提交
134
			extrudePts = extrudePath.getSpacedPoints( steps );
135

M
Mugen87 已提交
136 137
			extrudeByPath = true;
			bevelEnabled = false; // bevels not supported for path extrusion
138

M
Mugen87 已提交
139
			// SETUP TNB variables
140

M
Mugen87 已提交
141
			// TODO1 - have a .isClosed in spline?
142

M
Mugen87 已提交
143
			splineTube = extrudePath.computeFrenetFrames( steps, false );
144

M
Mugen87 已提交
145
			// console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
146

M
Mugen87 已提交
147 148 149
			binormal = new Vector3();
			normal = new Vector3();
			position2 = new Vector3();
150

M
Mugen87 已提交
151
		}
152

M
Mugen87 已提交
153
		// Safeguards if bevels are not enabled
154

M
Mugen87 已提交
155
		if ( ! bevelEnabled ) {
156

M
Mugen87 已提交
157 158 159
			bevelSegments = 0;
			bevelThickness = 0;
			bevelSize = 0;
160

M
Mugen87 已提交
161
		}
162

M
Mugen87 已提交
163
		// Variables initialization
164

M
Mugen87 已提交
165
		var ahole, h, hl; // looping of holes
Z
zz85 已提交
166

M
Mugen87 已提交
167
		var shapePoints = shape.extractPoints( curveSegments );
168

M
Mugen87 已提交
169 170
		var vertices = shapePoints.shape;
		var holes = shapePoints.holes;
171

M
Mugen87 已提交
172
		var reverse = ! ShapeUtils.isClockWise( vertices );
Z
zz85 已提交
173

M
Mugen87 已提交
174
		if ( reverse ) {
Z
zz85 已提交
175

M
Mugen87 已提交
176
			vertices = vertices.reverse();
177

M
Mugen87 已提交
178
			// Maybe we should also check if holes are in the opposite direction, just to be safe ...
179

M
Mugen87 已提交
180
			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
181

M
Mugen87 已提交
182
				ahole = holes[ h ];
183

M
Mugen87 已提交
184
				if ( ShapeUtils.isClockWise( ahole ) ) {
185

M
Mugen87 已提交
186 187 188
					holes[ h ] = ahole.reverse();

				}
189

Z
zz85 已提交
190
			}
191

Z
zz85 已提交
192
		}
193 194


M
Mugen87 已提交
195
		var faces = ShapeUtils.triangulateShape( vertices, holes );
196

M
Mugen87 已提交
197
		/* Vertices */
198

M
Mugen87 已提交
199
		var contour = vertices; // vertices has all points but contour has only points of circumference
200

M
Mugen87 已提交
201
		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
Z
zz85 已提交
202

M
Mugen87 已提交
203
			ahole = holes[ h ];
204

M
Mugen87 已提交
205
			vertices = vertices.concat( ahole );
Z
zz85 已提交
206

M
Mugen87 已提交
207
		}
Z
zz85 已提交
208

209

M
Mugen87 已提交
210
		function scalePt2( pt, vec, size ) {
211

M
Mugen87 已提交
212
			if ( ! vec ) console.error( "THREE.ExtrudeGeometry: vec does not exist" );
213

M
Mugen87 已提交
214
			return vec.clone().multiplyScalar( size ).add( pt );
215

M
Mugen87 已提交
216
		}
217

M
Mugen87 已提交
218 219 220
		var b, bs, t, z,
			vert, vlen = vertices.length,
			face, flen = faces.length;
221 222


M
Mugen87 已提交
223
		// Find directions for point movement
224 225


M
Mugen87 已提交
226
		function getBevelVec( inPt, inPrev, inNext ) {
227

M
Mugen87 已提交
228 229 230 231 232 233
			// computes for inPt the corresponding point inPt' on a new contour
			//   shifted by 1 unit (length of normalized vector) to the left
			// if we walk along contour clockwise, this new contour is outside the old one
			//
			// inPt' is the intersection of the two lines parallel to the two
			//  adjacent edges of inPt at a distance of 1 unit on the left side.
M
Mr.doob 已提交
234

M
Mugen87 已提交
235
			var v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
M
Mr.doob 已提交
236

M
Mugen87 已提交
237 238
			// good reading for geometry algorithms (here: line-line intersection)
			// http://geomalgorithms.com/a05-_intersect-1.html
239

M
Mugen87 已提交
240 241 242 243
			var v_prev_x = inPt.x - inPrev.x,
				v_prev_y = inPt.y - inPrev.y;
			var v_next_x = inNext.x - inPt.x,
				v_next_y = inNext.y - inPt.y;
244

M
Mugen87 已提交
245
			var v_prev_lensq = ( v_prev_x * v_prev_x + v_prev_y * v_prev_y );
M
Mr.doob 已提交
246

M
Mugen87 已提交
247 248
			// check for collinear edges
			var collinear0 = ( v_prev_x * v_next_y - v_prev_y * v_next_x );
M
Mr.doob 已提交
249

M
Mugen87 已提交
250
			if ( Math.abs( collinear0 ) > Number.EPSILON ) {
M
Mr.doob 已提交
251

M
Mugen87 已提交
252
				// not collinear
G
gero3 已提交
253

M
Mugen87 已提交
254
				// length of vectors for normalizing
M
Mr.doob 已提交
255

M
Mugen87 已提交
256 257
				var v_prev_len = Math.sqrt( v_prev_lensq );
				var v_next_len = Math.sqrt( v_next_x * v_next_x + v_next_y * v_next_y );
M
Mr.doob 已提交
258

M
Mugen87 已提交
259
				// shift adjacent points by unit vectors to the left
M
Mr.doob 已提交
260

M
Mugen87 已提交
261 262
				var ptPrevShift_x = ( inPrev.x - v_prev_y / v_prev_len );
				var ptPrevShift_y = ( inPrev.y + v_prev_x / v_prev_len );
M
Mr.doob 已提交
263

M
Mugen87 已提交
264 265
				var ptNextShift_x = ( inNext.x - v_next_y / v_next_len );
				var ptNextShift_y = ( inNext.y + v_next_x / v_next_len );
M
Mr.doob 已提交
266

M
Mugen87 已提交
267
				// scaling factor for v_prev to intersection point
M
Mr.doob 已提交
268

M
Mugen87 已提交
269 270 271
				var sf = ( ( ptNextShift_x - ptPrevShift_x ) * v_next_y -
						( ptNextShift_y - ptPrevShift_y ) * v_next_x ) /
					( v_prev_x * v_next_y - v_prev_y * v_next_x );
M
Mr.doob 已提交
272

M
Mugen87 已提交
273
				// vector from inPt to intersection point
M
Mr.doob 已提交
274

M
Mugen87 已提交
275 276
				v_trans_x = ( ptPrevShift_x + v_prev_x * sf - inPt.x );
				v_trans_y = ( ptPrevShift_y + v_prev_y * sf - inPt.y );
M
Mr.doob 已提交
277

M
Mugen87 已提交
278 279 280 281
				// Don't normalize!, otherwise sharp corners become ugly
				//  but prevent crazy spikes
				var v_trans_lensq = ( v_trans_x * v_trans_x + v_trans_y * v_trans_y );
				if ( v_trans_lensq <= 2 ) {
M
Mr.doob 已提交
282

M
Mugen87 已提交
283
					return new Vector2( v_trans_x, v_trans_y );
G
gero3 已提交
284

M
Mugen87 已提交
285
				} else {
G
gero3 已提交
286

M
Mugen87 已提交
287
					shrink_by = Math.sqrt( v_trans_lensq / 2 );
G
gero3 已提交
288

M
Mugen87 已提交
289
				}
G
gero3 已提交
290

M
Mugen87 已提交
291
			} else {
M
Mr.doob 已提交
292

M
Mugen87 已提交
293
				// handle special case of collinear edges
G
gero3 已提交
294

M
Mugen87 已提交
295 296
				var direction_eq = false; // assumes: opposite
				if ( v_prev_x > Number.EPSILON ) {
297

M
Mugen87 已提交
298
					if ( v_next_x > Number.EPSILON ) {
G
gero3 已提交
299

M
Mugen87 已提交
300
						direction_eq = true;
G
gero3 已提交
301

M
Mugen87 已提交
302
					}
G
gero3 已提交
303

M
Mugen87 已提交
304
				} else {
G
gero3 已提交
305

M
Mugen87 已提交
306
					if ( v_prev_x < - Number.EPSILON ) {
G
gero3 已提交
307

M
Mugen87 已提交
308
						if ( v_next_x < - Number.EPSILON ) {
G
gero3 已提交
309

M
Mugen87 已提交
310
							direction_eq = true;
G
gero3 已提交
311

M
Mugen87 已提交
312
						}
G
gero3 已提交
313

M
Mugen87 已提交
314
					} else {
G
gero3 已提交
315

M
Mugen87 已提交
316
						if ( Math.sign( v_prev_y ) === Math.sign( v_next_y ) ) {
G
gero3 已提交
317

M
Mugen87 已提交
318
							direction_eq = true;
G
gero3 已提交
319

M
Mugen87 已提交
320
						}
G
gero3 已提交
321 322 323

					}

324
				}
G
gero3 已提交
325

M
Mugen87 已提交
326
				if ( direction_eq ) {
327

M
Mugen87 已提交
328 329 330 331
					// console.log("Warning: lines are a straight sequence");
					v_trans_x = - v_prev_y;
					v_trans_y = v_prev_x;
					shrink_by = Math.sqrt( v_prev_lensq );
G
gero3 已提交
332

M
Mugen87 已提交
333
				} else {
G
gero3 已提交
334

M
Mugen87 已提交
335 336 337 338
					// console.log("Warning: lines are a straight spike");
					v_trans_x = v_prev_x;
					v_trans_y = v_prev_y;
					shrink_by = Math.sqrt( v_prev_lensq / 2 );
G
gero3 已提交
339

M
Mugen87 已提交
340
				}
G
gero3 已提交
341

342
			}
343

M
Mugen87 已提交
344 345
			return new Vector2( v_trans_x / shrink_by, v_trans_y / shrink_by );

346
		}
347

348

M
Mugen87 已提交
349
		var contourMovements = [];
350

M
Mugen87 已提交
351
		for ( var i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
352

M
Mugen87 已提交
353 354
			if ( j === il ) j = 0;
			if ( k === il ) k = 0;
355

M
Mugen87 已提交
356 357
			//  (j)---(i)---(k)
			// console.log('i,j,k', i, j , k)
358

M
Mugen87 已提交
359
			contourMovements[ i ] = getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
360

M
Mugen87 已提交
361
		}
Z
zz85 已提交
362

M
Mugen87 已提交
363 364
		var holesMovements = [],
			oneHoleMovements, verticesMovements = contourMovements.concat();
365

M
Mugen87 已提交
366
		for ( h = 0, hl = holes.length; h < hl; h ++ ) {
367

M
Mugen87 已提交
368
			ahole = holes[ h ];
369

M
Mugen87 已提交
370
			oneHoleMovements = [];
Z
zz85 已提交
371

M
Mugen87 已提交
372
			for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i ++, j ++, k ++ ) {
373

M
Mugen87 已提交
374 375
				if ( j === il ) j = 0;
				if ( k === il ) k = 0;
376

M
Mugen87 已提交
377 378
				//  (j)---(i)---(k)
				oneHoleMovements[ i ] = getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
379

M
Mugen87 已提交
380
			}
Z
zz85 已提交
381

M
Mugen87 已提交
382 383
			holesMovements.push( oneHoleMovements );
			verticesMovements = verticesMovements.concat( oneHoleMovements );
Z
zz85 已提交
384 385

		}
386

Z
zz85 已提交
387

M
Mugen87 已提交
388
		// Loop bevelSegments, 1 for the front, 1 for the back
389

M
Mugen87 已提交
390
		for ( b = 0; b < bevelSegments; b ++ ) {
391

M
Mugen87 已提交
392
			//for ( b = bevelSegments; b > 0; b -- ) {
393

M
Mugen87 已提交
394 395 396
			t = b / bevelSegments;
			z = bevelThickness * Math.cos( t * Math.PI / 2 );
			bs = bevelSize * Math.sin( t * Math.PI / 2 );
G
gero3 已提交
397

M
Mugen87 已提交
398
			// contract shape
399

M
Mugen87 已提交
400
			for ( i = 0, il = contour.length; i < il; i ++ ) {
Z
zz85 已提交
401

M
Mugen87 已提交
402
				vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
403

M
Mugen87 已提交
404
				v( vert.x, vert.y, - z );
405

M
Mugen87 已提交
406
			}
407

M
Mugen87 已提交
408
			// expand holes
409

M
Mugen87 已提交
410
			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
411

M
Mugen87 已提交
412 413
				ahole = holes[ h ];
				oneHoleMovements = holesMovements[ h ];
414

M
Mugen87 已提交
415
				for ( i = 0, il = ahole.length; i < il; i ++ ) {
416

M
Mugen87 已提交
417
					vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
418

M
Mugen87 已提交
419
					v( vert.x, vert.y, - z );
Z
zz85 已提交
420

M
Mugen87 已提交
421
				}
422

Z
zz85 已提交
423
			}
424

Z
zz85 已提交
425
		}
426

M
Mugen87 已提交
427
		bs = bevelSize;
428

M
Mugen87 已提交
429
		// Back facing vertices
430

M
Mugen87 已提交
431
		for ( i = 0; i < vlen; i ++ ) {
Z
zz85 已提交
432

M
Mugen87 已提交
433
			vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
Z
zz85 已提交
434

M
Mugen87 已提交
435
			if ( ! extrudeByPath ) {
436

M
Mugen87 已提交
437
				v( vert.x, vert.y, 0 );
Z
zz85 已提交
438

M
Mugen87 已提交
439
			} else {
Z
zz85 已提交
440

M
Mugen87 已提交
441
				// v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
Z
zz85 已提交
442

M
Mugen87 已提交
443 444
				normal.copy( splineTube.normals[ 0 ] ).multiplyScalar( vert.x );
				binormal.copy( splineTube.binormals[ 0 ] ).multiplyScalar( vert.y );
445

M
Mugen87 已提交
446
				position2.copy( extrudePts[ 0 ] ).add( normal ).add( binormal );
A
alteredq 已提交
447

M
Mugen87 已提交
448
				v( position2.x, position2.y, position2.z );
449

M
Mugen87 已提交
450
			}
Z
zz85 已提交
451 452 453

		}

M
Mugen87 已提交
454 455
		// Add stepped vertices...
		// Including front facing vertices
Z
zz85 已提交
456

M
Mugen87 已提交
457
		var s;
Z
zz85 已提交
458

M
Mugen87 已提交
459
		for ( s = 1; s <= steps; s ++ ) {
460

M
Mugen87 已提交
461
			for ( i = 0; i < vlen; i ++ ) {
Z
zz85 已提交
462

M
Mugen87 已提交
463
				vert = bevelEnabled ? scalePt2( vertices[ i ], verticesMovements[ i ], bs ) : vertices[ i ];
Z
zz85 已提交
464

M
Mugen87 已提交
465
				if ( ! extrudeByPath ) {
Z
zz85 已提交
466

467
					v( vert.x, vert.y, depth / steps * s );
Z
zz85 已提交
468

M
Mugen87 已提交
469
				} else {
Z
zz85 已提交
470

M
Mugen87 已提交
471
					// v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
Z
zz85 已提交
472

M
Mugen87 已提交
473 474
					normal.copy( splineTube.normals[ s ] ).multiplyScalar( vert.x );
					binormal.copy( splineTube.binormals[ s ] ).multiplyScalar( vert.y );
475

M
Mugen87 已提交
476
					position2.copy( extrudePts[ s ] ).add( normal ).add( binormal );
477

M
Mugen87 已提交
478
					v( position2.x, position2.y, position2.z );
479

M
Mugen87 已提交
480
				}
Z
zz85 已提交
481 482 483 484 485

			}

		}

486

M
Mugen87 已提交
487
		// Add bevel segments planes
488

M
Mugen87 已提交
489 490
		//for ( b = 1; b <= bevelSegments; b ++ ) {
		for ( b = bevelSegments - 1; b >= 0; b -- ) {
491

M
Mugen87 已提交
492 493 494
			t = b / bevelSegments;
			z = bevelThickness * Math.cos( t * Math.PI / 2 );
			bs = bevelSize * Math.sin( t * Math.PI / 2 );
495

M
Mugen87 已提交
496
			// contract shape
497

M
Mugen87 已提交
498
			for ( i = 0, il = contour.length; i < il; i ++ ) {
499

M
Mugen87 已提交
500
				vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
501
				v( vert.x, vert.y, depth + z );
502

M
Mugen87 已提交
503
			}
504

M
Mugen87 已提交
505
			// expand holes
506

M
Mugen87 已提交
507
			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
508

M
Mugen87 已提交
509 510
				ahole = holes[ h ];
				oneHoleMovements = holesMovements[ h ];
511

M
Mugen87 已提交
512
				for ( i = 0, il = ahole.length; i < il; i ++ ) {
513

M
Mugen87 已提交
514
					vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
515

M
Mugen87 已提交
516
					if ( ! extrudeByPath ) {
Z
zz85 已提交
517

518
						v( vert.x, vert.y, depth + z );
Z
zz85 已提交
519

M
Mugen87 已提交
520
					} else {
Z
zz85 已提交
521

M
Mugen87 已提交
522
						v( vert.x, vert.y + extrudePts[ steps - 1 ].y, extrudePts[ steps - 1 ].x + z );
Z
zz85 已提交
523

M
Mugen87 已提交
524
					}
Z
zz85 已提交
525

Z
zz85 已提交
526
				}
527

Z
zz85 已提交
528 529
			}

530 531
		}

M
Mugen87 已提交
532
		/* Faces */
Z
zz85 已提交
533

M
Mugen87 已提交
534
		// Top and bottom faces
535

M
Mugen87 已提交
536
		buildLidFaces();
A
alteredq 已提交
537

M
Mugen87 已提交
538
		// Sides faces
539

M
Mugen87 已提交
540
		buildSideFaces();
A
alteredq 已提交
541

542

M
Mugen87 已提交
543
		/////  Internal functions
544

M
Mugen87 已提交
545
		function buildLidFaces() {
546

M
Mugen87 已提交
547
			var start = verticesArray.length / 3;
M
Mugen87 已提交
548

M
Mugen87 已提交
549
			if ( bevelEnabled ) {
A
alteredq 已提交
550

M
Mugen87 已提交
551 552
				var layer = 0; // steps + 1
				var offset = vlen * layer;
553

M
Mugen87 已提交
554
				// Bottom faces
Z
zz85 已提交
555

M
Mugen87 已提交
556
				for ( i = 0; i < flen; i ++ ) {
A
alteredq 已提交
557

M
Mugen87 已提交
558 559
					face = faces[ i ];
					f3( face[ 2 ] + offset, face[ 1 ] + offset, face[ 0 ] + offset );
560

M
Mugen87 已提交
561
				}
562

M
Mugen87 已提交
563 564
				layer = steps + bevelSegments * 2;
				offset = vlen * layer;
565

M
Mugen87 已提交
566
				// Top faces
Z
zz85 已提交
567

M
Mugen87 已提交
568
				for ( i = 0; i < flen; i ++ ) {
Z
zz85 已提交
569

M
Mugen87 已提交
570 571
					face = faces[ i ];
					f3( face[ 0 ] + offset, face[ 1 ] + offset, face[ 2 ] + offset );
A
alteredq 已提交
572

M
Mugen87 已提交
573
				}
A
alteredq 已提交
574

M
Mugen87 已提交
575
			} else {
A
alteredq 已提交
576

M
Mugen87 已提交
577
				// Bottom faces
A
alteredq 已提交
578

M
Mugen87 已提交
579
				for ( i = 0; i < flen; i ++ ) {
580

M
Mugen87 已提交
581 582
					face = faces[ i ];
					f3( face[ 2 ], face[ 1 ], face[ 0 ] );
A
alteredq 已提交
583

M
Mugen87 已提交
584
				}
A
alteredq 已提交
585

M
Mugen87 已提交
586
				// Top faces
Z
zz85 已提交
587

M
Mugen87 已提交
588
				for ( i = 0; i < flen; i ++ ) {
Z
zz85 已提交
589

M
Mugen87 已提交
590 591
					face = faces[ i ];
					f3( face[ 0 ] + vlen * steps, face[ 1 ] + vlen * steps, face[ 2 ] + vlen * steps );
A
alteredq 已提交
592

M
Mugen87 已提交
593
				}
A
alteredq 已提交
594

595
			}
G
gero3 已提交
596

M
Mugen87 已提交
597 598
			scope.addGroup( start, verticesArray.length / 3 - start, 0 );

Z
zz85 已提交
599
		}
M
Mugen87 已提交
600

M
Mugen87 已提交
601
		// Create faces for the z-sides of the shape
A
alteredq 已提交
602

M
Mugen87 已提交
603
		function buildSideFaces() {
604

M
Mugen87 已提交
605 606 607 608
			var start = verticesArray.length / 3;
			var layeroffset = 0;
			sidewalls( contour, layeroffset );
			layeroffset += contour.length;
609

M
Mugen87 已提交
610
			for ( h = 0, hl = holes.length; h < hl; h ++ ) {
A
alteredq 已提交
611

M
Mugen87 已提交
612 613
				ahole = holes[ h ];
				sidewalls( ahole, layeroffset );
614

M
Mugen87 已提交
615 616
				//, true
				layeroffset += ahole.length;
617

M
Mugen87 已提交
618
			}
A
alteredq 已提交
619

M
Mugen87 已提交
620

M
Mugen87 已提交
621
			scope.addGroup( start, verticesArray.length / 3 - start, 1 );
G
gero3 已提交
622 623


M
Mugen87 已提交
624
		}
A
alteredq 已提交
625

M
Mugen87 已提交
626
		function sidewalls( contour, layeroffset ) {
Z
zz85 已提交
627

M
Mugen87 已提交
628 629
			var j, k;
			i = contour.length;
A
alteredq 已提交
630

M
Mugen87 已提交
631
			while ( -- i >= 0 ) {
632

M
Mugen87 已提交
633 634 635
				j = i;
				k = i - 1;
				if ( k < 0 ) k = contour.length - 1;
A
alteredq 已提交
636

M
Mugen87 已提交
637
				//console.log('b', i,j, i-1, k,vertices.length);
638

M
Mugen87 已提交
639 640
				var s = 0,
					sl = steps + bevelSegments * 2;
641

M
Mugen87 已提交
642
				for ( s = 0; s < sl; s ++ ) {
643

M
Mugen87 已提交
644 645
					var slen1 = vlen * s;
					var slen2 = vlen * ( s + 1 );
A
alteredq 已提交
646

M
Mugen87 已提交
647 648 649 650
					var a = layeroffset + j + slen1,
						b = layeroffset + k + slen1,
						c = layeroffset + k + slen2,
						d = layeroffset + j + slen2;
A
alteredq 已提交
651

M
Mugen87 已提交
652
					f4( a, b, c, d );
A
alteredq 已提交
653

M
Mugen87 已提交
654
				}
A
alteredq 已提交
655

Z
zz85 已提交
656
			}
G
gero3 已提交
657

Z
zz85 已提交
658
		}
A
alteredq 已提交
659

M
Mugen87 已提交
660
		function v( x, y, z ) {
G
cleanup  
gero3 已提交
661

M
Mugen87 已提交
662 663 664
			placeholder.push( x );
			placeholder.push( y );
			placeholder.push( z );
G
cleanup  
gero3 已提交
665

M
Mugen87 已提交
666
		}
A
alteredq 已提交
667

668

M
Mugen87 已提交
669
		function f3( a, b, c ) {
A
alteredq 已提交
670

M
Mugen87 已提交
671 672 673
			addVertex( a );
			addVertex( b );
			addVertex( c );
674

M
Mugen87 已提交
675 676
			var nextIndex = verticesArray.length / 3;
			var uvs = uvgen.generateTopUV( scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
A
alteredq 已提交
677

M
Mugen87 已提交
678 679 680
			addUV( uvs[ 0 ] );
			addUV( uvs[ 1 ] );
			addUV( uvs[ 2 ] );
A
alteredq 已提交
681

M
Mugen87 已提交
682
		}
683

M
Mugen87 已提交
684
		function f4( a, b, c, d ) {
685

M
Mugen87 已提交
686 687 688
			addVertex( a );
			addVertex( b );
			addVertex( d );
A
alteredq 已提交
689

M
Mugen87 已提交
690 691 692
			addVertex( b );
			addVertex( c );
			addVertex( d );
Z
zz85 已提交
693

A
alteredq 已提交
694

M
Mugen87 已提交
695 696
			var nextIndex = verticesArray.length / 3;
			var uvs = uvgen.generateSideWallUV( scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1 );
M
Mr.doob 已提交
697

M
Mugen87 已提交
698 699 700
			addUV( uvs[ 0 ] );
			addUV( uvs[ 1 ] );
			addUV( uvs[ 3 ] );
G
cleanup  
gero3 已提交
701

M
Mugen87 已提交
702 703 704
			addUV( uvs[ 1 ] );
			addUV( uvs[ 2 ] );
			addUV( uvs[ 3 ] );
G
cleanup  
gero3 已提交
705

M
Mugen87 已提交
706
		}
G
cleanup  
gero3 已提交
707

M
Mugen87 已提交
708
		function addVertex( index ) {
G
cleanup  
gero3 已提交
709

M
Mugen87 已提交
710 711 712
			verticesArray.push( placeholder[ index * 3 + 0 ] );
			verticesArray.push( placeholder[ index * 3 + 1 ] );
			verticesArray.push( placeholder[ index * 3 + 2 ] );
G
cleanup  
gero3 已提交
713

M
Mugen87 已提交
714
		}
G
cleanup  
gero3 已提交
715 716


M
Mugen87 已提交
717
		function addUV( vector2 ) {
G
cleanup  
gero3 已提交
718

M
Mugen87 已提交
719 720
			uvArray.push( vector2.x );
			uvArray.push( vector2.y );
G
cleanup  
gero3 已提交
721

M
Mugen87 已提交
722
		}
G
cleanup  
gero3 已提交
723

G
gero3 已提交
724
	}
G
gero3 已提交
725

M
Mugen87 已提交
726
}
727

M
Mugen87 已提交
728 729
ExtrudeBufferGeometry.prototype = Object.create( BufferGeometry.prototype );
ExtrudeBufferGeometry.prototype.constructor = ExtrudeBufferGeometry;
730

731 732 733 734 735 736 737 738 739 740 741 742 743
ExtrudeBufferGeometry.prototype.toJSON = function () {

	var data = BufferGeometry.prototype.toJSON.call( this );

	var shapes = this.parameters.shapes;
	var options = this.parameters.options;

	return toJSON( shapes, options, data );

};

//

M
Mugen87 已提交
744
var WorldUVGenerator = {
A
alteredq 已提交
745

G
cleanup  
gero3 已提交
746
	generateTopUV: function ( geometry, vertices, indexA, indexB, indexC ) {
M
Mr.doob 已提交
747

G
cleanup  
gero3 已提交
748 749 750 751 752 753
		var a_x = vertices[ indexA * 3 ];
		var a_y = vertices[ indexA * 3 + 1 ];
		var b_x = vertices[ indexB * 3 ];
		var b_y = vertices[ indexB * 3 + 1 ];
		var c_x = vertices[ indexC * 3 ];
		var c_y = vertices[ indexC * 3 + 1 ];
A
alteredq 已提交
754

755
		return [
G
cleanup  
gero3 已提交
756 757 758
			new Vector2( a_x, a_y ),
			new Vector2( b_x, b_y ),
			new Vector2( c_x, c_y )
759
		];
A
alteredq 已提交
760

761 762
	},

G
cleanup  
gero3 已提交
763
	generateSideWallUV: function ( geometry, vertices, indexA, indexB, indexC, indexD ) {
764

G
cleanup  
gero3 已提交
765 766 767 768 769 770 771 772 773 774 775 776
		var a_x = vertices[ indexA * 3 ];
		var a_y = vertices[ indexA * 3 + 1 ];
		var a_z = vertices[ indexA * 3 + 2 ];
		var b_x = vertices[ indexB * 3 ];
		var b_y = vertices[ indexB * 3 + 1 ];
		var b_z = vertices[ indexB * 3 + 2 ];
		var c_x = vertices[ indexC * 3 ];
		var c_y = vertices[ indexC * 3 + 1 ];
		var c_z = vertices[ indexC * 3 + 2 ];
		var d_x = vertices[ indexD * 3 ];
		var d_y = vertices[ indexD * 3 + 1 ];
		var d_z = vertices[ indexD * 3 + 2 ];
G
gero3 已提交
777

G
cleanup  
gero3 已提交
778
		if ( Math.abs( a_y - b_y ) < 0.01 ) {
G
gero3 已提交
779

780
			return [
G
cleanup  
gero3 已提交
781 782 783 784
				new Vector2( a_x, 1 - a_z ),
				new Vector2( b_x, 1 - b_z ),
				new Vector2( c_x, 1 - c_z ),
				new Vector2( d_x, 1 - d_z )
785
			];
G
gero3 已提交
786

G
cleanup  
gero3 已提交
787
		} else {
G
gero3 已提交
788

789
			return [
G
cleanup  
gero3 已提交
790 791 792 793
				new Vector2( a_y, 1 - a_z ),
				new Vector2( b_y, 1 - b_z ),
				new Vector2( c_y, 1 - c_z ),
				new Vector2( d_y, 1 - d_z )
794
			];
G
gero3 已提交
795

796
		}
G
gero3 已提交
797

798 799
	}
};
R
Rich Harris 已提交
800

801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
function toJSON( shapes, options, data ) {

	//

	data.shapes = [];

	if ( Array.isArray( shapes ) ) {

		for ( var i = 0, l = shapes.length; i < l; i ++ ) {

			var shape = shapes[ i ];

			data.shapes.push( shape.uuid );

		}

	} else {

		data.shapes.push( shapes.uuid );

	}

	//

	if ( options.extrudePath !== undefined ) data.options.extrudePath = options.extrudePath.toJSON();

	return data;

}

R
Rich Harris 已提交
831

M
Mugen87 已提交
832
export { ExtrudeGeometry, ExtrudeBufferGeometry };