Object3D.js 15.5 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';
R
Rich Harris 已提交
9

M
Mugen87 已提交
10
var _object3DId = 0;
11 12 13 14 15 16 17 18 19 20 21 22 23 24

var _v1 = new Vector3();
var _q1 = new Quaternion();
var _m1 = new Matrix4();
var _target = new Vector3();

var _position = new Vector3();
var _scale = new Vector3();
var _quaternion = new Quaternion();

var _xAxis = new Vector3( 1, 0, 0 );
var _yAxis = new Vector3( 0, 1, 0 );
var _zAxis = new Vector3( 0, 0, 1 );

25 26
var _addedEvent = { type: 'added' };
var _removedEvent = { type: 'removed' };
27

M
Mugen87 已提交
28 29 30 31 32 33 34 35
/**
 * @author mrdoob / http://mrdoob.com/
 * @author mikael emtinger / http://gomo.se/
 * @author alteredq / http://alteredqualia.com/
 * @author WestLangley / http://github.com/WestLangley
 * @author elephantatwork / www.elephantatwork.ch
 */

M
Mr.doob 已提交
36
function Object3D() {
37

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

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

42
	this.name = '';
43
	this.type = 'Object3D';
44

45
	this.parent = null;
46 47
	this.children = [];

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

R
Rich Harris 已提交
50
	var position = new Vector3();
51
	var rotation = new Euler();
R
Rich Harris 已提交
52 53
	var quaternion = new Quaternion();
	var scale = new Vector3( 1, 1, 1 );
54

M
Mr.doob 已提交
55
	function onRotationChange() {
G
gero3 已提交
56

57 58 59 60 61 62 63
		quaternion.setFromEuler( rotation, false );

	}

	function onQuaternionChange() {

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

M
Mr.doob 已提交
65
	}
M
Mr.doob 已提交
66

67 68
	rotation._onChange( onRotationChange );
	quaternion._onChange( onQuaternionChange );
69 70

	Object.defineProperties( this, {
71
		position: {
72
			configurable: true,
73
			enumerable: true,
74
			value: position
75
		},
76
		rotation: {
77
			configurable: true,
78
			enumerable: true,
79
			value: rotation
80 81
		},
		quaternion: {
82
			configurable: true,
83
			enumerable: true,
84
			value: quaternion
85 86
		},
		scale: {
87
			configurable: true,
88
			enumerable: true,
89
			value: scale
90 91
		},
		modelViewMatrix: {
R
Rich Harris 已提交
92
			value: new Matrix4()
93 94
		},
		normalMatrix: {
R
Rich Harris 已提交
95
			value: new Matrix3()
M
Mr.doob 已提交
96
		}
97
	} );
98

R
Rich Harris 已提交
99 100
	this.matrix = new Matrix4();
	this.matrixWorld = new Matrix4();
101

R
Rich Harris 已提交
102
	this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
103
	this.matrixWorldNeedsUpdate = false;
104

R
Rich Harris 已提交
105
	this.layers = new Layers();
106
	this.visible = true;
107

108 109 110
	this.castShadow = false;
	this.receiveShadow = false;

A
alteredq 已提交
111
	this.frustumCulled = true;
112
	this.renderOrder = 0;
A
alteredq 已提交
113

114
	this.userData = {};
M
Mugen87 已提交
115

M
Mr.doob 已提交
116
}
117

R
Rich Harris 已提交
118 119
Object3D.DefaultUp = new Vector3( 0, 1, 0 );
Object3D.DefaultMatrixAutoUpdate = true;
120

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

123
	constructor: Object3D,
M
Mr.doob 已提交
124

125 126
	isObject3D: true,

127 128 129
	onBeforeRender: function () {},
	onAfterRender: function () {},

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

W
WestLangley 已提交
132 133 134
		if ( this.matrixAutoUpdate ) this.updateMatrix();

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

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

W
WestLangley 已提交
138
	},
M
Mr.doob 已提交
139

W
WestLangley 已提交
140 141 142 143 144 145 146 147
	applyQuaternion: function ( q ) {

		this.quaternion.premultiply( q );

		return this;

	},

