BufferGeometry.js 18.9 KB
Newer Older
1 2
/**
 * @author alteredq / http://alteredqualia.com/
3
 * @author mrdoob / http://mrdoob.com/
4 5 6 7
 */

THREE.BufferGeometry = function () {

M
Mr.doob 已提交
8 9
	Object.defineProperty( this, 'id', { value: THREE.GeometryIdCount ++ } );

10
	this.uuid = THREE.Math.generateUUID();
11

M
Mr.doob 已提交
12
	this.name = '';
13
	this.type = 'BufferGeometry';
M
Mr.doob 已提交
14

15
	this.index = null;
16
	this.attributes = {};
17

18
	this.morphAttributes = {};
19

20
	this.groups = [];
21

22 23 24
	this.boundingBox = null;
	this.boundingSphere = null;

25 26
	this.drawRange = { start: 0, count: Infinity };

27 28 29 30
};

THREE.BufferGeometry.prototype = {

31
	constructor: THREE.BufferGeometry,
32

33
	addIndex: function ( index ) {
34

35 36 37 38 39 40 41 42 43 44 45 46 47 48
		console.warn( 'THREE.BufferGeometry: .addIndex() has been renamed to .setIndex().' );
		this.setIndex( index );

	},

	getIndex: function () {

		return this.index;

	},

	setIndex: function ( index ) {

		this.index = index;
49 50 51

	},

M
Mr.doob 已提交
52
	addAttribute: function ( name, attribute ) {
53

M
Mr.doob 已提交
54
		if ( attribute instanceof THREE.BufferAttribute === false && attribute instanceof THREE.InterleavedBufferAttribute === false ) {
55

56
			console.warn( 'THREE.BufferGeometry: .addAttribute() now expects ( name, attribute ).' );
57

58
			this.addAttribute( name, new THREE.BufferAttribute( arguments[ 1 ], arguments[ 2 ] ) );
59 60 61 62 63

			return;

		}

64
		if ( name === 'index' ) {
M
Mr.doob 已提交
65

66
			console.warn( 'THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute.' );
67
			this.setIndex( attribute );
M
Mr.doob 已提交
68

69 70
			return;

M
Mr.doob 已提交
71 72
		}

M
Mr.doob 已提交
73
		this.attributes[ name ] = attribute;
74

M
Mr.doob 已提交
75 76 77 78
	},

	getAttribute: function ( name ) {

79 80
		return this.attributes[ name ];

81 82
	},

83 84 85 86 87 88
	removeAttribute: function ( name ) {

		delete this.attributes[ name ];

	},

89 90 91 92 93 94 95
	get drawcalls() {

		console.error( 'THREE.BufferGeometry: .drawcalls has been renamed to .groups.' );
		return this.groups;

	},

96
	get offsets() {
97

98 99
		console.warn( 'THREE.BufferGeometry: .offsets has been renamed to .groups.' );
		return this.groups;
100 101 102

	},

M
Mr.doob 已提交
103 104
	addDrawCall: function ( start, count, indexOffset ) {

105 106 107 108 109 110
		if ( indexOffset !== undefined ) {

			console.warn( 'THREE.BufferGeometry: .addDrawCall() no longer supports indexOffset.' );

		}

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
		console.warn( 'THREE.BufferGeometry: .addDrawCall() is now .addGroup().' );
		this.addGroup( start, count );

	},

	clearDrawCalls: function () {

		console.warn( 'THREE.BufferGeometry: .clearDrawCalls() is now .clearGroups().' );
		this.clearGroups();

	},

	addGroup: function ( start, count, materialIndex ) {

		this.groups.push( {
M
Mr.doob 已提交
126 127

			start: start,
128 129
			count: count,
			materialIndex: materialIndex !== undefined ? materialIndex : 0
M
Mr.doob 已提交
130 131 132 133 134

		} );

	},

135
	clearGroups: function () {
D
dubejf 已提交
136

137
		this.groups = [];
D
dubejf 已提交
138 139 140

	},

141 142 143 144 145 146 147
	setDrawRange: function ( start, count ) {

		this.drawRange.start = start;
		this.drawRange.count = count;

	},

148 149
	applyMatrix: function ( matrix ) {

M
Mr.doob 已提交
150
		var position = this.attributes.position;
151

M
Mr.doob 已提交
152
		if ( position !== undefined ) {
153

154
			matrix.applyToVector3Array( position.array );
M
Mr.doob 已提交
155
			position.needsUpdate = true;
156 157 158

		}

M
Mr.doob 已提交
159
		var normal = this.attributes.normal;
160

M
Mr.doob 已提交
161
		if ( normal !== undefined ) {
162

M
Mr.doob 已提交
163
			var normalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
164

165
			normalMatrix.applyToVector3Array( normal.array );
M
Mr.doob 已提交
166
			normal.needsUpdate = true;
167 168 169

		}

M
Mr.doob 已提交
170
		if ( this.boundingBox !== null ) {
171 172 173 174 175

			this.computeBoundingBox();

		}

M
Mr.doob 已提交
176
		if ( this.boundingSphere !== null ) {
177 178 179 180 181

			this.computeBoundingSphere();

		}

182 183
	},

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
	rotateX: function () {

		// rotate geometry around world x-axis

		var m1;

		return function rotateX( angle ) {

			if ( m1 === undefined ) m1 = new THREE.Matrix4();

			m1.makeRotationX( angle );

			this.applyMatrix( m1 );

			return this;

		};

	}(),

	rotateY: function () {

		// rotate geometry around world y-axis

		var m1;

		return function rotateY( angle ) {

			if ( m1 === undefined ) m1 = new THREE.Matrix4();

			m1.makeRotationY( angle );

			this.applyMatrix( m1 );

			return this;

		};

	}(),

	rotateZ: function () {

		// rotate geometry around world z-axis

		var m1;

		return function rotateZ( angle ) {

			if ( m1 === undefined ) m1 = new THREE.Matrix4();

			m1.makeRotationZ( angle );

			this.applyMatrix( m1 );

			return this;

		};

	}(),

	translate: function () {

		// translate geometry

		var m1;

		return function translate( x, y, z ) {

			if ( m1 === undefined ) m1 = new THREE.Matrix4();

			m1.makeTranslation( x, y, z );

			this.applyMatrix( m1 );

			return this;

		};

	}(),

	scale: function () {

		// scale geometry

		var m1;

		return function scale( x, y, z ) {

			if ( m1 === undefined ) m1 = new THREE.Matrix4();

			m1.makeScale( x, y, z );

			this.applyMatrix( m1 );

			return this;

		};

	}(),

	lookAt: function () {

		var obj;

		return function lookAt( vector ) {

			if ( obj === undefined ) obj = new THREE.Object3D();

			obj.lookAt( vector );

			obj.updateMatrix();

			this.applyMatrix( obj.matrix );

		};

	}(),

302 303
	center: function () {

M
Mr.doob 已提交
304 305 306 307
		this.computeBoundingBox();

		var offset = this.boundingBox.center().negate();

308
		this.translate( offset.x, offset.y, offset.z );
M
Mr.doob 已提交
309 310

		return offset;
311 312 313

	},

314
	setFromObject: function ( object ) {
315

316
		// console.log( 'THREE.BufferGeometry.setFromObject(). Converting', object, this );
317

318 319
		var geometry = object.geometry;

320
		if ( object instanceof THREE.Points || object instanceof THREE.Line ) {
321

322 323
			var positions = new THREE.Float32Attribute( geometry.vertices.length * 3, 3 );
			var colors = new THREE.Float32Attribute( geometry.colors.length * 3, 3 );
324

325 326
			this.addAttribute( 'position', positions.copyVector3sArray( geometry.vertices ) );
			this.addAttribute( 'color', colors.copyColorsArray( geometry.colors ) );
327

C
Chen Pang 已提交
328 329 330 331
			if ( geometry.lineDistances && geometry.lineDistances.length === geometry.vertices.length ) {

				var lineDistances = new THREE.Float32Attribute( geometry.lineDistances.length, 1 );

332
				this.addAttribute( 'lineDistance', lineDistances.copyArray( geometry.lineDistances ) );
C
Chen Pang 已提交
333 334 335

			}

336 337 338 339 340 341 342 343 344 345 346
			if ( geometry.boundingSphere !== null ) {

				this.boundingSphere = geometry.boundingSphere.clone();

			}

			if ( geometry.boundingBox !== null ) {

				this.boundingBox = geometry.boundingBox.clone();

			}
347 348 349

		} else if ( object instanceof THREE.Mesh ) {

M
Mr.doob 已提交
350
			if ( geometry instanceof THREE.Geometry ) {
351 352

				this.fromGeometry( geometry );
353

M
Mr.doob 已提交
354
			}
355 356 357 358 359 360 361

		}

		return this;

	},

362 363
	updateFromObject: function ( object ) {

M
Mr.doob 已提交
364
		var geometry = object.geometry;
365

M
Mr.doob 已提交
366
		if ( object instanceof THREE.Mesh ) {
367

M
Mr.doob 已提交
368
			var direct = geometry.__directGeometry;
369

370 371 372 373 374 375
			if ( direct === undefined ) {

				return this.fromGeometry( geometry );

			}

M
Mr.doob 已提交
376 377 378 379
			direct.verticesNeedUpdate = geometry.verticesNeedUpdate;
			direct.normalsNeedUpdate = geometry.normalsNeedUpdate;
			direct.colorsNeedUpdate = geometry.colorsNeedUpdate;
			direct.uvsNeedUpdate = geometry.uvsNeedUpdate;
380
			direct.groupsNeedUpdate = geometry.groupsNeedUpdate;
M
Mr.doob 已提交
381 382 383 384 385

			geometry.verticesNeedUpdate = false;
			geometry.normalsNeedUpdate = false;
			geometry.colorsNeedUpdate = false;
			geometry.uvsNeedUpdate = false;
386
			geometry.groupsNeedUpdate = false;
387

M
Mr.doob 已提交
388
			geometry = direct;
389 390

		}
391

M
Mr.doob 已提交
392
		if ( geometry.verticesNeedUpdate === true ) {
393

M
Mr.doob 已提交
394
			var attribute = this.attributes.position;
395

M
Mr.doob 已提交
396
			if ( attribute !== undefined ) {
397

M
Mr.doob 已提交
398 399
				attribute.copyVector3sArray( geometry.vertices );
				attribute.needsUpdate = true;
400 401 402

			}

M
Mr.doob 已提交
403
			geometry.verticesNeedUpdate = false;
404

M
Mr.doob 已提交
405
		}
406

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
		if ( geometry.normalsNeedUpdate === true ) {

			var attribute = this.attributes.normal;

			if ( attribute !== undefined ) {

				attribute.copyVector3sArray( geometry.normals );
				attribute.needsUpdate = true;

			}

			geometry.normalsNeedUpdate = false;

		}

M
Mr.doob 已提交
422
		if ( geometry.colorsNeedUpdate === true ) {
423

M
Mr.doob 已提交
424
			var attribute = this.attributes.color;
425

M
Mr.doob 已提交
426
			if ( attribute !== undefined ) {
427

M
Mr.doob 已提交
428 429
				attribute.copyColorsArray( geometry.colors );
				attribute.needsUpdate = true;
430 431 432

			}

M
Mr.doob 已提交
433 434
			geometry.colorsNeedUpdate = false;

435
		}
436

437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
		if ( geometry.uvsNeedUpdate ) {

				var attribute = this.attributes.uv;

				if ( attribute !== undefined ) {

						attribute.copyVector2sArray( geometry.uvs );
						attribute.needsUpdate = true;

				}

				geometry.uvsNeedUpdate = false;

		}

C
Chen Pang 已提交
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
		if ( geometry.lineDistancesNeedUpdate ) {

			var attribute = this.attributes.lineDistance;

			if ( attribute !== undefined ) {

				attribute.copyArray( geometry.lineDistances );
				attribute.needsUpdate = true;

			}

			geometry.lineDistancesNeedUpdate = false;

		}

467 468 469 470 471 472 473 474 475
		if ( geometry.groupsNeedUpdate ) {

			geometry.computeGroups( object.geometry );
			this.groups = geometry.groups;

			geometry.groupsNeedUpdate = false;

		}

476
		return this;
477 478 479

	},

480
	fromGeometry: function ( geometry ) {
481

482
		geometry.__directGeometry = new THREE.DirectGeometry().fromGeometry( geometry );
483 484

		return this.fromDirectGeometry( geometry.__directGeometry );
485

486
	},
487

488
	fromDirectGeometry: function ( geometry ) {
489

490 491
		var positions = new Float32Array( geometry.vertices.length * 3 );
		this.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ).copyVector3sArray( geometry.vertices ) );
