JSONLoader.js 8.6 KB
Newer Older
M
Mr.doob 已提交
1
/**
A
alteredq 已提交
2
 * @author mrdoob / http://mrdoob.com/
M
Mr.doob 已提交
3 4 5
 * @author alteredq / http://alteredqualia.com/
 */

A
alteredq 已提交
6
THREE.JSONLoader = function ( showStatus ) {
M
Mr.doob 已提交
7

8
	THREE.Loader.call( this, showStatus );
9

10 11
	this.withCredentials = false;

M
Mr.doob 已提交
12 13
};

14
THREE.JSONLoader.prototype = Object.create( THREE.Loader.prototype );
A
alteredq 已提交
15

16
THREE.JSONLoader.prototype.load = function ( url, callback, texturePath ) {
A
alteredq 已提交
17

18
	var scope = this;
A
alteredq 已提交
19

20 21 22
	// todo: unify load API to for easier SceneLoader use

	texturePath = texturePath && ( typeof texturePath === "string" ) ? texturePath : this.extractUrlBase( url );
A
alteredq 已提交
23

24 25 26 27 28
	this.onLoadStart();
	this.loadAjaxJSON( this, url, callback, texturePath );

};

29
THREE.JSONLoader.prototype.loadAjaxJSON = function ( context, url, callback, texturePath, callbackProgress ) {
30 31 32 33 34

	var xhr = new XMLHttpRequest();

	var length = 0;

35
	xhr.onreadystatechange = function () {
36

A
alteredq 已提交
37
		if ( xhr.readyState === xhr.DONE ) {
38

A
alteredq 已提交
39 40
			if ( xhr.status === 200 || xhr.status === 0 ) {

M
Mr.doob 已提交
41
				if ( xhr.responseText ) {
42

M
Mr.doob 已提交
43 44
					var json = JSON.parse( xhr.responseText );
					context.createModel( json, callback, texturePath );
45

M
Mr.doob 已提交
46
				} else {
A
alteredq 已提交
47

M
Mr.doob 已提交
48
					console.warn( "THREE.JSONLoader: [" + url + "] seems to be unreachable or file there is empty" );
49 50

				}
A
alteredq 已提交
51

A
alteredq 已提交
52 53 54 55
				// in context of more complex asset initialization
				// do not block on single failed file
				// maybe should go even one more level up

56 57
				context.onLoadComplete();

58 59
			} else {

M
Mr.doob 已提交
60
				console.error( "THREE.JSONLoader: Couldn't load [" + url + "] [" + xhr.status + "]" );
61 62 63

			}

A
alteredq 已提交
64
		} else if ( xhr.readyState === xhr.LOADING ) {
65 66 67

			if ( callbackProgress ) {

A
alteredq 已提交
68
				if ( length === 0 ) {
69 70 71 72 73 74 75 76 77

					length = xhr.getResponseHeader( "Content-Length" );

				}

				callbackProgress( { total: length, loaded: xhr.responseText.length } );

			}

A
alteredq 已提交
78
		} else if ( xhr.readyState === xhr.HEADERS_RECEIVED ) {
79 80 81 82

			length = xhr.getResponseHeader( "Content-Length" );

		}
A
alteredq 已提交
83

84
	};
A
alteredq 已提交
85

86
	xhr.open( "GET", url, true );
87
	xhr.withCredentials = this.withCredentials;
88
	xhr.send( null );
A
alteredq 已提交
89

90
};
A
alteredq 已提交
91