148 149 150 151 152 153 154 155 156 157
	setRotationFromAxisAngle: function ( axis, angle ) {

		// assumes axis is normalized

		this.quaternion.setFromAxisAngle( axis, angle );

	},

	setRotationFromEuler: function ( euler ) {

158
		this.quaternion.setFromEuler( euler, true );
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177

	},

	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 已提交
178
	rotateOnAxis: function ( axis, angle ) {
179

180 181 182
		// rotate object on axis in object space
		// axis is assumed to be normalized

M
Mugen87 已提交
183
		_q1.setFromAxisAngle( axis, angle );
184

M
Mugen87 已提交
185
		this.quaternion.multiply( _q1 );
186

M
Mugen87 已提交
187
		return this;
188

M
Mugen87 已提交
189
	},
190

M
Mugen87 已提交
191
	rotateOnWorldAxis: function ( axis, angle ) {
M
Mugen87 已提交
192

193 194 195 196
		// rotate object on axis in world space
		// axis is assumed to be normalized
		// method assumes no rotated parent

M
Mugen87 已提交
197
		_q1.setFromAxisAngle( axis, angle );
M
Mugen87 已提交
198

M
Mugen87 已提交
199
		this.quaternion.premultiply( _q1 );
M
Mugen87 已提交
200

M
Mugen87 已提交
201
		return this;
202

M
Mugen87 已提交
203
	},
204

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

M
Mugen87 已提交
207
		return this.rotateOnAxis( _xAxis, angle );
208

M
Mugen87 已提交
209
	},
210

M
Mugen87 已提交
211
	rotateY: function ( angle ) {
212

M
Mugen87 已提交
213
		return this.rotateOnAxis( _yAxis, angle );
214

M
Mugen87 已提交
215
	},
216

M
Mugen87 已提交
217
	rotateZ: function ( angle ) {
218

M
Mugen87 已提交
219
		return this.rotateOnAxis( _zAxis, angle );
220

M
Mugen87 已提交
221
	},
222

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

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

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
		return this.translateOnAxis( _xAxis, distance );
239

M
Mugen87 已提交
240
	},
241

M
Mugen87 已提交
242
	translateY: function ( distance ) {
243

M
Mugen87 已提交
244
		return this.translateOnAxis( _yAxis, distance );
245

M
Mugen87 已提交
246
	},
247

M
Mugen87 已提交
248
	translateZ: function ( distance ) {
249

M
Mugen87 已提交
250
		return this.translateOnAxis( _zAxis, distance );
251

M
Mugen87 已提交
252
	},
253

M
Mr.doob 已提交
254 255
	localToWorld: function ( vector ) {

256
		return vector.applyMatrix4( this.matrixWorld );
M
Mr.doob 已提交
257 258 259

	},

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

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

M
Mugen87 已提交
264
	},
265

M
Mugen87 已提交
266
	lookAt: function ( x, y, z ) {
267

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

M
Mugen87 已提交
270
		if ( x.isVector3 ) {
W
WestLangley 已提交
271

M
Mugen87 已提交
272
			_target.copy( x );
W
WestLangley 已提交
273

M
Mugen87 已提交
274
		} else {
W
WestLangley 已提交
275

M
Mugen87 已提交
276
			_target.set( x, y, z );
277

M
Mugen87 已提交
278
		}
279

M
Mugen87 已提交
280
		var parent = this.parent;
281

M
Mugen87 已提交
282
		this.updateWorldMatrix( true, false );
283

M
Mugen87 已提交
284
		_position.setFromMatrixPosition( this.matrixWorld );
285

M
Mugen87 已提交
286
		if ( this.isCamera || this.isLight ) {
287

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

M
Mugen87 已提交
290
		} else {
291

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

M
Mugen87 已提交
294
		}
295

M
Mugen87 已提交
296
		this.quaternion.setFromRotationMatrix( _m1 );
297

M
Mugen87 已提交
298
		if ( parent ) {
299

M
Mugen87 已提交
300 301 302
			_m1.extractRotation( parent.matrixWorld );
			_q1.setFromRotationMatrix( _m1 );
			this.quaternion.premultiply( _q1.inverse() );
303

M
Mugen87 已提交
304
		}
305

M
Mugen87 已提交
306
	},
307