492

493 494 495 496 497 498 499 500
		if ( geometry.normals.length > 0 ) {

			var normals = new Float32Array( geometry.normals.length * 3 );
			this.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ).copyVector3sArray( geometry.normals ) );

		}

		if ( geometry.colors.length > 0 ) {
M
Mr.doob 已提交
501

502
			var colors = new Float32Array( geometry.colors.length * 3 );
503
			this.addAttribute( 'color', new THREE.BufferAttribute( colors, 3 ).copyColorsArray( geometry.colors ) );
M
Mr.doob 已提交
504

505 506 507 508 509 510 511 512
		}

		if ( geometry.uvs.length > 0 ) {

			var uvs = new Float32Array( geometry.uvs.length * 2 );
			this.addAttribute( 'uv', new THREE.BufferAttribute( uvs, 2 ).copyVector2sArray( geometry.uvs ) );

		}
M
Mr.doob 已提交
513

514 515 516 517 518 519 520
		if ( geometry.uvs2.length > 0 ) {

			var uvs2 = new Float32Array( geometry.uvs2.length * 2 );
			this.addAttribute( 'uv2', new THREE.BufferAttribute( uvs2, 2 ).copyVector2sArray( geometry.uvs2 ) );

		}

521 522
		if ( geometry.indices.length > 0 ) {

M
Mr.doob 已提交
523 524
			var TypeArray = geometry.vertices.length > 65535 ? Uint32Array : Uint16Array;
			var indices = new TypeArray( geometry.indices.length * 3 );
525
			this.setIndex( new THREE.BufferAttribute( indices, 1 ).copyIndicesArray( geometry.indices ) );
526 527 528

		}