92
THREE.JSONLoader.prototype.createModel = function ( json, callback, texturePath ) {
A
alteredq 已提交
93

94
	var scope = this,
95
	geometry = new THREE.Geometry(),
96
	scale = ( json.scale !== undefined ) ? 1.0 / json.scale : 1.0;
A
alteredq 已提交
97

A
alteredq 已提交
98
	parseModel( scale );
A
alteredq 已提交
99

A
alteredq 已提交
100 101
	parseSkin();
	parseMorphing( scale );
A
alteredq 已提交
102

103
	geometry.computeCentroids();
104
	geometry.computeFaceNormals();
105

A
alteredq 已提交
106
	function parseModel( scale ) {
A
alteredq 已提交
107

108
		function isBitSet( value, position ) {
A
alteredq 已提交
109

110
			return value & ( 1 << position );
A
alteredq 已提交
111

M
Mr.doob 已提交
112
		}
A
alteredq 已提交
113

114
		var i, j, fi,
A
alteredq 已提交
115

116
		offset, zLength, nVertices,
117

A
alteredq 已提交
118
		colorIndex, normalIndex, uvIndex, materialIndex,
119

120
		type,
A
alteredq 已提交
121 122
		isQuad,
		hasMaterial,
123 124 125
		hasFaceUv, hasFaceVertexUv,
		hasFaceNormal, hasFaceVertexNormal,
		hasFaceColor, hasFaceVertexColor,
A
alteredq 已提交
126

127
		vertex, face, color, normal,
128

129
		uvLayer, uvs, u, v,
A
alteredq 已提交
130

131 132 133 134
		faces = json.faces,
		vertices = json.vertices,
		normals = json.normals,
		colors = json.colors,
A
alteredq 已提交
135

136
		nUvLayers = 0;
A
alteredq 已提交
137

138
		// disregard empty arrays
A
alteredq 已提交
139

140
		for ( i = 0; i < json.uvs.length; i++ ) {
A
alteredq 已提交
141

142
			if ( json.uvs[ i ].length ) nUvLayers ++;
A
alteredq 已提交
143

144
		}
A
alteredq 已提交
145

146
		for ( i = 0; i < nUvLayers; i++ ) {
A
alteredq 已提交
147

148 149
			geometry.faceUvs[ i ] = [];
			geometry.faceVertexUvs[ i ] = [];
A
alteredq 已提交
150

151
		}
A
alteredq 已提交
152

153 154
		offset = 0;
		zLength = vertices.length;
A
alteredq 已提交
155

156
		while ( offset < zLength ) {
A
alteredq 已提交
157

M
Mr.doob 已提交
158
			vertex = new THREE.Vector3();
A
alteredq 已提交
159

160 161 162
			vertex.x = vertices[ offset ++ ] * scale;
			vertex.y = vertices[ offset ++ ] * scale;
			vertex.z = vertices[ offset ++ ] * scale;
A
alteredq 已提交
163

164
			geometry.vertices.push( vertex );
A
alteredq 已提交
165

166
		}
A
alteredq 已提交
167

168 169
		offset = 0;
		zLength = faces.length;
A
alteredq 已提交
170

171
		while ( offset < zLength ) {
A
alteredq 已提交
172

173
			type = faces[ offset ++ ];
A
alteredq 已提交
174 175


176 177 178 179 180 181 182 183
			isQuad          	= isBitSet( type, 0 );
			hasMaterial         = isBitSet( type, 1 );
			hasFaceUv           = isBitSet( type, 2 );
			hasFaceVertexUv     = isBitSet( type, 3 );
			hasFaceNormal       = isBitSet( type, 4 );
			hasFaceVertexNormal = isBitSet( type, 5 );
			hasFaceColor	    = isBitSet( type, 6 );
			hasFaceVertexColor  = isBitSet( type, 7 );
A
alteredq 已提交
184

185
			//console.log("type", type, "bits", isQuad, hasMaterial, hasFaceUv, hasFaceVertexUv, hasFaceNormal, hasFaceVertexNormal, hasFaceColor, hasFaceVertexColor);
A
alteredq 已提交
186

187
			if ( isQuad ) {
A
alteredq 已提交
188

189
				face = new THREE.Face4();
A
alteredq 已提交
190

191 192 193 194
				face.a = faces[ offset ++ ];
				face.b = faces[ offset ++ ];
				face.c = faces[ offset ++ ];
				face.d = faces[ offset ++ ];
A
alteredq 已提交
195

196
				nVertices = 4;
A
alteredq 已提交
197

198
			} else {
A
alteredq 已提交
199

200
				face = new THREE.Face3();
A
alteredq 已提交
201

202 203 204
				face.a = faces[ offset ++ ];
				face.b = faces[ offset ++ ];
				face.c = faces[ offset ++ ];
A
alteredq 已提交
205

206
				nVertices = 3;
A
alteredq 已提交
207

208
			}
A
alteredq 已提交
209

210
			if ( hasMaterial ) {
A
alteredq 已提交
211

212
				materialIndex = faces[ offset ++ ];
213
				face.materialIndex = materialIndex;
A
alteredq 已提交
214

215
			}
A
alteredq 已提交
216

217 218 219 220
			// to get face <=> uv index correspondence

			fi = geometry.faces.length;

221
			if ( hasFaceUv ) {
A
alteredq 已提交
222

223
				for ( i = 0; i < nUvLayers; i++ ) {
A
alteredq 已提交
224

225
					uvLayer = json.uvs[ i ];
A
alteredq 已提交
226

227
					uvIndex = faces[ offset ++ ];
A
alteredq 已提交
228

229 230
					u = uvLayer[ uvIndex * 2 ];
					v = uvLayer[ uvIndex * 2 + 1 ];
A
alteredq 已提交
231

M
Mr.doob 已提交
232
					geometry.faceUvs[ i ][ fi ] = new THREE.Vector2( u, v );
A
alteredq 已提交
233

234
				}
A
alteredq 已提交
235

236
			}
A
alteredq 已提交
237

238
			if ( hasFaceVertexUv ) {
A
alteredq 已提交
239

240 241 242 243 244 245 246
				for ( i = 0; i < nUvLayers; i++ ) {

					uvLayer = json.uvs[ i ];

					uvs = [];

					for ( j = 0; j < nVertices; j ++ ) {
A
alteredq 已提交
247

248
						uvIndex = faces[ offset ++ ];
A
alteredq 已提交
249

250 251
						u = uvLayer[ uvIndex * 2 ];
						v = uvLayer[ uvIndex * 2 + 1 ];
A
alteredq 已提交
252

M
Mr.doob 已提交
253
						uvs[ j ] = new THREE.Vector2( u, v );
A
alteredq 已提交
254 255 256

					}

257
					geometry.faceVertexUvs[ i ][ fi ] = uvs;
A
alteredq 已提交
258 259 260

				}

261
			}
A
alteredq 已提交
262

263
			if ( hasFaceNormal ) {
A
alteredq 已提交
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
				normalIndex = faces[ offset ++ ] * 3;

				normal = new THREE.Vector3();

				normal.x = normals[ normalIndex ++ ];
				normal.y = normals[ normalIndex ++ ];
				normal.z = normals[ normalIndex ];

				face.normal = normal;

			}

			if ( hasFaceVertexNormal ) {

				for ( i = 0; i < nVertices; i++ ) {

					normalIndex = faces[ offset ++ ] * 3;

					normal = new THREE.Vector3();

					normal.x = normals[ normalIndex ++ ];
					normal.y = normals[ normalIndex ++ ];
					normal.z = normals[ normalIndex ];

					face.vertexNormals.push( normal );
A
alteredq 已提交
290 291 292

				}

293
			}
A
alteredq 已提交
294 295


296 297
			if ( hasFaceColor ) {

M
Mr.doob 已提交
298 299 300
				colorIndex = faces[ offset ++ ];

				color = new THREE.Color( colors[ colorIndex ] );
301 302 303 304 305 306 307 308 309 310 311 312 313 314
				face.color = color;

			}


			if ( hasFaceVertexColor ) {

				for ( i = 0; i < nVertices; i++ ) {

					colorIndex = faces[ offset ++ ];

					color = new THREE.Color( colors[ colorIndex ] );
					face.vertexColors.push( color );

A
alteredq 已提交
315
				}
316 317 318 319 320 321 322 323 324

			}

			geometry.faces.push( face );

		}

	};

A
alteredq 已提交
325
	function parseSkin() {
326 327 328 329 330

		var i, l, x, y, z, w, a, b, c, d;

		if ( json.skinWeights ) {

331
			for ( i = 0, l = json.skinWeights.length; i < l; i += 2 ) {
332 333 334 335 336 337 338 339 340 341 342 343 344 345

				x = json.skinWeights[ i     ];
				y = json.skinWeights[ i + 1 ];
				z = 0;
				w = 0;

				geometry.skinWeights.push( new THREE.Vector4( x, y, z, w ) );

			}

		}

		if ( json.skinIndices ) {

346
			for ( i = 0, l = json.skinIndices.length; i < l; i += 2 ) {
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363

				a = json.skinIndices[ i     ];
				b = json.skinIndices[ i + 1 ];
				c = 0;
				d = 0;

				geometry.skinIndices.push( new THREE.Vector4( a, b, c, d ) );

			}

		}

		geometry.bones = json.bones;
		geometry.animation = json.animation;

	};

A
alteredq 已提交
364
	function parseMorphing( scale ) {
365

366
		if ( json.morphTargets !== undefined ) {
367

M
Mr.doob 已提交
368
			var i, l, v, vl, dstVertices, srcVertices;
369

A
alteredq 已提交
370
			for ( i = 0, l = json.morphTargets.length; i < l; i ++ ) {
371 372 373 374 375 376 377 378 379 380

				geometry.morphTargets[ i ] = {};
				geometry.morphTargets[ i ].name = json.morphTargets[ i ].name;
				geometry.morphTargets[ i ].vertices = [];

				dstVertices = geometry.morphTargets[ i ].vertices;
				srcVertices = json.morphTargets [ i ].vertices;

				for( v = 0, vl = srcVertices.length; v < vl; v += 3 ) {

M
Mr.doob 已提交
381 382 383 384
					var vertex = new THREE.Vector3();
					vertex.x = srcVertices[ v ] * scale;
					vertex.y = srcVertices[ v + 1 ] * scale;
					vertex.z = srcVertices[ v + 2 ] * scale;
385

M
Mr.doob 已提交
386
					dstVertices.push( vertex );
387

A
alteredq 已提交
388 389
				}

M
Mr.doob 已提交
390
			}
A
alteredq 已提交
391

392
		}
393 394

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

			var i, l, c, cl, dstColors, srcColors, color;

398
			for ( i = 0, l = json.morphColors.length; i < l; i++ ) {
M
Mr.doob 已提交
399 400 401 402 403 404 405 406

				geometry.morphColors[ i ] = {};
				geometry.morphColors[ i ].name = json.morphColors[ i ].name;
				geometry.morphColors[ i ].colors = [];

				dstColors = geometry.morphColors[ i ].colors;
				srcColors = json.morphColors [ i ].colors;

407
				for ( c = 0, cl = srcColors.length; c < cl; c += 3 ) {
M
Mr.doob 已提交
408 409

					color = new THREE.Color( 0xffaa00 );
410
					color.setRGB( srcColors[ c ], srcColors[ c + 1 ], srcColors[ c + 2 ] );
M
Mr.doob 已提交
411 412 413 414
					dstColors.push( color );

				}

M
Mr.doob 已提交
415
			}
M
Mr.doob 已提交
416 417

		}
A
alteredq 已提交
418

419
	};
A
alteredq 已提交
420

421 422
	var materials = this.initMaterials( json.materials, texturePath );

423 424
	if ( this.needsTangents( materials ) ) geometry.computeTangents();

425
	callback( geometry, materials );
A
alteredq 已提交
426

427
};