Object3D.js 16.2 KB
Newer Older
B
bentok 已提交
1 2 3 4 5 6 7 8
import { Quaternion } from '../math/Quaternion.js';
import { Vector3 } from '../math/Vector3.js';
import { Matrix4 } from '../math/Matrix4.js';
import { EventDispatcher } from './EventDispatcher.js';
import { Euler } from '../math/Euler.js';
import { Layers } from './Layers.js';
import { Matrix3 } from '../math/Matrix3.js';
import { _Math } from '../math/Math.js';
9
import { TrianglesDrawMode } from '../constants.js';
R
Rich Harris 已提交
10

M
Mr.doob 已提交
11
/**
M
Mr.doob 已提交
12
 * @author mrdoob / http://mrdoob.com/
13 14
 * @author mikael emtinger / http://gomo.se/
 * @author alteredq / http://alteredqualia.com/
15
 * @author WestLangley / http://github.com/WestLangley
E
elephantatwork 已提交
16
 * @author elephantatwork / www.elephantatwork.ch
M
Mr.doob 已提交
17 18
 */

M
Mugen87 已提交
19 20 21 22
var _object3DId = 0;
var _m1, _q1, _v1;
var _xAxis, _yAxis, _zAxis;
var _target, _position, _scale, _quaternion;
23

M
Mr.doob 已提交
24
function Object3D() {
25

M
Mugen87 已提交
26
	Object.defineProperty( this, 'id', { value: _object3DId ++ } );
M
Mr.doob 已提交
27

R
Rich Harris 已提交
28
	this.uuid = _Math.generateUUID();
M
Mr.doob 已提交
29

30
	this.name = '';
31
	this.type = 'Object3D';
32

33
	this.parent = null;
34 35
	this.children = [];

R
Rich Harris 已提交
36
	this.up = Object3D.DefaultUp.clone();
37

R
Rich Harris 已提交
38
	var position = new Vector3();
39
	var rotation = new Euler();
R
Rich Harris 已提交
40 41
	var quaternion = new Quaternion();
	var scale = new Vector3( 1, 1, 1 );
42

M
Mr.doob 已提交
43
	function onRotationChange() {
G
gero3 已提交
44

45 46 47 48 49 50 51
		quaternion.setFromEuler( rotation, false );

	}

	function onQuaternionChange() {

		rotation.setFromQuaternion( quaternion, undefined, false );
G
gero3 已提交
52

M
Mr.doob 已提交
53
	}
M
Mr.doob 已提交
54

55 56
	rotation._onChange( onRotationChange );
	quaternion._onChange( onQuaternionChange );
57 58

	Object.defineProperties( this, {
59
		position: {
60
			configurable: true,
61
			enumerable: true,
62
			value: position
63
		},
64
		rotation: {
65
			configurable: true,
66
			enumerable: true,
67
			value: rotation
68 69
		},
		quaternion: {
70
			configurable: true,
71
			enumerable: true,
72
			value: quaternion
73 74
		},
		scale: {
75
			configurable: true,
76
			enumerable: true,
77
			value: scale
78 79
		},
		modelViewMatrix: {
R
Rich Harris 已提交
80
			value: new Matrix4()
81 82
		},
		normalMatrix: {
R
Rich Harris 已提交
83
			value: new Matrix3()
M
Mr.doob 已提交
84
		}
85
	} );
86

R
Rich Harris 已提交
87 88
	this.matrix = new Matrix4();
	this.matrixWorld = new Matrix4();
89

R
Rich Harris 已提交
90
	this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
91
	this.matrixWorldNeedsUpdate = false;
92

R
Rich Harris 已提交
93
	this.layers = new Layers();
94
	this.visible = true;
95

96 97 98
	this.castShadow = false;
	this.receiveShadow = false;

A
alteredq 已提交
99
	this.frustumCulled = true;
100
	this.renderOrder = 0;
A
alteredq 已提交
101

102
	this.userData = {};
M
Mugen87 已提交
103

M
Mr.doob 已提交
104
}
105

R
Rich Harris 已提交
106 107
Object3D.DefaultUp = new Vector3( 0, 1, 0 );
Object3D.DefaultMatrixAutoUpdate = true;
108