529 530 531 532
		// groups

		this.groups = geometry.groups;

533 534
		// morphs

535
		for ( var name in geometry.morphTargets ) {
536

537 538
			var array = [];
			var morphTargets = geometry.morphTargets[ name ];
539 540 541 542 543 544 545

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

				var morphTarget = morphTargets[ i ];

				var attribute = new THREE.Float32Attribute( morphTarget.length * 3, 3 );

546
				array.push( attribute.copyVector3sArray( morphTarget ) );
547 548 549

			}

550
			this.morphAttributes[ name ] = array;
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571

		}

		// skinning

		if ( geometry.skinIndices.length > 0 ) {

			var skinIndices = new THREE.Float32Attribute( geometry.skinIndices.length * 4, 4 );
			this.addAttribute( 'skinIndex', skinIndices.copyVector4sArray( geometry.skinIndices ) );

		}

		if ( geometry.skinWeights.length > 0 ) {

			var skinWeights = new THREE.Float32Attribute( geometry.skinWeights.length * 4, 4 );
			this.addAttribute( 'skinWeight', skinWeights.copyVector4sArray( geometry.skinWeights ) );

		}

		//

572 573 574 575 576 577 578 579 580 581 582
		if ( geometry.boundingSphere !== null ) {

			this.boundingSphere = geometry.boundingSphere.clone();

		}

		if ( geometry.boundingBox !== null ) {

			this.boundingBox = geometry.boundingBox.clone();

		}
