Geometry.js 8.7 KB
Newer Older
M
Mr.doob 已提交
1 2
/**
 * @author mr.doob / http://mrdoob.com/
M
Mr.doob 已提交
3
 * @author kile / http://kile.stravaganza.org/
M
Mr.doob 已提交
4
 * @author alteredq / http://alteredqualia.com/
5
 * @author mikael emtinger / http://gomo.se/
M
Mr.doob 已提交
6 7
 */

M
Mr.doob 已提交
8
THREE.Geometry = function () {
9

M
Mr.doob 已提交
10
	this.id = "Geometry" + THREE.GeometryIdCounter ++;
M
Mr.doob 已提交
11

M
Mr.doob 已提交
12 13
	this.vertices = [];
	this.faces = [];
14
	this.uvs = [];
15
	this.uvs2 = [];
A
alteredq 已提交
16
	this.colors = [];
17
	this.morphTargets = [];
M
Mr.doob 已提交
18

19 20
	this.skinWeights = [];
	this.skinIndices = [];
M
Mr.doob 已提交
21

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

25
	this.hasTangents = false;
26

M
Mr.doob 已提交
27 28 29 30
};

THREE.Geometry.prototype = {

M
Mr.doob 已提交
31 32 33 34
	computeCentroids: function () {

		var f, fl, face;

M
Mr.doob 已提交
35
		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
M
Mr.doob 已提交
36 37 38 39 40 41

			face = this.faces[ f ];
			face.centroid.set( 0, 0, 0 );

			if ( face instanceof THREE.Face3 ) {

M
Mr.doob 已提交
42 43 44
				face.centroid.addSelf( this.vertices[ face.a ].position );
				face.centroid.addSelf( this.vertices[ face.b ].position );
				face.centroid.addSelf( this.vertices[ face.c ].position );
M
Mr.doob 已提交
45 46 47 48
				face.centroid.divideScalar( 3 );

			} else if ( face instanceof THREE.Face4 ) {

M
Mr.doob 已提交
49 50 51
				face.centroid.addSelf( this.vertices[ face.a ].position );
				face.centroid.addSelf( this.vertices[ face.b ].position );
				face.centroid.addSelf( this.vertices[ face.c ].position );
M
Mr.doob 已提交
52 53 54 55 56 57 58 59 60
				face.centroid.addSelf( this.vertices[ face.d ].position );
				face.centroid.divideScalar( 4 );

			}

		}

	},

61
	computeFaceNormals: function ( useVertexNormals ) {
62

63 64
		var n, nl, v, vl, vertex, f, fl, face, vA, vB, vC,
		cb = new THREE.Vector3(), ab = new THREE.Vector3();
65

M
Mr.doob 已提交
66
		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
67

M
Mr.doob 已提交
68 69
			vertex = this.vertices[ v ];
			vertex.normal.set( 0, 0, 0 );
70 71 72

		}

M
Mr.doob 已提交
73
		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
74

M
Mr.doob 已提交
75
			face = this.faces[ f ];
76

77
			if ( useVertexNormals && face.vertexNormals.length  ) {
78

79
				cb.set( 0, 0, 0 );
80

81
				for ( n = 0, nl = face.vertexNormals.length; n < nl; n++ ) {
82

83
					cb.addSelf( face.vertexNormals[n] );
84

85
				}
U
unknown 已提交
86

87
				cb.divideScalar( 3 );
U
unknown 已提交
88

89
				if ( ! cb.isZero() ) {
U
unknown 已提交
90

91
					cb.normalize();
U
unknown 已提交
92

93
				}
U
unknown 已提交
94

95
				face.normal.copy( cb );
U
unknown 已提交
96

97
			} else {
98

99 100 101 102 103 104 105 106 107 108
				vA = this.vertices[ face.a ];
				vB = this.vertices[ face.b ];
				vC = this.vertices[ face.c ];

				cb.sub( vC.position, vB.position );
				ab.sub( vA.position, vB.position );
				cb.crossSelf( ab );

				if ( !cb.isZero() ) {

M
Mr.doob 已提交
109
					cb.normalize();
110 111 112 113 114 115 116 117 118 119 120

				}

				face.normal.copy( cb );

			}

		}

	},