308
	add: function ( object ) {
309

310 311
		if ( arguments.length > 1 ) {

G
gero3 已提交
312
			for ( var i = 0; i < arguments.length; i ++ ) {
313 314 315 316 317 318 319

				this.add( arguments[ i ] );

			}

			return this;

B
brason 已提交
320
		}
321

322 323
		if ( object === this ) {

324
			console.error( "THREE.Object3D.add: object can't be added as a child of itself.", object );
325
			return this;
326 327 328

		}

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

331
			if ( object.parent !== null ) {
A
alteredq 已提交
332

M
Mr.doob 已提交
333
				object.parent.remove( object );
334

A
alteredq 已提交
335 336
			}

337 338
			object.parent = this;
			this.children.push( object );
M
Mr.doob 已提交
339

340
			object.dispatchEvent( _addedEvent );
341

M
Mr.doob 已提交
342
		} else {
M
Mr.doob 已提交
343

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

346
		}
M
Mr.doob 已提交
347

348 349
		return this;

350
	},
351

352
	remove: function ( object ) {
353

354 355
		if ( arguments.length > 1 ) {

G
gero3 已提交
356
			for ( var i = 0; i < arguments.length; i ++ ) {
357 358 359 360 361

				this.remove( arguments[ i ] );

			}

0
06wj 已提交
362 363
			return this;

B
brason 已提交
364
		}
365

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

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

370
			object.parent = null;
371
			this.children.splice( index, 1 );
372

373
			object.dispatchEvent( _removedEvent );
374

M
Mr.doob 已提交
375
		}
376

0
06wj 已提交
377
		return this;
378

M
Mr.doob 已提交
379
	},
380

M
Mugen87 已提交
381
	attach: function ( object ) {
W
WestLangley 已提交
382 383 384

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

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

M
Mugen87 已提交
387
		_m1.getInverse( this.matrixWorld );
W
WestLangley 已提交
388

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

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

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

M
Mugen87 已提交
395
		}
W
WestLangley 已提交
396

M
Mugen87 已提交
397
		object.applyMatrix( _m1 );
W
WestLangley 已提交
398

M
Mugen87 已提交
399
		object.updateWorldMatrix( false, false );
W
WestLangley 已提交
400

M
Mugen87 已提交
401
		this.add( object );
W
WestLangley 已提交
402

M
Mugen87 已提交
403
		return this;
W
WestLangley 已提交
404

M
Mugen87 已提交
405
	},
W
WestLangley 已提交
406

407
	getObjectById: function ( id ) {
408

409
		return this.getObjectByProperty( 'id', id );
410

W
Wilt 已提交
411
	},
412

413
	getObjectByName: function ( name ) {
414

415
		return this.getObjectByProperty( 'name', name );
416 417

	},
M
Mr.doob 已提交
418

419
	getObjectByProperty: function ( name, value ) {
420

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

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

425
			var child = this.children[ i ];
426
			var object = child.getObjectByProperty( name, value );
M
Mr.doob 已提交
427

428
			if ( object !== undefined ) {
M
Mr.doob 已提交
429

430
				return object;
M
Mr.doob 已提交
431

432
			}
M
Mr.doob 已提交
433

434
		}
M
Mr.doob 已提交
435

436
		return undefined;
M
Mr.doob 已提交
437

438
	},
M
Mr.doob 已提交
439

W
WestLangley 已提交
440
	getWorldPosition: function ( target ) {
W
WestLangley 已提交
441

W
WestLangley 已提交
442 443 444 445 446 447
		if ( target === undefined ) {

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

		}
W
WestLangley 已提交
448 449 450

		this.updateMatrixWorld( true );

W
WestLangley 已提交
451
		return target.setFromMatrixPosition( this.matrixWorld );
W
WestLangley 已提交
452 453 454

	},

M
Mugen87 已提交
455
	getWorldQuaternion: function ( target ) {
W
WestLangley 已提交
456

M
Mugen87 已提交
457
		if ( target === undefined ) {
W
WestLangley 已提交
458

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

M
Mugen87 已提交
462
		}
W
WestLangley 已提交
463

M
Mugen87 已提交
464
		this.updateMatrixWorld( true );
W
WestLangley 已提交
465

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

M
Mugen87 已提交
468
		return target;
W
WestLangley 已提交
469

M
Mugen87 已提交
470
	},