M
Mr.doob 已提交
583 584 585 586 587

		return this;

	},

588 589
	computeBoundingBox: function () {

590
		var vector = new THREE.Vector3();
591

592
		return function () {
593

594
			if ( this.boundingBox === null ) {
595

596
				this.boundingBox = new THREE.Box3();
597

598 599
			}

600
			var positions = this.attributes.position.array;
601

602
			if ( positions ) {
603

604 605
				var bb = this.boundingBox;
				bb.makeEmpty();
606

607
				for ( var i = 0, il = positions.length; i < il; i += 3 ) {
608

609
					vector.fromArray( positions, i );
610
					bb.expandByPoint( vector );
611 612 613 614 615

				}

			}

616
			if ( positions === undefined || positions.length === 0 ) {
617

618 619
				this.boundingBox.min.set( 0, 0, 0 );
				this.boundingBox.max.set( 0, 0, 0 );
620

621
			}
622

623
			if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
624

625
				console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
626

627
			}
628

G
Greg French 已提交
629
		};
630

631
	}(),
632 633 634

	computeBoundingSphere: function () {

635 636
		var box = new THREE.Box3();
		var vector = new THREE.Vector3();
637

638
		return function () {
639

640
			if ( this.boundingSphere === null ) {
641

642
				this.boundingSphere = new THREE.Sphere();
643

644
			}
645

646
			var positions = this.attributes.position.array;
647

648
			if ( positions ) {
649

650 651
				box.makeEmpty();

652
				var center = this.boundingSphere.center;
653

654
				for ( var i = 0, il = positions.length; i < il; i += 3 ) {
655

656
					vector.fromArray( positions, i );
J
Jan Wrobel 已提交
657
					box.expandByPoint( vector );
658 659 660 661 662

				}

				box.center( center );

663
				// hoping to find a boundingSphere with a radius smaller than the
M
Mr.doob 已提交
664
				// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
665

666 667
				var maxRadiusSq = 0;

668
				for ( var i = 0, il = positions.length; i < il; i += 3 ) {
669

670
					vector.fromArray( positions, i );
671
					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
672

673 674 675 676
				}

				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );

677 678
				if ( isNaN( this.boundingSphere.radius ) ) {

679
					console.error( 'THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this );
680 681 682

				}

683
			}
684

G
Greg French 已提交
685
		};
686

687
	}(),