121 122
	computeVertexNormals: function () {

123
		var v, vl, f, fl, face, vertices;
124

125 126
		// create internal buffers for reuse when calling this method repeatedly
		// (otherwise memory allocation / deallocation every frame is big resource hog)
M
Mr.doob 已提交
127

128
		if ( this.__tmpVertices == undefined ) {
M
Mr.doob 已提交
129

130 131
			this.__tmpVertices = new Array( this.vertices.length );
			vertices = this.__tmpVertices;
M
Mr.doob 已提交
132

133 134 135 136 137
			for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {

				vertices[ v ] = new THREE.Vector3();

			}
M
Mr.doob 已提交
138

139 140 141 142 143 144 145
			for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {

				face = this.faces[ f ];

				if ( face instanceof THREE.Face3 ) {

					face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];
M
Mr.doob 已提交
146

147
				} else if ( face instanceof THREE.Face4 ) {
M
Mr.doob 已提交
148

149 150 151 152 153
					face.vertexNormals = [ new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3() ];

				}

			}
M
Mr.doob 已提交
154

155
		} else {
M
Mr.doob 已提交
156

157
			vertices = this.__tmpVertices;
M
Mr.doob 已提交
158

159 160 161 162 163
			for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {

				vertices[ v ].set( 0, 0, 0 );

			}
M
Mr.doob 已提交
164

M
Mr.doob 已提交
165 166 167 168 169 170 171
		}

		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {

			face = this.faces[ f ];

			if ( face instanceof THREE.Face3 ) {
172

M
Mr.doob 已提交
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
				vertices[ face.a ].addSelf( face.normal );
				vertices[ face.b ].addSelf( face.normal );
				vertices[ face.c ].addSelf( face.normal );

			} else if ( face instanceof THREE.Face4 ) {

				vertices[ face.a ].addSelf( face.normal );
				vertices[ face.b ].addSelf( face.normal );
				vertices[ face.c ].addSelf( face.normal );
				vertices[ face.d ].addSelf( face.normal );

			}

		}

		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {

			vertices[ v ].normalize();

		}

		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {

			face = this.faces[ f ];

			if ( face instanceof THREE.Face3 ) {

200 201 202
				face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
				face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
				face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
M
Mr.doob 已提交
203 204 205

			} else if ( face instanceof THREE.Face4 ) {

206 207 208 209
				face.vertexNormals[ 0 ].copy( vertices[ face.a ] );
				face.vertexNormals[ 1 ].copy( vertices[ face.b ] );
				face.vertexNormals[ 2 ].copy( vertices[ face.c ] );
				face.vertexNormals[ 3 ].copy( vertices[ face.d ] );
M
Mr.doob 已提交
210 211

			}
212 213 214 215 216

		}

	},

217
	computeTangents: function () {
218

219 220
		// based on http://www.terathon.com/code/tangent.html
		// tangents go to vertices
221

222 223
		var f, fl, v, vl, face, uv, vA, vB, vC, uvA, uvB, uvC,
			x1, x2, y1, y2, z1, z2,
224
			s1, s2, t1, t2, r, t, test,
225 226
			tan1 = [], tan2 = [],
			sdir = new THREE.Vector3(), tdir = new THREE.Vector3(),
227
			tmp = new THREE.Vector3(), tmp2 = new THREE.Vector3(),
228
			n = new THREE.Vector3(), w;
229

230 231 232 233 234 235
		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {

			tan1[ v ] = new THREE.Vector3();
			tan2[ v ] = new THREE.Vector3();

		}
236

M
Mr.doob 已提交
237
		function handleTriangle( context, a, b, c, ua, ub, uc ) {
238

239 240 241
			vA = context.vertices[ a ].position;
			vB = context.vertices[ b ].position;
			vC = context.vertices[ c ].position;
242

M
Mr.doob 已提交
243 244 245
			uvA = uv[ ua ];
			uvB = uv[ ub ];
			uvC = uv[ uc ];
246

247 248 249 250 251 252 253 254 255 256 257 258 259
			x1 = vB.x - vA.x;
			x2 = vC.x - vA.x;
			y1 = vB.y - vA.y;
			y2 = vC.y - vA.y;
			z1 = vB.z - vA.z;
			z2 = vC.z - vA.z;

			s1 = uvB.u - uvA.u;
			s2 = uvC.u - uvA.u;
			t1 = uvB.v - uvA.v;
			t2 = uvC.v - uvA.v;

			r = 1.0 / ( s1 * t2 - s2 * t1 );
260
			sdir.set( ( t2 * x1 - t1 * x2 ) * r,
261 262
					  ( t2 * y1 - t1 * y2 ) * r,
					  ( t2 * z1 - t1 * z2 ) * r );
263
			tdir.set( ( s1 * x2 - s2 * x1 ) * r,
264 265
					  ( s1 * y2 - s2 * y1 ) * r,
					  ( s1 * z2 - s2 * z1 ) * r );
266

267 268 269
			tan1[ a ].addSelf( sdir );
			tan1[ b ].addSelf( sdir );
			tan1[ c ].addSelf( sdir );
270

271 272 273
			tan2[ a ].addSelf( tdir );
			tan2[ b ].addSelf( tdir );
			tan2[ c ].addSelf( tdir );
274

275
		}
276

277
		for ( f = 0, fl = this.faces.length; f < fl; f ++ ) {
278

279 280
			face = this.faces[ f ];
			uv = this.uvs[ f ];
281

282
			if ( face instanceof THREE.Face3 ) {
283

M
Mr.doob 已提交
284
				handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
285

286 287 288
				this.vertices[ face.a ].normal.copy( face.vertexNormals[ 0 ] );
				this.vertices[ face.b ].normal.copy( face.vertexNormals[ 1 ] );
				this.vertices[ face.c ].normal.copy( face.vertexNormals[ 2 ] );
289 290


291
			} else if ( face instanceof THREE.Face4 ) {
292

M
Mr.doob 已提交
293 294
				handleTriangle( this, face.a, face.b, face.c, 0, 1, 2 );
				handleTriangle( this, face.a, face.b, face.d, 0, 1, 3 );
295 296 297 298 299

				this.vertices[ face.a ].normal.copy( face.vertexNormals[ 0 ] );
				this.vertices[ face.b ].normal.copy( face.vertexNormals[ 1 ] );
				this.vertices[ face.c ].normal.copy( face.vertexNormals[ 2 ] );
				this.vertices[ face.d ].normal.copy( face.vertexNormals[ 3 ] );
300

301
			}
302

303
		}
304

305
		for ( v = 0, vl = this.vertices.length; v < vl; v ++ ) {
306

307 308
			n.copy( this.vertices[ v ].normal );
			t = tan1[ v ];
309

310
			// Gram-Schmidt orthogonalize
311

312 313
			tmp.copy( t );
			tmp.subSelf( n.multiplyScalar( n.dot( t ) ) ).normalize();
314

315
			// Calculate handedness
316

317 318 319
			tmp2.cross( this.vertices[ v ].normal, t );
			test = tmp2.dot( tan2[ v ] );
			w = (test < 0.0) ? -1.0 : 1.0;
320

321
			this.vertices[ v ].tangent.set( tmp.x, tmp.y, tmp.z, w );
322

323
		}
324

325
		this.hasTangents = true;
326

327
	},