W
WestLangley 已提交
471

M
Mugen87 已提交
472
	getWorldScale: function ( target ) {
W
WestLangley 已提交
473

M
Mugen87 已提交
474
		if ( target === undefined ) {
W
WestLangley 已提交
475

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

M
Mugen87 已提交
479
		}
W
WestLangley 已提交
480

M
Mugen87 已提交
481
		this.updateMatrixWorld( true );
W
WestLangley 已提交
482

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

M
Mugen87 已提交
485
		return target;
W
WestLangley 已提交
486

M
Mugen87 已提交
487
	},
W
WestLangley 已提交
488

M
mbredif 已提交
489
	getWorldDirection: function ( target ) {
W
WestLangley 已提交
490

M
mbredif 已提交
491
		if ( target === undefined ) {
W
WestLangley 已提交
492

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

M
mbredif 已提交
496
		}
W
WestLangley 已提交
497

M
mbredif 已提交
498
		this.updateMatrixWorld( true );
W
WestLangley 已提交
499

M
mbredif 已提交
500
		var e = this.matrixWorld.elements;
W
WestLangley 已提交
501

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

M
mbredif 已提交
504
	},
W
WestLangley 已提交
505

506 507 508 509 510 511
	raycast: function () {},

	traverse: function ( callback ) {

		callback( this );

M
Mr.doob 已提交
512 513 514
		var children = this.children;

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

M
Mr.doob 已提交
516
			children[ i ].traverse( callback );
517 518 519 520 521 522 523 524 525 526 527

		}

	},

	traverseVisible: function ( callback ) {

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

		callback( this );

M
Mr.doob 已提交
528
		var children = this.children;
529

M
Mr.doob 已提交
530 531 532
		for ( var i = 0, l = children.length; i < l; i ++ ) {

			children[ i ].traverseVisible( callback );
533 534 535 536 537

		}

	},

U
unknown 已提交
538 539
	traverseAncestors: function ( callback ) {

M
Mr.doob 已提交
540 541
		var parent = this.parent;

542
		if ( parent !== null ) {
543

M
Mr.doob 已提交
544
			callback( parent );
U
unknown 已提交
545

M
Mr.doob 已提交
546
			parent.traverseAncestors( callback );
U
unknown 已提交
547

548
		}
U
unknown 已提交
549

550 551
	},

552 553 554 555 556 557 558 559 560 561
	updateMatrix: function () {

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

		this.matrixWorldNeedsUpdate = true;

	},

	updateMatrixWorld: function ( force ) {

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

564
		if ( this.matrixWorldNeedsUpdate || force ) {
565

M
Mr.doob 已提交
566
			if ( this.parent === null ) {
567

M
Mr.doob 已提交
568
				this.matrixWorld.copy( this.matrix );
569 570 571

			} else {

M
Mr.doob 已提交
572
				this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
573 574 575 576 577 578 579 580 581 582 583

			}

			this.matrixWorldNeedsUpdate = false;

			force = true;

		}

		// update children

584 585 586
		var children = this.children;

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

588
			children[ i ].updateMatrixWorld( force );
589 590 591 592 593

		}

	},

594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631
	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 );

			}

		}

	},

632
	toJSON: function ( meta ) {
E
elephantatwork 已提交
633

634 635
		// meta is a string when called from JSON.stringify
		var isRootObject = ( meta === undefined || typeof meta === 'string' );
636

M
Mr.doob 已提交
637
		var output = {};
638 639 640 641 642 643 644 645 646

		// 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 已提交
647
				materials: {},
648
				textures: {},
649 650
				images: {},
				shapes: {}
B
brason 已提交
651
			};
652

653
			output.metadata = {
M
Mr.doob 已提交
654
				version: 4.5,
655 656
				type: 'Object',
				generator: 'Object3D.toJSON'
657
			};
658

659
		}
660

661
		// standard Object3D serialization
662

M
Mr.doob 已提交
663 664 665 666 667 668 669 670 671
		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;
672 673
		if ( this.frustumCulled === false ) object.frustumCulled = false;
		if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
674
		if ( JSON.stringify( this.userData ) !== '{}' ) object.userData = this.userData;
M
Mr.doob 已提交
675

676
		object.layers = this.layers.mask;
