Geometry.js 8.6 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 = [];
M
Mr.doob 已提交
17

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

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

24
	this.hasTangents = false;
25

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

THREE.Geometry.prototype = {

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

		var f, fl, face;

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

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

			if ( face instanceof THREE.Face3 ) {

M
Mr.doob 已提交
41 42 43
				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 已提交
44 45 46 47
				face.centroid.divideScalar( 3 );

			} else if ( face instanceof THREE.Face4 ) {

M
Mr.doob 已提交
48 49 50
				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 已提交
51 52 53 54 55 56 57 58 59
				face.centroid.addSelf( this.vertices[ face.d ].position );
				face.centroid.divideScalar( 4 );

			}

		}

	},

60
	computeFaceNormals: function ( useVertexNormals ) {
61

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

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

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

		}

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

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

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

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

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

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

84
				}
U
unknown 已提交
85

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

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

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

92
				}
U
unknown 已提交
93

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

96
			} else {
97

98 99 100 101 102 103 104 105 106 107
				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 已提交
108
					cb.normalize();
109 110 111 112 113 114 115 116 117 118 119

				}

				face.normal.copy( cb );

			}

		}

	},

120 121
	computeVertexNormals: function () {

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

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

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

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

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

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

			}
M
Mr.doob 已提交
137

138 139 140 141 142 143 144
			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 已提交
145

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

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

				}

			}
M
Mr.doob 已提交
153

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

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

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

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

			}
M
Mr.doob 已提交
163

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

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

			face = this.faces[ f ];

			if ( face instanceof THREE.Face3 ) {
171

M
Mr.doob 已提交
172 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
				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 ) {

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

			} else if ( face instanceof THREE.Face4 ) {

205 206 207 208
				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 已提交
209 210

			}
211 212 213 214 215

		}

	},

216
	computeTangents: function() {
217

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

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

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

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

		}
235

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

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

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

246 247 248 249 250 251 252 253 254 255 256 257 258
			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 );
259
			sdir.set( ( t2 * x1 - t1 * x2 ) * r,
260 261
					  ( t2 * y1 - t1 * y2 ) * r,
					  ( t2 * z1 - t1 * z2 ) * r );
262
			tdir.set( ( s1 * x2 - s2 * x1 ) * r,
263 264
					  ( s1 * y2 - s2 * y1 ) * r,
					  ( s1 * z2 - s2 * z1 ) * r );
265

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

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

274
		}
275

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

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

281
			if ( face instanceof THREE.Face3 ) {
282

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

285 286 287
				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 ] );
288 289


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

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

				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 ] );
299

300
			}
301

302
		}
303

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

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

309
			// Gram-Schmidt orthogonalize
310

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

314
			// Calculate handedness
315

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

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

322
		}
323

324
		this.hasTangents = true;
325

326
	},
327

328
	computeBoundingBox: function () {
329

330 331
		var vertex;

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

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

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

				vertex = this.vertices[ v ];

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

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

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

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

				}

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

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

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

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

				}

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

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

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

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

				}

			}
373 374 375

		}

M
Mr.doob 已提交
376 377
	},

378 379 380 381 382 383 384 385 386 387 388 389
	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 已提交
390
	}
391

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

THREE.GeometryIdCounter = 0;