109
Object3D.prototype = Object.assign( Object.create( EventDispatcher.prototype ), {
M
Mugen87 已提交
110

111
	constructor: Object3D,
M
Mr.doob 已提交
112

113 114
	isObject3D: true,

115 116 117
	onBeforeRender: function () {},
	onAfterRender: function () {},

W
WestLangley 已提交
118
	applyMatrix: function ( matrix ) {
M
Mr.doob 已提交
119

W
WestLangley 已提交
120 121 122
		if ( this.matrixAutoUpdate ) this.updateMatrix();

		this.matrix.premultiply( matrix );
A
alteredq 已提交
123

W
WestLangley 已提交
124
		this.matrix.decompose( this.position, this.quaternion, this.scale );
125

W
WestLangley 已提交
126
	},
M
Mr.doob 已提交
127

W
WestLangley 已提交
128 129 130 131 132 133 134 135
	applyQuaternion: function ( q ) {

		this.quaternion.premultiply( q );

		return this;

	},

136 137 138 139 140 141 142 143 144 145
	setRotationFromAxisAngle: function ( axis, angle ) {

		// assumes axis is normalized

		this.quaternion.setFromAxisAngle( axis, angle );

	},

	setRotationFromEuler: function ( euler ) {

146
		this.quaternion.setFromEuler( euler, true );
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165

	},

	setRotationFromMatrix: function ( m ) {

		// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)

		this.quaternion.setFromRotationMatrix( m );

	},

	setRotationFromQuaternion: function ( q ) {

		// assumes q is normalized

		this.quaternion.copy( q );

	},

M
Mugen87 已提交
166
	rotateOnAxis: function ( axis, angle ) {
167

168 169 170
		// rotate object on axis in object space
		// axis is assumed to be normalized

M
Mugen87 已提交
171
		if ( _q1 === undefined ) _q1 = new Quaternion();
172

M
Mugen87 已提交
173
		_q1.setFromAxisAngle( axis, angle );
174

M
Mugen87 已提交
175
		this.quaternion.multiply( _q1 );
176

M
Mugen87 已提交
177
		return this;
178

M
Mugen87 已提交
179
	},
180

M
Mugen87 已提交
181
	rotateOnWorldAxis: function ( axis, angle ) {
M
Mugen87 已提交
182

183 184 185 186
		// rotate object on axis in world space
		// axis is assumed to be normalized
		// method assumes no rotated parent

M
Mugen87 已提交
187
		if ( _q1 === undefined ) _q1 = new Quaternion();
M
Mugen87 已提交
188

M
Mugen87 已提交
189
		_q1.setFromAxisAngle( axis, angle );
M
Mugen87 已提交
190

M
Mugen87 已提交
191
		this.quaternion.premultiply( _q1 );
M
Mugen87 已提交
192

M
Mugen87 已提交
193
		return this;
194

M
Mugen87 已提交
195
	},
196

M
Mugen87 已提交
197
	rotateX: function ( angle ) {
198

M
Mugen87 已提交
199
		if ( _xAxis === undefined ) _xAxis = new Vector3( 1, 0, 0 );
200

M
Mugen87 已提交
201
		return this.rotateOnAxis( _xAxis, angle );
202

M
Mugen87 已提交
203
	},
204

M
Mugen87 已提交
205
	rotateY: function ( angle ) {
206

M
Mugen87 已提交
207
		if ( _yAxis === undefined ) _yAxis = new Vector3( 0, 1, 0 );
208

M
Mugen87 已提交
209
		return this.rotateOnAxis( _yAxis, angle );
210

M
Mugen87 已提交
211
	},
212

M
Mugen87 已提交
213
	rotateZ: function ( angle ) {
214

M
Mugen87 已提交
215
		if ( _zAxis === undefined ) _zAxis = new Vector3( 0, 0, 1 );
216

M
Mugen87 已提交
217
		return this.rotateOnAxis( _zAxis, angle );
218

M
Mugen87 已提交
219
	},
220

M
Mugen87 已提交
221
	translateOnAxis: function ( axis, distance ) {
222 223 224 225

		// translate object by distance along axis in object space
		// axis is assumed to be normalized

M
Mugen87 已提交
226
		if ( _v1 === undefined ) _v1 = new Vector3();
227

M
Mugen87 已提交
228
		_v1.copy( axis ).applyQuaternion( this.quaternion );
229

M
Mugen87 已提交
230
		this.position.add( _v1.multiplyScalar( distance ) );
231

M
Mugen87 已提交
232
		return this;
233

M
Mugen87 已提交
234
	},
235

M
Mugen87 已提交
236
	translateX: function ( distance ) {
237

M
Mugen87 已提交
238
		if ( _xAxis === undefined ) _xAxis = new Vector3( 1, 0, 0 );
239

M
Mugen87 已提交
240
		return this.translateOnAxis( _xAxis, distance );
241

M
Mugen87 已提交
242
	},
243

M
Mugen87 已提交
244
	translateY: function ( distance ) {
245

M
Mugen87 已提交
246
		if ( _yAxis === undefined ) _yAxis = new Vector3( 0, 1, 0 );
247

M
Mugen87 已提交
248
		return this.translateOnAxis( _yAxis, distance );
249

M
Mugen87 已提交
250
	},
251

M
Mugen87 已提交
252
	translateZ: function ( distance ) {
253

M
Mugen87 已提交
254
		if ( _zAxis === undefined ) _zAxis = new Vector3( 0, 0, 1 );
255

M
Mugen87 已提交
256
		return this.translateOnAxis( _zAxis, distance );
257

M
Mugen87 已提交
258
	},
259

M
Mr.doob 已提交
260 261
	localToWorld: function ( vector ) {

262
		return vector.applyMatrix4( this.matrixWorld );
M
Mr.doob 已提交
263 264 265

	},

M
Mugen87 已提交
266
	worldToLocal: function ( vector ) {
M
Mr.doob 已提交
267

M
Mugen87 已提交
268
		if ( _m1 === undefined ) _m1 = new Matrix4();
269

M
Mugen87 已提交
270
		return vector.applyMatrix4( _m1.getInverse( this.matrixWorld ) );
271

M
Mugen87 已提交
272
	},
273

M
Mugen87 已提交
274
	lookAt: function ( x, y, z ) {
275

276
		// This method does not support objects having non-uniformly-scaled parent(s)
277

M
Mugen87 已提交
278
		if ( _position === undefined ) {
279

M
Mugen87 已提交
280 281 282 283
			_q1 = new Quaternion();
			_m1 = new Matrix4();
			_target = new Vector3();
			_position = new Vector3();
W
WestLangley 已提交
284

M
Mugen87 已提交
285
		}
W
WestLangley 已提交
286

M
Mugen87 已提交
287
		if ( x.isVector3 ) {
W
WestLangley 已提交
288

M
Mugen87 已提交
289
			_target.copy( x );
W
WestLangley 已提交
290

M
Mugen87 已提交
291
		} else {
W
WestLangley 已提交
292

M
Mugen87 已提交
293
			_target.set( x, y, z );
294

M
Mugen87 已提交
295
		}
296

M
Mugen87 已提交
297
		var parent = this.parent;
298

M
Mugen87 已提交
299
		this.updateWorldMatrix( true, false );
300

M
Mugen87 已提交
301
		_position.setFromMatrixPosition( this.matrixWorld );
302

M
Mugen87 已提交
303
		if ( this.isCamera || this.isLight ) {
304

M
Mugen87 已提交
305
			_m1.lookAt( _position, _target, this.up );
306

M
Mugen87 已提交
307
		} else {
308

M
Mugen87 已提交
309
			_m1.lookAt( _target, _position, this.up );
310

M
Mugen87 已提交
311
		}
312

M
Mugen87 已提交
313
		this.quaternion.setFromRotationMatrix( _m1 );
314

M
Mugen87 已提交
315
		if ( parent ) {
316

M
Mugen87 已提交
317 318 319
			_m1.extractRotation( parent.matrixWorld );
			_q1.setFromRotationMatrix( _m1 );
			this.quaternion.premultiply( _q1.inverse() );
320

M
Mugen87 已提交
321
		}
322

M
Mugen87 已提交
323
	},
324

325
	add: function ( object ) {
326

327 328
		if ( arguments.length > 1 ) {

G
gero3 已提交
329
			for ( var i = 0; i < arguments.length; i ++ ) {
330 331 332 333 334 335 336

				this.add( arguments[ i ] );

			}

			return this;

B
brason 已提交
337
		}
338

339 340
		if ( object === this ) {

341
			console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
342
			return this;
343 344 345

		}

M
Mr.doob 已提交
346
		if ( ( object && object.isObject3D ) ) {
A
alteredq 已提交
347

348
			if ( object.parent !== null ) {
A
alteredq 已提交
349

M
Mr.doob 已提交
350
				object.parent.remove( object );
351

A
alteredq 已提交
352 353
			}

354 355
			object.parent = this;
			this.children.push( object );
M
Mr.doob 已提交
356

357 358
			object.dispatchEvent( { type: 'added' } );

M
Mr.doob 已提交
359
		} else {
M
Mr.doob 已提交
360

361
			console.error( "THREE.Object3D.add: object not an instance of THREE.Object3D.", object );
M
Mr.doob 已提交
362

363
		}
M
Mr.doob 已提交
364

365 366
		return this;

367
	},
368

369
	remove: function ( object ) {
370

371 372
		if ( arguments.length > 1 ) {

G
gero3 已提交
373
			for ( var i = 0; i < arguments.length; i ++ ) {
374 375 376 377 378

				this.remove( arguments[ i ] );

			}

0
06wj 已提交
379 380
			return this;

B
brason 已提交
381
		}
382

M
Mr.doob 已提交
383
		var index = this.children.indexOf( object );
384

M
Mr.doob 已提交
385
		if ( index !== - 1 ) {
386

387
			object.parent = null;
388
			this.children.splice( index, 1 );
389

390 391
			object.dispatchEvent( { type: 'removed' } );

M
Mr.doob 已提交
392
		}
393

0
06wj 已提交
394
		return this;
395

M
Mr.doob 已提交
396
	},
397

M
Mugen87 已提交
398
	attach: function ( object ) {
W
WestLangley 已提交
399 400 401

		// adds object as a child of this, while maintaining the object's world transform

M
Mugen87 已提交
402
		if ( _m1 === undefined ) _m1 = new Matrix4();
W
WestLangley 已提交
403

M
Mugen87 已提交
404
		this.updateWorldMatrix( true, false );
W
WestLangley 已提交
405

M
Mugen87 已提交
406
		_m1.getInverse( this.matrixWorld );
W
WestLangley 已提交
407

M
Mugen87 已提交
408
		if ( object.parent !== null ) {
W
WestLangley 已提交
409

M
Mugen87 已提交
410
			object.parent.updateWorldMatrix( true, false );
W
WestLangley 已提交
411

M
Mugen87 已提交
412
			_m1.multiply( object.parent.matrixWorld );
W
WestLangley 已提交
413

M
Mugen87 已提交
414
		}
W
WestLangley 已提交
415

M
Mugen87 已提交
416
		object.applyMatrix( _m1 );
W
WestLangley 已提交
417

M
Mugen87 已提交
418
		object.updateWorldMatrix( false, false );
W
WestLangley 已提交
419

M
Mugen87 已提交
420
		this.add( object );
W
WestLangley 已提交
421

M
Mugen87 已提交
422
		return this;
W
WestLangley 已提交
423

M
Mugen87 已提交
424
	},
W
WestLangley 已提交
425

426
	getObjectById: function ( id ) {
427

428
		return this.getObjectByProperty( 'id', id );
429

W
Wilt 已提交
430
	},
431

432
	getObjectByName: function ( name ) {
433

434
		return this.getObjectByProperty( 'name', name );
435 436

	},
M
Mr.doob 已提交
437

438
	getObjectByProperty: function ( name, value ) {
439

M
Mr.doob 已提交
440
		if ( this[ name ] === value ) return this;
441

442
		for ( var i = 0, l = this.children.length; i < l; i ++ ) {
M
Mr.doob 已提交
443

444
			var child = this.children[ i ];
445
			var object = child.getObjectByProperty( name, value );
M
Mr.doob 已提交
446

447
			if ( object !== undefined ) {
M
Mr.doob 已提交
448

449
				return object;
M
Mr.doob 已提交
450

451
			}
M
Mr.doob 已提交
452

453
		}
M
Mr.doob 已提交
454

455
		return undefined;
M
Mr.doob 已提交
456

457
	},
M
Mr.doob 已提交
458

W
WestLangley 已提交
459
	getWorldPosition: function ( target ) {
W
WestLangley 已提交
460

W
WestLangley 已提交
461 462 463 464 465 466
		if ( target === undefined ) {

			console.warn( 'THREE.Object3D: .getWorldPosition() target is now required' );
			target = new Vector3();

		}
W
WestLangley 已提交
467 468 469

		this.updateMatrixWorld( true );

W
WestLangley 已提交
470
		return target.setFromMatrixPosition( this.matrixWorld );
W
WestLangley 已提交
471 472 473

	},

M
Mugen87 已提交
474
	getWorldQuaternion: function ( target ) {
W
WestLangley 已提交
475

M
Mugen87 已提交
476
		if ( _scale === undefined ) {
W
WestLangley 已提交
477

M
Mugen87 已提交
478 479
			_position = new Vector3();
			_scale = new Vector3();
W
WestLangley 已提交
480

M
Mugen87 已提交
481
		}
W
WestLangley 已提交
482

M
Mugen87 已提交
483
		if ( target === undefined ) {
W
WestLangley 已提交
484

M
Mugen87 已提交
485 486
			console.warn( 'THREE.Object3D: .getWorldQuaternion() target is now required' );
			target = new Quaternion();
W
WestLangley 已提交
487

M
Mugen87 已提交
488
		}
W
WestLangley 已提交
489

M
Mugen87 已提交
490
		this.updateMatrixWorld( true );
W
WestLangley 已提交
491

M
Mugen87 已提交
492
		this.matrixWorld.decompose( _position, target, _scale );
W
WestLangley 已提交
493

M
Mugen87 已提交
494
		return target;
W
WestLangley 已提交
495

M
Mugen87 已提交
496
	},
W
WestLangley 已提交
497

M
Mugen87 已提交
498
	getWorldScale: function ( target ) {
W
WestLangley 已提交
499

M
Mugen87 已提交
500
		if ( _quaternion === undefined ) {
W
WestLangley 已提交
501

M
Mugen87 已提交
502 503
			_position = new Vector3();
			_quaternion = new Quaternion();
W
WestLangley 已提交
504

M
Mugen87 已提交
505
		}
W
WestLangley 已提交
506

M
Mugen87 已提交
507
		if ( target === undefined ) {
W
WestLangley 已提交
508

M
Mugen87 已提交
509 510
			console.warn( 'THREE.Object3D: .getWorldScale() target is now required' );
			target = new Vector3();
W
WestLangley 已提交
511

M
Mugen87 已提交
512
		}
W
WestLangley 已提交
513

M
Mugen87 已提交
514
		this.updateMatrixWorld( true );
W
WestLangley 已提交
515

M
Mugen87 已提交
516
		this.matrixWorld.decompose( _position, _quaternion, target );
W
WestLangley 已提交
517

M
Mugen87 已提交
518
		return target;
W
WestLangley 已提交
519

M
Mugen87 已提交
520
	},
W
WestLangley 已提交
521

M
mbredif 已提交
522
	getWorldDirection: function ( target ) {
W
WestLangley 已提交
523

M
mbredif 已提交
524
		if ( target === undefined ) {
W
WestLangley 已提交
525

M
mbredif 已提交
526 527
			console.warn( 'THREE.Object3D: .getWorldDirection() target is now required' );
			target = new Vector3();
W
WestLangley 已提交
528

M
mbredif 已提交
529
		}
W
WestLangley 已提交
530

M
mbredif 已提交
531
		this.updateMatrixWorld( true );
W
WestLangley 已提交
532

M
mbredif 已提交
533
		var e = this.matrixWorld.elements;
W
WestLangley 已提交
534

M
mbredif 已提交
535
		return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
W
WestLangley 已提交
536

M
mbredif 已提交
537
	},
W
WestLangley 已提交
538

539 540 541 542 543 544
	raycast: function () {},

	traverse: function ( callback ) {

		callback( this );

M
Mr.doob 已提交
545 546 547
		var children = this.children;

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

M
Mr.doob 已提交
549
			children[ i ].traverse( callback );
550 551 552 553 554 555 556 557 558 559 560

		}

	},

	traverseVisible: function ( callback ) {

		if ( this.visible === false ) return;

		callback( this );

M
Mr.doob 已提交
561
		var children = this.children;
562

M
Mr.doob 已提交
563 564 565
		for ( var i = 0, l = children.length; i < l; i ++ ) {

			children[ i ].traverseVisible( callback );
566 567 568 569 570

		}

	},

U
unknown 已提交
571 572
	traverseAncestors: function ( callback ) {

M
Mr.doob 已提交
573 574
		var parent = this.parent;

575
		if ( parent !== null ) {
576

M
Mr.doob 已提交
577
			callback( parent );
U
unknown 已提交
578

M
Mr.doob 已提交
579
			parent.traverseAncestors( callback );
U
unknown 已提交
580

581
		}
U
unknown 已提交
582

583 584
	},

585 586 587 588 589 590 591 592 593 594
	updateMatrix: function () {

		this.matrix.compose( this.position, this.quaternion, this.scale );

		this.matrixWorldNeedsUpdate = true;

	},

	updateMatrixWorld: function ( force ) {

595
		if ( this.matrixAutoUpdate ) this.updateMatrix();
596

597
		if ( this.matrixWorldNeedsUpdate || force ) {
598

M
Mr.doob 已提交
599
			if ( this.parent === null ) {
600

M
Mr.doob 已提交
601
				this.matrixWorld.copy( this.matrix );
602 603 604

			} else {

M
Mr.doob 已提交
605
				this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
606 607 608 609 610 611 612 613 614 615 616

			}

			this.matrixWorldNeedsUpdate = false;

			force = true;

		}

		// update children

617 618 619
		var children = this.children;

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

621
			children[ i ].updateMatrixWorld( force );
622 623 624 625 626

		}

	},