328

329
	computeBoundingBox: function () {
330

331 332
		var vertex;

333 334
		if ( this.vertices.length > 0 ) {

M
Mr.doob 已提交
335
			this.boundingBox = { 'x': [ this.vertices[ 0 ].position.x, this.vertices[ 0 ].position.x ],
336
			'y': [ this.vertices[ 0 ].position.y, this.vertices[ 0 ].position.y ],
337 338
			'z': [ this.vertices[ 0 ].position.z, this.vertices[ 0 ].position.z ] };

M
Mr.doob 已提交
339
			for ( var v = 1, vl = this.vertices.length; v < vl; v ++ ) {
340 341 342

				vertex = this.vertices[ v ];

M
Mr.doob 已提交
343
				if ( vertex.position.x < this.boundingBox.x[ 0 ] ) {
344

M
Mr.doob 已提交
345
					this.boundingBox.x[ 0 ] = vertex.position.x;
346

M
Mr.doob 已提交
347
				} else if ( vertex.position.x > this.boundingBox.x[ 1 ] ) {
348

M
Mr.doob 已提交
349
					this.boundingBox.x[ 1 ] = vertex.position.x;
350 351 352

				}

M
Mr.doob 已提交
353
				if ( vertex.position.y < this.boundingBox.y[ 0 ] ) {
354

M
Mr.doob 已提交
355
					this.boundingBox.y[ 0 ] = vertex.position.y;
356

M
Mr.doob 已提交
357
				} else if ( vertex.position.y > this.boundingBox.y[ 1 ] ) {
358

M
Mr.doob 已提交
359
					this.boundingBox.y[ 1 ] = vertex.position.y;
360 361 362

				}

M
Mr.doob 已提交
363
				if ( vertex.position.z < this.boundingBox.z[ 0 ] ) {
364

M
Mr.doob 已提交
365
					this.boundingBox.z[ 0 ] = vertex.position.z;
366

M
Mr.doob 已提交
367
				} else if ( vertex.position.z > this.boundingBox.z[ 1 ] ) {
368

M
Mr.doob 已提交
369
					this.boundingBox.z[ 1 ] = vertex.position.z;
370 371 372 373

				}

			}
374 375 376

		}

M
Mr.doob 已提交
377 378
	},

379 380 381 382 383 384 385 386 387 388 389 390
	computeBoundingSphere: function () {

		var radius = this.boundingSphere === null ? 0 : this.boundingSphere.radius;

		for ( var v = 0, vl = this.vertices.length; v < vl; v ++ ) {

			radius = Math.max( radius, this.vertices[ v ].position.length() );

		}

		this.boundingSphere = { radius: radius };

M
Mr.doob 已提交
391
	}
392

M
Mr.doob 已提交
393
};
394 395

THREE.GeometryIdCounter = 0;