688

689 690 691 692 693 694
	computeFaceNormals: function () {

		// backwards compatibility

	},

695 696
	computeVertexNormals: function () {

697
		var index = this.index;
698
		var attributes = this.attributes;
699
		var groups = this.groups;
700

701
		if ( attributes.position ) {
702

703
			var positions = attributes.position.array;
704

705
			if ( attributes.normal === undefined ) {
706

707
				this.addAttribute( 'normal', new THREE.BufferAttribute( new Float32Array( positions.length ), 3 ) );
708 709 710 711 712

			} else {

				// reset existing normals to zero

713 714 715
				var normals = attributes.normal.array;

				for ( var i = 0, il = normals.length; i < il; i ++ ) {
716

717
					normals[ i ] = 0;
718 719 720 721 722

				}

			}

723
			var normals = attributes.normal.array;
724

M
Mr.doob 已提交
725
			var vA, vB, vC,
726 727 728 729 730 731 732 733

			pA = new THREE.Vector3(),
			pB = new THREE.Vector3(),
			pC = new THREE.Vector3(),

			cb = new THREE.Vector3(),
			ab = new THREE.Vector3();

734 735
			// indexed elements

736
			if ( index ) {
737

738
				var indices = index.array;
739

740
				if ( groups.length === 0 ) {
D
dubejf 已提交
741

742
					this.addGroup( 0, indices.length );
743

D
dubejf 已提交
744 745
				}

746
				for ( var j = 0, jl = groups.length; j < jl; ++ j ) {
747

748
					var group = groups[ j ];
749

750 751
					var start = group.start;
					var count = group.count;
752

753
					for ( var i = start, il = start + count; i < il; i += 3 ) {
754

755 756 757
						vA = indices[ i + 0 ] * 3;
						vB = indices[ i + 1 ] * 3;
						vC = indices[ i + 2 ] * 3;
758

M
Mr.doob 已提交
759 760 761
						pA.fromArray( positions, vA );
						pB.fromArray( positions, vB );
						pC.fromArray( positions, vC );
762

763 764 765
						cb.subVectors( pC, pB );
						ab.subVectors( pA, pB );
						cb.cross( ab );
766

G
gero3 已提交
767
						normals[ vA ] += cb.x;
M
Mr.doob 已提交
768 769
						normals[ vA + 1 ] += cb.y;
						normals[ vA + 2 ] += cb.z;
770

G
gero3 已提交
771
						normals[ vB ] += cb.x;
M
Mr.doob 已提交
772 773
						normals[ vB + 1 ] += cb.y;
						normals[ vB + 2 ] += cb.z;
774

G
gero3 已提交
775
						normals[ vC ] += cb.x;
M
Mr.doob 已提交
776 777
						normals[ vC + 1 ] += cb.y;
						normals[ vC + 2 ] += cb.z;
778 779 780 781 782 783

					}

				}

			} else {
784

785 786 787
				// non-indexed elements (unconnected triangle soup)

				for ( var i = 0, il = positions.length; i < il; i += 9 ) {
788

M
Mr.doob 已提交
789 790 791
					pA.fromArray( positions, i );
					pB.fromArray( positions, i + 3 );
					pC.fromArray( positions, i + 6 );
792

793 794 795
					cb.subVectors( pC, pB );
					ab.subVectors( pA, pB );
					cb.cross( ab );
796

G
gero3 已提交
797
					normals[ i ] = cb.x;
798 799
					normals[ i + 1 ] = cb.y;
					normals[ i + 2 ] = cb.z;
800

801 802 803
					normals[ i + 3 ] = cb.x;
					normals[ i + 4 ] = cb.y;
					normals[ i + 5 ] = cb.z;
804

805 806 807
					normals[ i + 6 ] = cb.x;
					normals[ i + 7 ] = cb.y;
					normals[ i + 8 ] = cb.z;
808 809 810 811 812

				}

			}

813
			this.normalizeNormals();
814

815
			attributes.normal.needsUpdate = true;
816

817
		}
818

819
	},