627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
	updateWorldMatrix: function ( updateParents, updateChildren ) {

		var parent = this.parent;

		if ( updateParents === true && parent !== null ) {

			parent.updateWorldMatrix( true, false );

		}

		if ( this.matrixAutoUpdate ) this.updateMatrix();

		if ( this.parent === null ) {

			this.matrixWorld.copy( this.matrix );

		} else {

			this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );

		}

		// update children

		if ( updateChildren === true ) {

			var children = this.children;

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

				children[ i ].updateWorldMatrix( false, true );

			}

		}

	},

665
	toJSON: function ( meta ) {
E
elephantatwork 已提交
666

667 668
		// meta is a string when called from JSON.stringify
		var isRootObject = ( meta === undefined || typeof meta === 'string' );
669

M
Mr.doob 已提交
670
		var output = {};
671 672 673 674 675 676 677 678 679

		// meta is a hash used to collect geometries, materials.
		// not providing it implies that this is the root object
		// being serialized.
		if ( isRootObject ) {

			// initialize meta obj
			meta = {
				geometries: {},
E
elephantatwork 已提交
680
				materials: {},
681
				textures: {},
682 683
				images: {},
				shapes: {}
B
brason 已提交
684
			};
685

686
			output.metadata = {
M
Mr.doob 已提交
687
				version: 4.5,
688 689
				type: 'Object',
				generator: 'Object3D.toJSON'
690
			};
691

692
		}
693

694
		// standard Object3D serialization
695

M
Mr.doob 已提交
696 697 698 699 700 701 702 703 704
		var object = {};

		object.uuid = this.uuid;
		object.type = this.type;

		if ( this.name !== '' ) object.name = this.name;
		if ( this.castShadow === true ) object.castShadow = true;
		if ( this.receiveShadow === true ) object.receiveShadow = true;
		if ( this.visible === false ) object.visible = false;
705 706
		if ( this.frustumCulled === false ) object.frustumCulled = false;
		if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
707
		if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
M
Mr.doob 已提交
708

709
		object.layers = this.layers.mask;
M
Mr.doob 已提交
710 711
		object.matrix = this.matrix.toArray();

W
WestLangley 已提交
712 713
		if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;

714 715 716 717
		// object specific properties

		if ( this.isMesh && this.drawMode !== TrianglesDrawMode ) object.drawMode = this.drawMode;

M
Mr.doob 已提交
718 719
		//

M
Mr.doob 已提交
720
		function serialize( library, element ) {
721

722
			if ( library[ element.uuid ] === undefined ) {
723

724
				library[ element.uuid ] = element.toJSON( meta );
M
Mr.doob 已提交
725 726 727

			}

728 729 730 731
			return element.uuid;

		}

732
		if ( this.isMesh || this.isLine || this.isPoints ) {
733

M
Mr.doob 已提交
734
			object.geometry = serialize( meta.geometries, this.geometry );
M
Mr.doob 已提交
735

736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
			var parameters = this.geometry.parameters;

			if ( parameters !== undefined && parameters.shapes !== undefined ) {

				var shapes = parameters.shapes;

				if ( Array.isArray( shapes ) ) {

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

						var shape = shapes[ i ];

						serialize( meta.shapes, shape );

					}

				} else {

					serialize( meta.shapes, shapes );

				}

			}

M
Mr.doob 已提交
760 761 762 763
		}

		if ( this.material !== undefined ) {

764
			if ( Array.isArray( this.material ) ) {
M
Mr.doob 已提交
765

766
				var uuids = [];
M
Mr.doob 已提交
767

768
				for ( var i = 0, l = this.material.length; i < l; i ++ ) {
M
Mr.doob 已提交
769

M
Mr.doob 已提交
770
					uuids.push( serialize( meta.materials, this.material[ i ] ) );
771 772 773 774 775 776 777

				}

				object.material = uuids;

			} else {

M
Mr.doob 已提交
778
				object.material = serialize( meta.materials, this.material );
779 780

			}
M
Mr.doob 已提交
781 782 783 784

		}

		//