M
Mr.doob 已提交
677 678
		object.matrix = this.matrix.toArray();

W
WestLangley 已提交
679 680
		if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;

681 682
		// object specific properties

683 684 685 686 687 688 689 690
		if ( this.isInstancedMesh ) {

			object.type = 'InstancedMesh';
			object.count = this.count;
			object.instanceMatrix = this.instanceMatrix.toJSON();

		}

M
Mr.doob 已提交
691 692
		//

M
Mr.doob 已提交
693
		function serialize( library, element ) {
694

695
			if ( library[ element.uuid ] === undefined ) {
696

697
				library[ element.uuid ] = element.toJSON( meta );
M
Mr.doob 已提交
698 699 700

			}

701 702 703 704
			return element.uuid;

		}

705
		if ( this.isMesh || this.isLine || this.isPoints ) {
706

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

709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
			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 已提交
733 734 735 736
		}

		if ( this.material !== undefined ) {

737
			if ( Array.isArray( this.material ) ) {
M
Mr.doob 已提交
738

739
				var uuids = [];
M
Mr.doob 已提交
740

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

M
Mr.doob 已提交
743
					uuids.push( serialize( meta.materials, this.material[ i ] ) );
744 745 746 747 748 749 750

				}

				object.material = uuids;

			} else {

M
Mr.doob 已提交
751
				object.material = serialize( meta.materials, this.material );
752 753

			}
M
Mr.doob 已提交
754 755 756 757

		}

		//
758

759
		if ( this.children.length > 0 ) {
760

M
Mr.doob 已提交
761
			object.children = [];
762

763
			for ( var i = 0; i < this.children.length; i ++ ) {
764

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

767
			}
768

769
		}
770

771
		if ( isRootObject ) {
M
Mr.doob 已提交
772

M
Mr.doob 已提交
773 774
			var geometries = extractFromCache( meta.geometries );
			var materials = extractFromCache( meta.materials );
775 776
			var textures = extractFromCache( meta.textures );
			var images = extractFromCache( meta.images );
777
			var shapes = extractFromCache( meta.shapes );
778

M
Mr.doob 已提交
779 780
			if ( geometries.length > 0 ) output.geometries = geometries;
			if ( materials.length > 0 ) output.materials = materials;
781 782
			if ( textures.length > 0 ) output.textures = textures;
			if ( images.length > 0 ) output.images = images;
783
			if ( shapes.length > 0 ) output.shapes = shapes;
784

785
		}
786

M
Mr.doob 已提交
787 788
		output.object = object;

789 790 791 792 793
		return output;

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

796 797
			var values = [];
			for ( var key in cache ) {
G
gero3 已提交
798

799 800 801
				var data = cache[ key ];
				delete data.metadata;
				values.push( data );
G
gero3 已提交
802

803 804
			}
			return values;
G
gero3 已提交
805

806
		}
807 808 809

	},

810 811
	clone: function ( recursive ) {

812
		return new this.constructor().copy( this, recursive );
813 814 815

	},

D
dubejf 已提交
816
	copy: function ( source, recursive ) {
817

M
Mr.doob 已提交
818
		if ( recursive === undefined ) recursive = true;
819

820
		this.name = source.name;
821

822
		this.up.copy( source.up );
823

824 825 826
		this.position.copy( source.position );
		this.quaternion.copy( source.quaternion );
		this.scale.copy( source.scale );
827

828 829
		this.matrix.copy( source.matrix );
		this.matrixWorld.copy( source.matrixWorld );
830

831 832
		this.matrixAutoUpdate = source.matrixAutoUpdate;
		this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
833

834
		this.layers.mask = source.layers.mask;
835
		this.visible = source.visible;
836

837 838
		this.castShadow = source.castShadow;
		this.receiveShadow = source.receiveShadow;
839

840 841
		this.frustumCulled = source.frustumCulled;
		this.renderOrder = source.renderOrder;
842

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

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

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

849 850
				var child = source.children[ i ];
				this.add( child.clone() );
M
Mr.doob 已提交
851 852

			}
853 854 855

		}

856
		return this;
857

858
	}
859

860
} );
M
Mr.doob 已提交
861

M
Mr.doob 已提交
862

863
export { Object3D };