820

821 822
	computeTangents: function () {

M
Mr.doob 已提交
823
		console.warn( 'THREE.BufferGeometry: .computeTangents() has been removed.' );
824

825 826
	},

M
Mr.doob 已提交
827
	computeOffsets: function ( size ) {
828

829
		console.warn( 'THREE.BufferGeometry: .computeOffsets() has been removed.')
830 831 832

	},

833 834 835 836
	merge: function ( geometry, offset ) {

		if ( geometry instanceof THREE.BufferGeometry === false ) {

837
			console.error( 'THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry );
838 839 840 841 842 843 844 845 846 847 848
			return;

		}

		if ( offset === undefined ) offset = 0;

		var attributes = this.attributes;

		for ( var key in attributes ) {

			if ( geometry.attributes[ key ] === undefined ) continue;
849

850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
			var attribute1 = attributes[ key ];
			var attributeArray1 = attribute1.array;

			var attribute2 = geometry.attributes[ key ];
			var attributeArray2 = attribute2.array;

			var attributeSize = attribute2.itemSize;

			for ( var i = 0, j = attributeSize * offset; i < attributeArray2.length; i ++, j ++ ) {

				attributeArray1[ j ] = attributeArray2[ i ];

			}

		}

		return this;
867 868 869 870 871

	},

	normalizeNormals: function () {

872
		var normals = this.attributes.normal.array;
873 874 875 876 877 878 879 880 881 882 883

		var x, y, z, n;

		for ( var i = 0, il = normals.length; i < il; i += 3 ) {

			x = normals[ i ];
			y = normals[ i + 1 ];
			z = normals[ i + 2 ];

			n = 1.0 / Math.sqrt( x * x + y * y + z * z );

G
gero3 已提交
884
			normals[ i ] *= n;
885 886 887 888 889 890 891
			normals[ i + 1 ] *= n;
			normals[ i + 2 ] *= n;

		}

	},

892
	toJSON: function () {
893

894 895 896 897 898 899
		var data = {
			metadata: {
				version: 4.4,
				type: 'BufferGeometry',
				generator: 'BufferGeometry.toJSON'
			}
B
brason 已提交
900
		};
901

902
		// standard BufferGeometry serialization
903

904
		data.uuid = this.uuid;
M
Mr.doob 已提交
905
		data.type = this.type;
906
		if ( this.name !== '' ) data.name = this.name;
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922

		if ( this.parameters !== undefined ) {

			var parameters = this.parameters;

			for ( var key in parameters ) {

				if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ];

			}

			return data;

		}

		data.data = { attributes: {} };
923

M
Mr.doob 已提交
924
		var index = this.index;
925

M
Mr.doob 已提交
926 927 928 929 930 931 932 933 934 935 936 937
		if ( index !== null ) {

			var array = Array.prototype.slice.call( index.array );

			data.data.index = {
				type: index.array.constructor.name,
				array: array
			};

		}

		var attributes = this.attributes;
938 939 940 941 942

		for ( var key in attributes ) {

			var attribute = attributes[ key ];

M
makc 已提交
943
			var array = Array.prototype.slice.call( attribute.array );
944

945
			data.data.attributes[ key ] = {
946 947 948
				itemSize: attribute.itemSize,
				type: attribute.array.constructor.name,
				array: array
949
			};
950 951 952

		}

M
Mr.doob 已提交
953 954
		var groups = this.groups;

955
		if ( groups.length > 0 ) {
956

957
			data.data.groups = JSON.parse( JSON.stringify( groups ) );
958 959 960

		}

M
Mr.doob 已提交
961 962
		var boundingSphere = this.boundingSphere;

963 964
		if ( boundingSphere !== null ) {

965
			data.data.boundingSphere = {
966 967
				center: boundingSphere.center.toArray(),
				radius: boundingSphere.radius
968
			};
969 970 971

		}

972
		return data;
973 974 975

	},