785

786
		if ( this.children.length > 0 ) {
787

M
Mr.doob 已提交
788
			object.children = [];
789

790
			for ( var i = 0; i < this.children.length; i ++ ) {
791

M
Mr.doob 已提交
792
				object.children.push( this.children[ i ].toJSON( meta ).object );
793

794
			}
795

796
		}
797

798
		if ( isRootObject ) {
M
Mr.doob 已提交
799

M
Mr.doob 已提交
800 801
			var geometries = extractFromCache( meta.geometries );
			var materials = extractFromCache( meta.materials );
802 803
			var textures = extractFromCache( meta.textures );
			var images = extractFromCache( meta.images );
804
			var shapes = extractFromCache( meta.shapes );
805

M
Mr.doob 已提交
806 807
			if ( geometries.length > 0 ) output.geometries = geometries;
			if ( materials.length > 0 ) output.materials = materials;
808 809
			if ( textures.length > 0 ) output.textures = textures;
			if ( images.length > 0 ) output.images = images;
810
			if ( shapes.length > 0 ) output.shapes = shapes;
811

812
		}
813

M
Mr.doob 已提交
814 815
		output.object = object;

816 817 818 819 820
		return output;

		// extract data from the cache hash
		// remove metadata on each item
		// and return as array
M
Mr.doob 已提交
821
		function extractFromCache( cache ) {
G
gero3 已提交
822

823 824
			var values = [];
			for ( var key in cache ) {
G
gero3 已提交
825

826 827 828
				var data = cache[ key ];
				delete data.metadata;
				values.push( data );
G
gero3 已提交
829

830 831
			}
			return values;
G
gero3 已提交
832

833
		}
834 835 836

	},

837 838
	clone: function ( recursive ) {

839
		return new this.constructor().copy( this, recursive );
840 841 842

	},

D
dubejf 已提交
843
	copy: function ( source, recursive ) {
844

M
Mr.doob 已提交
845
		if ( recursive === undefined ) recursive = true;
846

847
		this.name = source.name;
848

849
		this.up.copy( source.up );
850

851 852 853
		this.position.copy( source.position );
		this.quaternion.copy( source.quaternion );
		this.scale.copy( source.scale );
854

855 856
		this.matrix.copy( source.matrix );
		this.matrixWorld.copy( source.matrixWorld );
857

858 859
		this.matrixAutoUpdate = source.matrixAutoUpdate;
		this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
860

861
		this.layers.mask = source.layers.mask;
862
		this.visible = source.visible;
863

864 865
		this.castShadow = source.castShadow;
		this.receiveShadow = source.receiveShadow;
866

867 868
		this.frustumCulled = source.frustumCulled;
		this.renderOrder = source.renderOrder;
869

870
		this.userData = JSON.parse( JSON.stringify( source.userData ) );
M
Mr.doob 已提交
871

M
Mr.doob 已提交
872
		if ( recursive === true ) {
M
Mr.doob 已提交
873

874
			for ( var i = 0; i < source.children.length; i ++ ) {
M
Mr.doob 已提交
875

876 877
				var child = source.children[ i ];
				this.add( child.clone() );
M
Mr.doob 已提交
878 879

			}
880 881 882

		}

883
		return this;
884

885
	}
886

887
} );
M
Mr.doob 已提交
888

M
Mr.doob 已提交
889

890
export { Object3D };