M
Mr.doob 已提交
976
	clone: function () {
O
ohmed 已提交
977

978
		return new this.constructor().copy( this );
O
ohmed 已提交
979

D
dubejf 已提交
980 981 982
	},

	copy: function ( source ) {
O
ohmed 已提交
983

984 985 986 987
		var index = source.index;

		if ( index !== null ) {

988
			this.setIndex( index.clone() );
989 990 991

		}

M
Mr.doob 已提交
992
		var attributes = source.attributes;
O
ohmed 已提交
993

M
Mr.doob 已提交
994
		for ( var name in attributes ) {
O
ohmed 已提交
995

M
Mr.doob 已提交
996 997
			var attribute = attributes[ name ];
			this.addAttribute( name, attribute.clone() );
O
ohmed 已提交
998

M
Mr.doob 已提交
999
		}
O
ohmed 已提交
1000

1001 1002
		var groups = source.groups;

1003 1004 1005
		for ( var i = 0, l = groups.length; i < l; i ++ ) {

			var group = groups[ i ];
M
Mr.doob 已提交
1006
			this.addGroup( group.start, group.count );
O
ohmed 已提交
1007

O
ohmed 已提交
1008
		}
O
ohmed 已提交
1009

1010
		return this;
O
ohmed 已提交
1011 1012 1013

	},

1014
	dispose: function () {
1015

1016
		this.dispatchEvent( { type: 'dispose' } );
1017

1018
	}
1019 1020

};
M
Mr.doob 已提交
1021 1022

THREE.EventDispatcher.prototype.apply( THREE.BufferGeometry.prototype );
1023

1024
THREE.BufferGeometry.MaxIndex = 65535;