MMDLoader.js 59.1 KB
Newer Older
M
r74  
Mr.doob 已提交
1 2 3 4
/**
 * @author takahiro / https://github.com/takahirox
 *
 * Dependencies
M
r83  
Mr.doob 已提交
5
 *  - mmd-parser https://github.com/takahirox/mmd-parser
M
r82  
Mr.doob 已提交
6
 *  - ammo.js https://github.com/kripken/ammo.js
M
r74  
Mr.doob 已提交
7
 *  - THREE.TGALoader
M
r82  
Mr.doob 已提交
8 9 10
 *  - THREE.MMDPhysics
 *  - THREE.CCDIKSolver
 *  - THREE.OutlineEffect
M
r74  
Mr.doob 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
 *
 *
 * This loader loads and parses PMD/PMX and VMD binary files
 * then creates mesh for Three.js.
 *
 * PMD/PMX is a model data format and VMD is a motion data format
 * used in MMD(Miku Miku Dance).
 *
 * MMD is a 3D CG animation tool which is popular in Japan.
 *
 *
 * MMD official site
 *  http://www.geocities.jp/higuchuu4/index_e.htm
 *
 * PMD, VMD format
 *  http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4
 *
 * PMX format
 *  http://gulshan-i-raz.geo.jp/labs/2012/10/17/pmx-format1/
 *
 *
 * TODO
 *  - light motion in vmd support.
 *  - SDEF support.
 *  - uv/material/bone morphing support.
M
r76  
Mr.doob 已提交
36
 *  - more precise grant skinning support.
M
r74  
Mr.doob 已提交
37 38 39
 *  - shadow support.
 */

M
r78  
Mr.doob 已提交
40
THREE.MMDLoader = function ( manager ) {
M
r74  
Mr.doob 已提交
41

M
r78  
Mr.doob 已提交
42
	THREE.Loader.call( this );
M
r74  
Mr.doob 已提交
43
	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
M
r83  
Mr.doob 已提交
44 45
	this.parser = new MMDParser.Parser();
	this.textureCrossOrigin = null;
M
r74  
Mr.doob 已提交
46 47 48 49 50 51

};

THREE.MMDLoader.prototype = Object.create( THREE.Loader.prototype );
THREE.MMDLoader.prototype.constructor = THREE.MMDLoader;

M
r83  
Mr.doob 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
/*
 * base64 encoded defalut toon textures toon00.bmp - toon10.bmp
 * Users don't need to prepare default texture files.
 *
 * This idea is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js
 */
THREE.MMDLoader.prototype.defaultToonTextures = [
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/bWiiMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh8aBHZBl14e8wAAAABJRU5ErkJggg==',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOUlEQVRYR+3WMREAMAwDsYY/yoDI7MLwIiP40+RJklfcCCBAgAABAgTqArfb/QMCCBAgQIAAgbbAB3z/e0F3js2cAAAAAElFTkSuQmCC',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/B5ilMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh81dWyx0gFwKAAAAABJRU5ErkJggg==',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOklEQVRYR+3WoREAMAwDsWb/UQtCy9wxTOQJ/oQ8SXKKGwEECBAgQIBAXeDt7f4BAQQIECBAgEBb4AOz8Hzx7WLY4wAAAABJRU5ErkJggg==',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABPUlEQVRYR+1XwW7CMAy1+f9fZOMysSEOEweEOPRNdm3HbdOyIhAcklPrOs/PLy9RygBALxzcCDQFmgJNgaZAU6Ap0BR4PwX8gsRMVLssMRH5HcpzJEaWL7EVg9F1IHRlyqQohgVr4FGUlUcMJSjcUlDw0zvjeun70cLWmneoyf7NgBTQSniBTQQSuJAZsOnnaczjIMb5hCiuHKxokCrJfVnrctyZL0PkJAJe1HMil4nxeyi3Ypfn1kX51jpPvo/JeCNC4PhVdHdJw2XjBR8brF8PEIhNVn12AgP7uHsTBguBn53MUZCqv7Lp07Pn5k1Ro+uWmUNn7D+M57rtk7aG0Vo73xyF/fbFf0bPJjDXngnGocDTdFhygZjwUQrMNrDcmZlQT50VJ/g/UwNyHpu778+yW+/ksOz/BFo54P4AsUXMfRq7XWsAAAAASUVORK5CYII=',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACMElEQVRYR+2Xv4pTQRTGf2dubhLdICiii2KnYKHVolhauKWPoGAnNr6BD6CvIVaihYuI2i1ia0BY0MZGRHQXjZj/mSPnnskfNWiWZUlzJ5k7M2cm833nO5Mziej2DWWJRUoCpQKlAntSQCqgw39/iUWAGmh37jrRnVsKlgpiqmkoGVABA7E57fvY+pJDdgKqF6HzFCSADkDq+F6AHABtQ+UMVE5D7zXod7fFNhTEckTbj5XQgHzNN+5tQvc5NG7C6BNkp6D3EmpXHDR+dQAjFLchW3VS9rlw3JBh+B7ys5Cf9z0GW1C/7P32AyBAOAz1q4jGliIH3YPuBnSfQX4OGreTIgEYQb/pBDtPnEQ4CivXYPAWBk13oHrB54yA9QuSn2H4AcKRpEILDt0BUzj+RLR1V5EqjD66NPRBVpLcQwjHoHYJOhsQv6U4mnzmrIXJCFr4LDwm/xBUoboG9XX4cc9VKdYoSA2yk5NQLJaKDUjTBoveG3Z2TElTxwjNK4M3LEZgUdDdruvcXzKBpStgp2NPiWi3ks9ZXxIoFVi+AvHLdc9TqtjL3/aYjpPlrzOcEnK62Szhimdd7xX232zFDTgtxezOu3WNMRLjiKgjtOhHVMd1loynVHvOgjuIIJMaELEqhJAV/RCSLbWTcfPFakFgFlALTRRvx+ok6Hlp/Q+v3fmx90bMyUzaEAhmM3KvHlXTL5DxnbGf/1M8RNNACLL5MNtPxP/mypJAqcDSFfgFhpYqWUzhTEAAAAAASUVORK5CYII=',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',
	'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII='
];

/*
 * Set 'anonymous' for the the texture image file in other domain
 * even if server responds with "Access-Control-Allow-Origin: *"
 * because some image operation fails in MMDLoader.
 */
THREE.MMDLoader.prototype.setTextureCrossOrigin = function ( value ) {
M
r74  
Mr.doob 已提交
78

M
r83  
Mr.doob 已提交
79
	this.textureCrossOrigin = value;
M
r74  
Mr.doob 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

};

THREE.MMDLoader.prototype.load = function ( modelUrl, vmdUrls, callback, onProgress, onError ) {

	var scope = this;

	this.loadModel( modelUrl, function ( mesh ) {

		scope.loadVmds( vmdUrls, function ( vmd ) {

			scope.pourVmdIntoModel( mesh, vmd );
			callback( mesh );

		}, onProgress, onError );

	}, onProgress, onError );

};

THREE.MMDLoader.prototype.loadModel = function ( url, callback, onProgress, onError ) {

	var scope = this;

M
r89  
Mr.doob 已提交
104
	var texturePath = THREE.LoaderUtils.extractUrlBase( url );
M
r74  
Mr.doob 已提交
105 106 107 108
	var modelExtension = this.extractExtension( url );

	this.loadFileAsBuffer( url, function ( buffer ) {

M
r83  
Mr.doob 已提交
109
		callback( scope.createModel( buffer, modelExtension, texturePath, onProgress, onError ) );
M
r74  
Mr.doob 已提交
110 111 112 113 114

	}, onProgress, onError );

};

M
r83  
Mr.doob 已提交
115
THREE.MMDLoader.prototype.createModel = function ( buffer, modelExtension, texturePath, onProgress, onError ) {
M
r74  
Mr.doob 已提交
116

M
r83  
Mr.doob 已提交
117
	return this.createMesh( this.parseModel( buffer, modelExtension ), texturePath, onProgress, onError );
M
r74  
Mr.doob 已提交
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

};

THREE.MMDLoader.prototype.loadVmd = function ( url, callback, onProgress, onError ) {

	var scope = this;

	this.loadFileAsBuffer( url, function ( buffer ) {

		callback( scope.parseVmd( buffer ) );

	}, onProgress, onError );

};

THREE.MMDLoader.prototype.loadVmds = function ( urls, callback, onProgress, onError ) {

	var scope = this;

	var vmds = [];
M
r83  
Mr.doob 已提交
138
	urls = urls.slice();
M
r74  
Mr.doob 已提交
139

M
r88  
Mr.doob 已提交
140
	function run() {
M
r74  
Mr.doob 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

		var url = urls.shift();

		scope.loadVmd( url, function ( vmd ) {

			vmds.push( vmd );

			if ( urls.length > 0 ) {

				run();

			} else {

				callback( scope.mergeVmds( vmds ) );

			}

		}, onProgress, onError );

M
r83  
Mr.doob 已提交
160
	}
M
r74  
Mr.doob 已提交
161 162 163 164 165 166 167 168 169

	run();

};

THREE.MMDLoader.prototype.loadAudio = function ( url, callback, onProgress, onError ) {

	var listener = new THREE.AudioListener();
	var audio = new THREE.Audio( listener );
M
r76  
Mr.doob 已提交
170
	var loader = new THREE.AudioLoader( this.manager );
M
r74  
Mr.doob 已提交
171

M
r76  
Mr.doob 已提交
172
	loader.load( url, function ( buffer ) {
M
r74  
Mr.doob 已提交
173

M
r76  
Mr.doob 已提交
174 175
		audio.setBuffer( buffer );
		callback( audio, listener );
M
r74  
Mr.doob 已提交
176

M
r76  
Mr.doob 已提交
177
	}, onProgress, onError );
M
r74  
Mr.doob 已提交
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

};

THREE.MMDLoader.prototype.loadVpd = function ( url, callback, onProgress, onError, params ) {

	var scope = this;

	var func = ( ( params && params.charcode === 'unicode' ) ? this.loadFileAsText : this.loadFileAsShiftJISText ).bind( this );

	func( url, function ( text ) {

		callback( scope.parseVpd( text ) );

	}, onProgress, onError );

};

M
r83  
Mr.doob 已提交
195 196 197
THREE.MMDLoader.prototype.parseModel = function ( buffer, modelExtension ) {

	// Should I judge from model data header?
M
r88  
Mr.doob 已提交
198
	switch ( modelExtension.toLowerCase() ) {
M
r83  
Mr.doob 已提交
199 200 201

		case 'pmd':
			return this.parsePmd( buffer );
M
r74  
Mr.doob 已提交
202

M
r83  
Mr.doob 已提交
203 204
		case 'pmx':
			return this.parsePmx( buffer );
M
r74  
Mr.doob 已提交
205

M
r83  
Mr.doob 已提交
206 207
		default:
			throw 'extension ' + modelExtension + ' is not supported.';
M
r74  
Mr.doob 已提交
208

M
r83  
Mr.doob 已提交
209
	}
M
r74  
Mr.doob 已提交
210

M
r83  
Mr.doob 已提交
211
};
M
r74  
Mr.doob 已提交
212

M
r83  
Mr.doob 已提交
213
THREE.MMDLoader.prototype.parsePmd = function ( buffer ) {
M
r74  
Mr.doob 已提交
214

M
r83  
Mr.doob 已提交
215
	return this.parser.parsePmd( buffer, true );
M
r74  
Mr.doob 已提交
216

M
r83  
Mr.doob 已提交
217
};
M
r74  
Mr.doob 已提交
218

M
r83  
Mr.doob 已提交
219
THREE.MMDLoader.prototype.parsePmx = function ( buffer ) {
M
r74  
Mr.doob 已提交
220

M
r83  
Mr.doob 已提交
221
	return this.parser.parsePmx( buffer, true );
M
r74  
Mr.doob 已提交
222

M
r83  
Mr.doob 已提交
223
};
M
r74  
Mr.doob 已提交
224

M
r83  
Mr.doob 已提交
225
THREE.MMDLoader.prototype.parseVmd = function ( buffer ) {
M
r74  
Mr.doob 已提交
226

M
r83  
Mr.doob 已提交
227
	return this.parser.parseVmd( buffer, true );
M
r74  
Mr.doob 已提交
228

M
r83  
Mr.doob 已提交
229
};
M
r74  
Mr.doob 已提交
230

M
r83  
Mr.doob 已提交
231 232 233 234 235
THREE.MMDLoader.prototype.parseVpd = function ( text ) {

	return this.parser.parseVpd( text, true );

};
M
r74  
Mr.doob 已提交
236

M
r83  
Mr.doob 已提交
237 238 239
THREE.MMDLoader.prototype.mergeVmds = function ( vmds ) {

	return this.parser.mergeVmds( vmds );
M
r74  
Mr.doob 已提交
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256

};

THREE.MMDLoader.prototype.pourVmdIntoModel = function ( mesh, vmd, name ) {

	this.createAnimation( mesh, vmd, name );

};

THREE.MMDLoader.prototype.pourVmdIntoCamera = function ( camera, vmd, name ) {

	var helper = new THREE.MMDLoader.DataCreationHelper();

	var initAnimation = function () {

		var orderedMotions = helper.createOrderedMotionArray( vmd.cameras );

M
r83  
Mr.doob 已提交
257 258 259 260 261
		var times = [];
		var centers = [];
		var quaternions = [];
		var positions = [];
		var fovs = [];
M
r74  
Mr.doob 已提交
262

M
r83  
Mr.doob 已提交
263 264 265 266
		var cInterpolations = [];
		var qInterpolations = [];
		var pInterpolations = [];
		var fInterpolations = [];
M
r74  
Mr.doob 已提交
267

M
r83  
Mr.doob 已提交
268 269 270 271
		var quaternion = new THREE.Quaternion();
		var euler = new THREE.Euler();
		var position = new THREE.Vector3();
		var center = new THREE.Vector3();
M
r74  
Mr.doob 已提交
272

M
r83  
Mr.doob 已提交
273
		var pushVector3 = function ( array, vec ) {
M
r74  
Mr.doob 已提交
274

M
r83  
Mr.doob 已提交
275 276 277
			array.push( vec.x );
			array.push( vec.y );
			array.push( vec.z );
M
r74  
Mr.doob 已提交
278

M
r83  
Mr.doob 已提交
279
		};
M
r74  
Mr.doob 已提交
280

M
r83  
Mr.doob 已提交
281
		var pushQuaternion = function ( array, q ) {
M
r74  
Mr.doob 已提交
282

M
r83  
Mr.doob 已提交
283 284 285 286
			array.push( q.x );
			array.push( q.y );
			array.push( q.z );
			array.push( q.w );
M
r74  
Mr.doob 已提交
287

M
r83  
Mr.doob 已提交
288
		};
M
r74  
Mr.doob 已提交
289

M
r83  
Mr.doob 已提交
290
		var pushInterpolation = function ( array, interpolation, index ) {
M
r74  
Mr.doob 已提交
291

M
r83  
Mr.doob 已提交
292 293 294 295
			array.push( interpolation[ index * 4 + 0 ] / 127 ); // x1
			array.push( interpolation[ index * 4 + 1 ] / 127 ); // x2
			array.push( interpolation[ index * 4 + 2 ] / 127 ); // y1
			array.push( interpolation[ index * 4 + 3 ] / 127 ); // y2
M
r74  
Mr.doob 已提交
296

M
r83  
Mr.doob 已提交
297
		};
M
r74  
Mr.doob 已提交
298

M
r83  
Mr.doob 已提交
299
		var createTrack = function ( node, type, times, values, interpolations ) {
M
r74  
Mr.doob 已提交
300

M
r83  
Mr.doob 已提交
301 302 303 304 305 306
			/*
			 * optimizes here not to let KeyframeTrackPrototype optimize
			 * because KeyframeTrackPrototype optimizes times and values but
			 * doesn't optimize interpolations.
			 */
			if ( times.length > 2 ) {
M
r74  
Mr.doob 已提交
307

M
r83  
Mr.doob 已提交
308 309 310
				times = times.slice();
				values = values.slice();
				interpolations = interpolations.slice();
M
r74  
Mr.doob 已提交
311

M
r83  
Mr.doob 已提交
312
				var stride = values.length / times.length;
M
r88  
Mr.doob 已提交
313
				var interpolateStride = ( stride === 3 ) ? 12 : 4; // 3: Vector3, others: Quaternion or Number
M
r74  
Mr.doob 已提交
314

M
r83  
Mr.doob 已提交
315
				var index = 1;
M
r74  
Mr.doob 已提交
316

M
r86  
Mr.doob 已提交
317
				for ( var aheadIndex = 2, endIndex = times.length; aheadIndex < endIndex; aheadIndex ++ ) {
M
r74  
Mr.doob 已提交
318

M
r83  
Mr.doob 已提交
319
					for ( var i = 0; i < stride; i ++ ) {
M
r74  
Mr.doob 已提交
320

M
r83  
Mr.doob 已提交
321 322
						if ( values[ index * stride + i ] !== values[ ( index - 1 ) * stride + i ] ||
							values[ index * stride + i ] !== values[ aheadIndex * stride + i ] ) {
M
r74  
Mr.doob 已提交
323

M
r83  
Mr.doob 已提交
324 325
							index ++;
							break;
M
r74  
Mr.doob 已提交
326

M
r83  
Mr.doob 已提交
327
						}
M
r74  
Mr.doob 已提交
328

M
r83  
Mr.doob 已提交
329
					}
M
r74  
Mr.doob 已提交
330

M
r83  
Mr.doob 已提交
331
					if ( aheadIndex > index ) {
M
r74  
Mr.doob 已提交
332

M
r83  
Mr.doob 已提交
333
						times[ index ] = times[ aheadIndex ];
M
r74  
Mr.doob 已提交
334

M
r83  
Mr.doob 已提交
335
						for ( var i = 0; i < stride; i ++ ) {
M
r74  
Mr.doob 已提交
336

M
r83  
Mr.doob 已提交
337
							values[ index * stride + i ] = values[ aheadIndex * stride + i ];
M
r74  
Mr.doob 已提交
338

M
r83  
Mr.doob 已提交
339
						}
M
r74  
Mr.doob 已提交
340

M
r83  
Mr.doob 已提交
341
						for ( var i = 0; i < interpolateStride; i ++ ) {
M
r74  
Mr.doob 已提交
342

M
r83  
Mr.doob 已提交
343
							interpolations[ index * interpolateStride + i ] = interpolations[ aheadIndex * interpolateStride + i ];
M
r74  
Mr.doob 已提交
344

M
r83  
Mr.doob 已提交
345
						}
M
r74  
Mr.doob 已提交
346

M
r83  
Mr.doob 已提交
347
					}
M
r74  
Mr.doob 已提交
348

M
r83  
Mr.doob 已提交
349
				}
M
r74  
Mr.doob 已提交
350

M
r83  
Mr.doob 已提交
351 352 353
				times.length = index + 1;
				values.length = ( index + 1 ) * stride;
				interpolations.length = ( index + 1 ) * interpolateStride;
M
r74  
Mr.doob 已提交
354

M
r83  
Mr.doob 已提交
355
			}
M
r74  
Mr.doob 已提交
356

M
r83  
Mr.doob 已提交
357
			return new THREE.MMDLoader[ type ]( node, times, values, interpolations );
M
r74  
Mr.doob 已提交
358

M
r83  
Mr.doob 已提交
359
		};
M
r74  
Mr.doob 已提交
360

M
r88  
Mr.doob 已提交
361
		for ( var i = 0; i < orderedMotions.length; i ++ ) {
M
r74  
Mr.doob 已提交
362

M
r83  
Mr.doob 已提交
363
			var m = orderedMotions[ i ];
M
r74  
Mr.doob 已提交
364

M
r83  
Mr.doob 已提交
365 366 367 368 369 370
			var time = m.frameNum / 30;
			var pos = m.position;
			var rot = m.rotation;
			var distance = m.distance;
			var fov = m.fov;
			var interpolation = m.interpolation;
M
r74  
Mr.doob 已提交
371

M
r88  
Mr.doob 已提交
372
			position.set( 0, 0, - distance );
M
r83  
Mr.doob 已提交
373
			center.set( pos[ 0 ], pos[ 1 ], pos[ 2 ] );
M
r74  
Mr.doob 已提交
374

M
r88  
Mr.doob 已提交
375
			euler.set( - rot[ 0 ], - rot[ 1 ], - rot[ 2 ] );
M
r83  
Mr.doob 已提交
376
			quaternion.setFromEuler( euler );
M
r74  
Mr.doob 已提交
377

M
r83  
Mr.doob 已提交
378 379
			position.add( center );
			position.applyQuaternion( quaternion );
M
r74  
Mr.doob 已提交
380

M
r83  
Mr.doob 已提交
381 382 383 384 385
			/*
			 * Note: This is a workaround not to make Animation system calculate lerp
			 *       if the diff from the last frame is 1 frame (in 30fps).
			 */
			if ( times.length > 0 && time < times[ times.length - 1 ] + ( 1 / 30 ) * 1.5 ) {
M
r74  
Mr.doob 已提交
386

M
r83  
Mr.doob 已提交
387
				times[ times.length - 1 ] = time - 1e-13;
M
r74  
Mr.doob 已提交
388

M
r83  
Mr.doob 已提交
389
			}
M
r74  
Mr.doob 已提交
390

M
r83  
Mr.doob 已提交
391
			times.push( time );
M
r74  
Mr.doob 已提交
392

M
r83  
Mr.doob 已提交
393 394 395
			pushVector3( centers, center );
			pushQuaternion( quaternions, quaternion );
			pushVector3( positions, position );
M
r74  
Mr.doob 已提交
396

M
r83  
Mr.doob 已提交
397
			fovs.push( fov );
M
r74  
Mr.doob 已提交
398

M
r83  
Mr.doob 已提交
399
			for ( var j = 0; j < 3; j ++ ) {
M
r74  
Mr.doob 已提交
400

M
r83  
Mr.doob 已提交
401
				pushInterpolation( cInterpolations, interpolation, j );
M
r74  
Mr.doob 已提交
402

M
r83  
Mr.doob 已提交
403
			}
M
r74  
Mr.doob 已提交
404

M
r83  
Mr.doob 已提交
405
			pushInterpolation( qInterpolations, interpolation, 3 );
M
r74  
Mr.doob 已提交
406

M
r83  
Mr.doob 已提交
407 408
			// use same one parameter for x, y, z axis.
			for ( var j = 0; j < 3; j ++ ) {
M
r74  
Mr.doob 已提交
409

M
r83  
Mr.doob 已提交
410
				pushInterpolation( pInterpolations, interpolation, 4 );
M
r74  
Mr.doob 已提交
411

M
r83  
Mr.doob 已提交
412
			}
M
r74  
Mr.doob 已提交
413

M
r83  
Mr.doob 已提交
414
			pushInterpolation( fInterpolations, interpolation, 5 );
M
r74  
Mr.doob 已提交
415

M
r83  
Mr.doob 已提交
416
		}
M
r74  
Mr.doob 已提交
417

M
r83  
Mr.doob 已提交
418
		if ( times.length === 0 ) return;
M
r74  
Mr.doob 已提交
419

M
r83  
Mr.doob 已提交
420
		var tracks = [];
M
r74  
Mr.doob 已提交
421

M
r83  
Mr.doob 已提交
422 423 424 425
		tracks.push( createTrack( '.center', 'VectorKeyframeTrackEx', times, centers, cInterpolations ) );
		tracks.push( createTrack( '.quaternion', 'QuaternionKeyframeTrackEx', times, quaternions, qInterpolations ) );
		tracks.push( createTrack( '.position', 'VectorKeyframeTrackEx', times, positions, pInterpolations ) );
		tracks.push( createTrack( '.fov', 'NumberKeyframeTrackEx', times, fovs, fInterpolations ) );
M
r74  
Mr.doob 已提交
426

M
r88  
Mr.doob 已提交
427
		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, - 1, tracks );
M
r74  
Mr.doob 已提交
428

M
r86  
Mr.doob 已提交
429 430 431
		if ( camera.center === undefined ) camera.center = new THREE.Vector3( 0, 0, 0 );
		if ( camera.animations === undefined ) camera.animations = [];
		camera.animations.push( clip );
M
r74  
Mr.doob 已提交
432

M
r83  
Mr.doob 已提交
433
	};
M
r74  
Mr.doob 已提交
434

M
r83  
Mr.doob 已提交
435
	initAnimation();
M
r74  
Mr.doob 已提交
436

M
r83  
Mr.doob 已提交
437
};
M
r74  
Mr.doob 已提交
438

M
r83  
Mr.doob 已提交
439
THREE.MMDLoader.prototype.extractExtension = function ( url ) {
M
r74  
Mr.doob 已提交
440

M
r83  
Mr.doob 已提交
441
	var index = url.lastIndexOf( '.' );
M
r74  
Mr.doob 已提交
442

M
r83  
Mr.doob 已提交
443
	if ( index < 0 ) {
M
r74  
Mr.doob 已提交
444

M
r83  
Mr.doob 已提交
445
		return null;
M
r74  
Mr.doob 已提交
446

M
r83  
Mr.doob 已提交
447
	}
M
r74  
Mr.doob 已提交
448

M
r83  
Mr.doob 已提交
449
	return url.slice( index + 1 );
M
r74  
Mr.doob 已提交
450

M
r83  
Mr.doob 已提交
451
};
M
r74  
Mr.doob 已提交
452

M
r83  
Mr.doob 已提交
453
THREE.MMDLoader.prototype.loadFile = function ( url, onLoad, onProgress, onError, responseType, mimeType ) {
M
r74  
Mr.doob 已提交
454

M
r83  
Mr.doob 已提交
455
	var loader = new THREE.FileLoader( this.manager );
M
r74  
Mr.doob 已提交
456

M
r83  
Mr.doob 已提交
457
	if ( mimeType !== undefined ) loader.setMimeType( mimeType );
M
r74  
Mr.doob 已提交
458

M
r83  
Mr.doob 已提交
459
	loader.setResponseType( responseType );
M
r74  
Mr.doob 已提交
460

M
r83  
Mr.doob 已提交
461
	var request = loader.load( url, function ( result ) {
M
r74  
Mr.doob 已提交
462

M
r83  
Mr.doob 已提交
463
		onLoad( result );
M
r74  
Mr.doob 已提交
464

M
r83  
Mr.doob 已提交
465
	}, onProgress, onError );
M
r74  
Mr.doob 已提交
466

M
r83  
Mr.doob 已提交
467
	return request;
M
r74  
Mr.doob 已提交
468

M
r83  
Mr.doob 已提交
469
};
M
r74  
Mr.doob 已提交
470

M
r83  
Mr.doob 已提交
471
THREE.MMDLoader.prototype.loadFileAsBuffer = function ( url, onLoad, onProgress, onError ) {
M
r74  
Mr.doob 已提交
472

M
r83  
Mr.doob 已提交
473
	this.loadFile( url, onLoad, onProgress, onError, 'arraybuffer' );
M
r74  
Mr.doob 已提交
474

M
r83  
Mr.doob 已提交
475
};
M
r74  
Mr.doob 已提交
476

M
r83  
Mr.doob 已提交
477
THREE.MMDLoader.prototype.loadFileAsText = function ( url, onLoad, onProgress, onError ) {
M
r74  
Mr.doob 已提交
478

M
r83  
Mr.doob 已提交
479
	this.loadFile( url, onLoad, onProgress, onError, 'text' );
M
r74  
Mr.doob 已提交
480

M
r83  
Mr.doob 已提交
481
};
M
r74  
Mr.doob 已提交
482

M
r83  
Mr.doob 已提交
483
THREE.MMDLoader.prototype.loadFileAsShiftJISText = function ( url, onLoad, onProgress, onError ) {
M
r74  
Mr.doob 已提交
484

M
r83  
Mr.doob 已提交
485
	this.loadFile( url, onLoad, onProgress, onError, 'text', 'text/plain; charset=shift_jis' );
M
r74  
Mr.doob 已提交
486

M
r83  
Mr.doob 已提交
487
};
M
r74  
Mr.doob 已提交
488

M
r83  
Mr.doob 已提交
489
THREE.MMDLoader.prototype.createMesh = function ( model, texturePath, onProgress, onError ) {
M
r74  
Mr.doob 已提交
490

M
r83  
Mr.doob 已提交
491 492
	var scope = this;
	var geometry = new THREE.BufferGeometry();
M
r85  
Mr.doob 已提交
493
	var materials = [];
M
r74  
Mr.doob 已提交
494

M
r83  
Mr.doob 已提交
495
	var buffer = {};
M
r74  
Mr.doob 已提交
496

M
r83  
Mr.doob 已提交
497 498 499 500 501 502
	buffer.vertices = [];
	buffer.uvs = [];
	buffer.normals = [];
	buffer.skinIndices = [];
	buffer.skinWeights = [];
	buffer.indices = [];
M
r74  
Mr.doob 已提交
503

M
r83  
Mr.doob 已提交
504
	var initVartices = function () {
M
r74  
Mr.doob 已提交
505

M
r88  
Mr.doob 已提交
506
		for ( var i = 0; i < model.metadata.vertexCount; i ++ ) {
M
r74  
Mr.doob 已提交
507

M
r83  
Mr.doob 已提交
508
			var v = model.vertices[ i ];
M
r74  
Mr.doob 已提交
509

M
r83  
Mr.doob 已提交
510
			for ( var j = 0, jl = v.position.length; j < jl; j ++ ) {
M
r74  
Mr.doob 已提交
511

M
r83  
Mr.doob 已提交
512
				buffer.vertices.push( v.position[ j ] );
M
r74  
Mr.doob 已提交
513

M
r83  
Mr.doob 已提交
514
			}
M
r74  
Mr.doob 已提交
515

M
r83  
Mr.doob 已提交
516
			for ( var j = 0, jl = v.normal.length; j < jl; j ++ ) {
M
r74  
Mr.doob 已提交
517

M
r83  
Mr.doob 已提交
518
				buffer.normals.push( v.normal[ j ] );
M
r74  
Mr.doob 已提交
519

M
r83  
Mr.doob 已提交
520
			}
M
r74  
Mr.doob 已提交
521

M
r83  
Mr.doob 已提交
522
			for ( var j = 0, jl = v.uv.length; j < jl; j ++ ) {
M
r74  
Mr.doob 已提交
523

M
r83  
Mr.doob 已提交
524
				buffer.uvs.push( v.uv[ j ] );
M
r74  
Mr.doob 已提交
525 526 527

			}

M
r83  
Mr.doob 已提交
528
			for ( var j = 0; j < 4; j ++ ) {
M
r74  
Mr.doob 已提交
529

M
r83  
Mr.doob 已提交
530
				buffer.skinIndices.push( v.skinIndices.length - 1 >= j ? v.skinIndices[ j ] : 0.0 );
M
r74  
Mr.doob 已提交
531

M
r83  
Mr.doob 已提交
532
			}
M
r74  
Mr.doob 已提交
533

M
r83  
Mr.doob 已提交
534
			for ( var j = 0; j < 4; j ++ ) {
M
r74  
Mr.doob 已提交
535

M
r83  
Mr.doob 已提交
536
				buffer.skinWeights.push( v.skinWeights.length - 1 >= j ? v.skinWeights[ j ] : 0.0 );
M
r74  
Mr.doob 已提交
537

M
r83  
Mr.doob 已提交
538
			}
M
r74  
Mr.doob 已提交
539 540 541 542 543

		}

	};

M
r83  
Mr.doob 已提交
544
	var initFaces = function () {
M
r74  
Mr.doob 已提交
545

M
r88  
Mr.doob 已提交
546
		for ( var i = 0; i < model.metadata.faceCount; i ++ ) {
M
r74  
Mr.doob 已提交
547

M
r83  
Mr.doob 已提交
548
			var f = model.faces[ i ];
M
r74  
Mr.doob 已提交
549

M
r83  
Mr.doob 已提交
550
			for ( var j = 0, jl = f.indices.length; j < jl; j ++ ) {
M
r74  
Mr.doob 已提交
551

M
r83  
Mr.doob 已提交
552
				buffer.indices.push( f.indices[ j ] );
M
r74  
Mr.doob 已提交
553 554 555 556 557 558 559

			}

		}

	};

M
r83  
Mr.doob 已提交
560
	var initBones = function () {
M
r74  
Mr.doob 已提交
561

M
r83  
Mr.doob 已提交
562
		var bones = [];
M
r74  
Mr.doob 已提交
563

M
r83  
Mr.doob 已提交
564 565
		var rigidBodies = model.rigidBodies;
		var dictionary = {};
M
r74  
Mr.doob 已提交
566

M
r83  
Mr.doob 已提交
567
		for ( var i = 0, il = rigidBodies.length; i < il; i ++ ) {
M
r74  
Mr.doob 已提交
568

M
r83  
Mr.doob 已提交
569 570
			var body = rigidBodies[ i ];
			var value = dictionary[ body.boneIndex ];
M
r74  
Mr.doob 已提交
571

M
r83  
Mr.doob 已提交
572 573
			// keeps greater number if already value is set without any special reasons
			value = value === undefined ? body.type : Math.max( body.type, value );
M
r74  
Mr.doob 已提交
574

M
r83  
Mr.doob 已提交
575
			dictionary[ body.boneIndex ] = value;
M
r74  
Mr.doob 已提交
576 577 578

		}

M
r88  
Mr.doob 已提交
579
		for ( var i = 0; i < model.metadata.boneCount; i ++ ) {
M
r74  
Mr.doob 已提交
580

M
r83  
Mr.doob 已提交
581 582
			var bone = {};
			var b = model.bones[ i ];
M
r74  
Mr.doob 已提交
583

M
r83  
Mr.doob 已提交
584 585 586 587 588
			bone.parent = b.parentIndex;
			bone.name = b.name;
			bone.pos = [ b.position[ 0 ], b.position[ 1 ], b.position[ 2 ] ];
			bone.rotq = [ 0, 0, 0, 1 ];
			bone.scl = [ 1, 1, 1 ];
M
r74  
Mr.doob 已提交
589

M
r88  
Mr.doob 已提交
590
			if ( bone.parent !== - 1 ) {
M
r74  
Mr.doob 已提交
591

M
r83  
Mr.doob 已提交
592 593 594
				bone.pos[ 0 ] -= model.bones[ bone.parent ].position[ 0 ];
				bone.pos[ 1 ] -= model.bones[ bone.parent ].position[ 1 ];
				bone.pos[ 2 ] -= model.bones[ bone.parent ].position[ 2 ];
M
r74  
Mr.doob 已提交
595

M
r83  
Mr.doob 已提交
596
			}
M
r74  
Mr.doob 已提交
597

M
r88  
Mr.doob 已提交
598
			bone.rigidBodyType = dictionary[ i ] !== undefined ? dictionary[ i ] : - 1;
M
r74  
Mr.doob 已提交
599

M
r83  
Mr.doob 已提交
600
			bones.push( bone );
M
r74  
Mr.doob 已提交
601 602 603

		}

M
r83  
Mr.doob 已提交
604 605
		geometry.bones = bones;

M
r74  
Mr.doob 已提交
606 607
	};

M
r83  
Mr.doob 已提交
608
	var initIKs = function () {
M
r74  
Mr.doob 已提交
609

M
r83  
Mr.doob 已提交
610
		var iks = [];
M
r74  
Mr.doob 已提交
611

M
r83  
Mr.doob 已提交
612 613
		// TODO: remove duplicated codes between PMD and PMX
		if ( model.metadata.format === 'pmd' ) {
M
r74  
Mr.doob 已提交
614

M
r88  
Mr.doob 已提交
615
			for ( var i = 0; i < model.metadata.ikCount; i ++ ) {
M
r74  
Mr.doob 已提交
616

M
r88  
Mr.doob 已提交
617
				var ik = model.iks[ i ];
M
r83  
Mr.doob 已提交
618
				var param = {};
M
r74  
Mr.doob 已提交
619

M
r83  
Mr.doob 已提交
620 621 622 623 624
				param.target = ik.target;
				param.effector = ik.effector;
				param.iteration = ik.iteration;
				param.maxAngle = ik.maxAngle * 4;
				param.links = [];
M
r74  
Mr.doob 已提交
625

M
r88  
Mr.doob 已提交
626
				for ( var j = 0; j < ik.links.length; j ++ ) {
M
r74  
Mr.doob 已提交
627

M
r83  
Mr.doob 已提交
628 629
					var link = {};
					link.index = ik.links[ j ].index;
M
r74  
Mr.doob 已提交
630

M
r83  
Mr.doob 已提交
631
					if ( model.bones[ link.index ].name.indexOf( 'ひざ' ) >= 0 ) {
M
r74  
Mr.doob 已提交
632

M
r83  
Mr.doob 已提交
633
						link.limitation = new THREE.Vector3( 1.0, 0.0, 0.0 );
M
r74  
Mr.doob 已提交
634

M
r83  
Mr.doob 已提交
635
					}
M
r74  
Mr.doob 已提交
636

M
r83  
Mr.doob 已提交
637
					param.links.push( link );
M
r74  
Mr.doob 已提交
638

M
r83  
Mr.doob 已提交
639
				}
M
r74  
Mr.doob 已提交
640

M
r83  
Mr.doob 已提交
641
				iks.push( param );
M
r74  
Mr.doob 已提交
642

M
r83  
Mr.doob 已提交
643
			}
M
r74  
Mr.doob 已提交
644

M
r83  
Mr.doob 已提交
645
		} else {
M
r74  
Mr.doob 已提交
646

M
r88  
Mr.doob 已提交
647
			for ( var i = 0; i < model.metadata.boneCount; i ++ ) {
M
r74  
Mr.doob 已提交
648

M
r83  
Mr.doob 已提交
649 650
				var b = model.bones[ i ];
				var ik = b.ik;
M
r74  
Mr.doob 已提交
651

M
r83  
Mr.doob 已提交
652
				if ( ik === undefined ) {
M
r74  
Mr.doob 已提交
653

M
r83  
Mr.doob 已提交
654
					continue;
M
r74  
Mr.doob 已提交
655

M
r83  
Mr.doob 已提交
656
				}
M
r74  
Mr.doob 已提交
657

M
r83  
Mr.doob 已提交
658
				var param = {};
M
r74  
Mr.doob 已提交
659

M
r83  
Mr.doob 已提交
660 661 662 663 664
				param.target = i;
				param.effector = ik.effector;
				param.iteration = ik.iteration;
				param.maxAngle = ik.maxAngle;
				param.links = [];
M
r74  
Mr.doob 已提交
665

M
r88  
Mr.doob 已提交
666
				for ( var j = 0; j < ik.links.length; j ++ ) {
M
r74  
Mr.doob 已提交
667

M
r83  
Mr.doob 已提交
668 669 670
					var link = {};
					link.index = ik.links[ j ].index;
					link.enabled = true;
M
r74  
Mr.doob 已提交
671

M
r83  
Mr.doob 已提交
672
					if ( ik.links[ j ].angleLimitation === 1 ) {
M
r74  
Mr.doob 已提交
673

M
r83  
Mr.doob 已提交
674 675 676 677
						link.limitation = new THREE.Vector3( 1.0, 0.0, 0.0 );
						// TODO: use limitation angles
						// link.lowerLimitationAngle;
						// link.upperLimitationAngle;
M
r74  
Mr.doob 已提交
678

M
r83  
Mr.doob 已提交
679
					}
M
r74  
Mr.doob 已提交
680

M
r83  
Mr.doob 已提交
681
					param.links.push( link );
M
r74  
Mr.doob 已提交
682

M
r83  
Mr.doob 已提交
683
				}
M
r74  
Mr.doob 已提交
684

M
r83  
Mr.doob 已提交
685
				iks.push( param );
M
r74  
Mr.doob 已提交
686

M
r83  
Mr.doob 已提交
687
			}
M
r74  
Mr.doob 已提交
688

M
r83  
Mr.doob 已提交
689
		}
M
r74  
Mr.doob 已提交
690

M
r83  
Mr.doob 已提交
691
		geometry.iks = iks;
M
r74  
Mr.doob 已提交
692

M
r83  
Mr.doob 已提交
693
	};
M
r74  
Mr.doob 已提交
694

M
r83  
Mr.doob 已提交
695
	var initGrants = function () {
M
r74  
Mr.doob 已提交
696

M
r83  
Mr.doob 已提交
697
		if ( model.metadata.format === 'pmd' ) {
M
r74  
Mr.doob 已提交
698

M
r83  
Mr.doob 已提交
699
			return;
M
r74  
Mr.doob 已提交
700 701 702

		}

M
r83  
Mr.doob 已提交
703
		var grants = [];
M
r74  
Mr.doob 已提交
704

M
r88  
Mr.doob 已提交
705
		for ( var i = 0; i < model.metadata.boneCount; i ++ ) {
M
r74  
Mr.doob 已提交
706

M
r83  
Mr.doob 已提交
707 708
			var b = model.bones[ i ];
			var grant = b.grant;
M
r74  
Mr.doob 已提交
709

M
r83  
Mr.doob 已提交
710
			if ( grant === undefined ) {
M
r74  
Mr.doob 已提交
711

M
r83  
Mr.doob 已提交
712
				continue;
M
r74  
Mr.doob 已提交
713

M
r83  
Mr.doob 已提交
714
			}
M
r74  
Mr.doob 已提交
715

M
r83  
Mr.doob 已提交
716
			var param = {};
M
r74  
Mr.doob 已提交
717

M
r83  
Mr.doob 已提交
718 719 720 721 722 723 724 725 726
			param.index = i;
			param.parentIndex = grant.parentIndex;
			param.ratio = grant.ratio;
			param.isLocal = grant.isLocal;
			param.affectRotation = grant.affectRotation;
			param.affectPosition = grant.affectPosition;
			param.transformationClass = b.transformationClass;

			grants.push( param );
M
r74  
Mr.doob 已提交
727 728 729

		}

M
r83  
Mr.doob 已提交
730
		grants.sort( function ( a, b ) {
M
r74  
Mr.doob 已提交
731

M
r83  
Mr.doob 已提交
732
			return a.transformationClass - b.transformationClass;
M
r74  
Mr.doob 已提交
733

M
r83  
Mr.doob 已提交
734
		} );
M
r74  
Mr.doob 已提交
735

M
r83  
Mr.doob 已提交
736
		geometry.grants = grants;
M
r74  
Mr.doob 已提交
737 738 739

	};

M
r83  
Mr.doob 已提交
740
	var initMorphs = function () {
M
r74  
Mr.doob 已提交
741

M
r83  
Mr.doob 已提交
742
		function updateVertex( attribute, index, v, ratio ) {
M
r74  
Mr.doob 已提交
743

M
r83  
Mr.doob 已提交
744 745 746
			attribute.array[ index * 3 + 0 ] += v.position[ 0 ] * ratio;
			attribute.array[ index * 3 + 1 ] += v.position[ 1 ] * ratio;
			attribute.array[ index * 3 + 2 ] += v.position[ 2 ] * ratio;
M
r74  
Mr.doob 已提交
747

M
r83  
Mr.doob 已提交
748
		}
M
r74  
Mr.doob 已提交
749

M
r83  
Mr.doob 已提交
750
		function updateVertices( attribute, m, ratio ) {
M
r74  
Mr.doob 已提交
751

M
r88  
Mr.doob 已提交
752
			for ( var i = 0; i < m.elementCount; i ++ ) {
M
r74  
Mr.doob 已提交
753

M
r83  
Mr.doob 已提交
754
				var v = m.elements[ i ];
M
r74  
Mr.doob 已提交
755

M
r83  
Mr.doob 已提交
756
				var index;
M
r74  
Mr.doob 已提交
757

M
r83  
Mr.doob 已提交
758
				if ( model.metadata.format === 'pmd' ) {
M
r74  
Mr.doob 已提交
759

M
r83  
Mr.doob 已提交
760
					index = model.morphs[ 0 ].elements[ v.index ].index;
M
r74  
Mr.doob 已提交
761

M
r83  
Mr.doob 已提交
762
				} else {
M
r74  
Mr.doob 已提交
763

M
r83  
Mr.doob 已提交
764
					index = v.index;
M
r74  
Mr.doob 已提交
765

M
r83  
Mr.doob 已提交
766
				}
M
r74  
Mr.doob 已提交
767

M
r83  
Mr.doob 已提交
768
				updateVertex( attribute, index, v, ratio );
M
r74  
Mr.doob 已提交
769

M
r83  
Mr.doob 已提交
770
			}
M
r74  
Mr.doob 已提交
771 772 773

		}

M
r83  
Mr.doob 已提交
774 775
		var morphTargets = [];
		var attributes = [];
M
r74  
Mr.doob 已提交
776

M
r88  
Mr.doob 已提交
777
		for ( var i = 0; i < model.metadata.morphCount; i ++ ) {
M
r74  
Mr.doob 已提交
778

M
r83  
Mr.doob 已提交
779 780
			var m = model.morphs[ i ];
			var params = { name: m.name };
M
r74  
Mr.doob 已提交
781

M
r83  
Mr.doob 已提交
782
			var attribute = new THREE.Float32BufferAttribute( model.metadata.vertexCount * 3, 3 );
M
r86  
Mr.doob 已提交
783
			attribute.name = m.name;
M
r74  
Mr.doob 已提交
784

M
r88  
Mr.doob 已提交
785
			for ( var j = 0; j < model.metadata.vertexCount * 3; j ++ ) {
M
r74  
Mr.doob 已提交
786

M
r83  
Mr.doob 已提交
787
				attribute.array[ j ] = buffer.vertices[ j ];
M
r74  
Mr.doob 已提交
788

M
r83  
Mr.doob 已提交
789
			}
M
r74  
Mr.doob 已提交
790

M
r83  
Mr.doob 已提交
791
			if ( model.metadata.format === 'pmd' ) {
M
r74  
Mr.doob 已提交
792

M
r83  
Mr.doob 已提交
793
				if ( i !== 0 ) {
M
r74  
Mr.doob 已提交
794

M
r83  
Mr.doob 已提交
795
					updateVertices( attribute, m, 1.0 );
M
r74  
Mr.doob 已提交
796

M
r83  
Mr.doob 已提交
797
				}
M
r74  
Mr.doob 已提交
798

M
r83  
Mr.doob 已提交
799
			} else {
M
r74  
Mr.doob 已提交
800

M
r88  
Mr.doob 已提交
801
				if ( m.type === 0 ) { // group
M
r74  
Mr.doob 已提交
802

M
r88  
Mr.doob 已提交
803
					for ( var j = 0; j < m.elementCount; j ++ ) {
M
r74  
Mr.doob 已提交
804

M
r83  
Mr.doob 已提交
805 806
						var m2 = model.morphs[ m.elements[ j ].index ];
						var ratio = m.elements[ j ].ratio;
M
r74  
Mr.doob 已提交
807

M
r83  
Mr.doob 已提交
808
						if ( m2.type === 1 ) {
M
r74  
Mr.doob 已提交
809

M
r83  
Mr.doob 已提交
810
							updateVertices( attribute, m2, ratio );
M
r74  
Mr.doob 已提交
811

M
r83  
Mr.doob 已提交
812
						} else {
M
r74  
Mr.doob 已提交
813

M
r83  
Mr.doob 已提交
814
							// TODO: implement
M
r74  
Mr.doob 已提交
815

M
r83  
Mr.doob 已提交
816
						}
M
r74  
Mr.doob 已提交
817

M
r83  
Mr.doob 已提交
818
					}
M
r74  
Mr.doob 已提交
819

M
r88  
Mr.doob 已提交
820
				} else if ( m.type === 1 ) { // vertex
M
r74  
Mr.doob 已提交
821

M
r83  
Mr.doob 已提交
822
					updateVertices( attribute, m, 1.0 );
M
r74  
Mr.doob 已提交
823

M
r88  
Mr.doob 已提交
824
				} else if ( m.type === 2 ) { // bone
M
r74  
Mr.doob 已提交
825

M
r83  
Mr.doob 已提交
826
					// TODO: implement
M
r74  
Mr.doob 已提交
827

M
r88  
Mr.doob 已提交
828
				} else if ( m.type === 3 ) { // uv
M
r74  
Mr.doob 已提交
829

M
r83  
Mr.doob 已提交
830
					// TODO: implement
M
r74  
Mr.doob 已提交
831

M
r88  
Mr.doob 已提交
832
				} else if ( m.type === 4 ) { // additional uv1
M
r74  
Mr.doob 已提交
833

M
r83  
Mr.doob 已提交
834
					// TODO: implement
M
r74  
Mr.doob 已提交
835

M
r88  
Mr.doob 已提交
836
				} else if ( m.type === 5 ) { // additional uv2
M
r74  
Mr.doob 已提交
837

M
r83  
Mr.doob 已提交
838
					// TODO: implement
M
r74  
Mr.doob 已提交
839

M
r88  
Mr.doob 已提交
840
				} else if ( m.type === 6 ) { // additional uv3
M
r74  
Mr.doob 已提交
841

M
r83  
Mr.doob 已提交
842
					// TODO: implement
M
r74  
Mr.doob 已提交
843

M
r88  
Mr.doob 已提交
844
				} else if ( m.type === 7 ) { // additional uv4
M
r74  
Mr.doob 已提交
845

M
r83  
Mr.doob 已提交
846
					// TODO: implement
M
r74  
Mr.doob 已提交
847

M
r88  
Mr.doob 已提交
848
				} else if ( m.type === 8 ) { // material
M
r74  
Mr.doob 已提交
849

M
r83  
Mr.doob 已提交
850
					// TODO: implement
M
r74  
Mr.doob 已提交
851

M
r83  
Mr.doob 已提交
852
				}
M
r74  
Mr.doob 已提交
853

M
r83  
Mr.doob 已提交
854
			}
M
r74  
Mr.doob 已提交
855

M
r83  
Mr.doob 已提交
856 857
			morphTargets.push( params );
			attributes.push( attribute );
M
r74  
Mr.doob 已提交
858

M
r83  
Mr.doob 已提交
859
		}
M
r74  
Mr.doob 已提交
860

M
r83  
Mr.doob 已提交
861 862
		geometry.morphTargets = morphTargets;
		geometry.morphAttributes.position = attributes;
M
r74  
Mr.doob 已提交
863

M
r83  
Mr.doob 已提交
864
	};
M
r74  
Mr.doob 已提交
865

M
r83  
Mr.doob 已提交
866
	var initMaterials = function () {
M
r74  
Mr.doob 已提交
867

M
r83  
Mr.doob 已提交
868 869 870 871 872 873 874
		var textures = {};
		var textureLoader = new THREE.TextureLoader( scope.manager );
		var tgaLoader = new THREE.TGALoader( scope.manager );
		var canvas = document.createElement( 'canvas' );
		var context = canvas.getContext( '2d' );
		var offset = 0;
		var materialParams = [];
M
r74  
Mr.doob 已提交
875

M
r83  
Mr.doob 已提交
876
		if ( scope.textureCrossOrigin !== null ) textureLoader.setCrossOrigin( scope.textureCrossOrigin );
M
r74  
Mr.doob 已提交
877

M
r88  
Mr.doob 已提交
878
		function loadTexture( filePath, params ) {
M
r74  
Mr.doob 已提交
879

M
r83  
Mr.doob 已提交
880
			if ( params === undefined ) {
M
r74  
Mr.doob 已提交
881

M
r83  
Mr.doob 已提交
882
				params = {};
M
r74  
Mr.doob 已提交
883

M
r83  
Mr.doob 已提交
884
			}
M
r74  
Mr.doob 已提交
885

M
r83  
Mr.doob 已提交
886
			var fullPath;
M
r74  
Mr.doob 已提交
887

M
r83  
Mr.doob 已提交
888
			if ( params.defaultTexturePath === true ) {
M
r74  
Mr.doob 已提交
889

M
r83  
Mr.doob 已提交
890
				try {
M
r74  
Mr.doob 已提交
891

M
r83  
Mr.doob 已提交
892
					fullPath = scope.defaultToonTextures[ parseInt( filePath.match( 'toon([0-9]{2})\.bmp$' )[ 1 ] ) ];
M
r74  
Mr.doob 已提交
893

M
r83  
Mr.doob 已提交
894
				} catch ( e ) {
M
r74  
Mr.doob 已提交
895

M
r83  
Mr.doob 已提交
896 897
					console.warn( 'THREE.MMDLoader: ' + filePath + ' seems like not right default texture path. Using toon00.bmp instead.' );
					fullPath = scope.defaultToonTextures[ 0 ];
M
r74  
Mr.doob 已提交
898

M
r83  
Mr.doob 已提交
899
				}
M
r74  
Mr.doob 已提交
900

M
r83  
Mr.doob 已提交
901
			} else {
M
r74  
Mr.doob 已提交
902

M
r83  
Mr.doob 已提交
903
				fullPath = texturePath + filePath;
M
r74  
Mr.doob 已提交
904

M
r83  
Mr.doob 已提交
905
			}
M
r74  
Mr.doob 已提交
906

M
r83  
Mr.doob 已提交
907
			if ( textures[ fullPath ] !== undefined ) return fullPath;
M
r74  
Mr.doob 已提交
908

M
r83  
Mr.doob 已提交
909
			var loader = THREE.Loader.Handlers.get( fullPath );
M
r74  
Mr.doob 已提交
910

M
r83  
Mr.doob 已提交
911
			if ( loader === null ) {
M
r74  
Mr.doob 已提交
912

M
r83  
Mr.doob 已提交
913
				loader = ( filePath.indexOf( '.tga' ) >= 0 ) ? tgaLoader : textureLoader;
M
r74  
Mr.doob 已提交
914

M
r83  
Mr.doob 已提交
915
			}
M
r74  
Mr.doob 已提交
916

M
r83  
Mr.doob 已提交
917
			var texture = loader.load( fullPath, function ( t ) {
M
r74  
Mr.doob 已提交
918

M
r83  
Mr.doob 已提交
919 920 921 922
				// MMD toon texture is Axis-Y oriented
				// but Three.js gradient map is Axis-X oriented.
				// So here replaces the toon texture image with the rotated one.
				if ( params.isToonTexture === true ) {
M
r74  
Mr.doob 已提交
923

M
r83  
Mr.doob 已提交
924 925 926
					var image = t.image;
					var width = image.width;
					var height = image.height;
M
r74  
Mr.doob 已提交
927

M
r83  
Mr.doob 已提交
928 929
					canvas.width = width;
					canvas.height = height;
M
r74  
Mr.doob 已提交
930

M
r83  
Mr.doob 已提交
931 932
					context.clearRect( 0, 0, width, height );
					context.translate( width / 2.0, height / 2.0 );
M
r88  
Mr.doob 已提交
933 934
					context.rotate( 0.5 * Math.PI ); // 90.0 * Math.PI / 180.0
					context.translate( - width / 2.0, - height / 2.0 );
M
r83  
Mr.doob 已提交
935
					context.drawImage( image, 0, 0 );
M
r74  
Mr.doob 已提交
936

M
r83  
Mr.doob 已提交
937
					t.image = context.getImageData( 0, 0, width, height );
M
r74  
Mr.doob 已提交
938

M
r83  
Mr.doob 已提交
939
				}
M
r74  
Mr.doob 已提交
940

M
r83  
Mr.doob 已提交
941 942 943
				t.flipY = false;
				t.wrapS = THREE.RepeatWrapping;
				t.wrapT = THREE.RepeatWrapping;
M
r74  
Mr.doob 已提交
944

M
r88  
Mr.doob 已提交
945
				for ( var i = 0; i < texture.readyCallbacks.length; i ++ ) {
M
r74  
Mr.doob 已提交
946

M
r83  
Mr.doob 已提交
947
					texture.readyCallbacks[ i ]( texture );
M
r74  
Mr.doob 已提交
948

M
r83  
Mr.doob 已提交
949
				}
M
r74  
Mr.doob 已提交
950

M
r83  
Mr.doob 已提交
951
				delete texture.readyCallbacks;
M
r74  
Mr.doob 已提交
952

M
r83  
Mr.doob 已提交
953
			}, onProgress, onError );
M
r74  
Mr.doob 已提交
954

M
r84  
Mr.doob 已提交
955 956 957 958 959 960
			if ( params.sphericalReflectionMapping === true ) {

				texture.mapping = THREE.SphericalReflectionMapping;

			}

M
r83  
Mr.doob 已提交
961
			texture.readyCallbacks = [];
M
r74  
Mr.doob 已提交
962

M
r83  
Mr.doob 已提交
963
			textures[ fullPath ] = texture;
M
r74  
Mr.doob 已提交
964

M
r83  
Mr.doob 已提交
965
			return fullPath;
M
r74  
Mr.doob 已提交
966

M
r83  
Mr.doob 已提交
967
		}
M
r74  
Mr.doob 已提交
968

M
r83  
Mr.doob 已提交
969
		function getTexture( name, textures ) {
M
r74  
Mr.doob 已提交
970

M
r83  
Mr.doob 已提交
971
			if ( textures[ name ] === undefined ) {
M
r74  
Mr.doob 已提交
972

M
r83  
Mr.doob 已提交
973
				console.warn( 'THREE.MMDLoader: Undefined texture', name );
M
r74  
Mr.doob 已提交
974

M
r83  
Mr.doob 已提交
975
			}
M
r74  
Mr.doob 已提交
976

M
r83  
Mr.doob 已提交
977
			return textures[ name ];
M
r74  
Mr.doob 已提交
978

M
r83  
Mr.doob 已提交
979
		}
M
r74  
Mr.doob 已提交
980

M
r88  
Mr.doob 已提交
981
		for ( var i = 0; i < model.metadata.materialCount; i ++ ) {
M
r74  
Mr.doob 已提交
982

M
r83  
Mr.doob 已提交
983 984
			var m = model.materials[ i ];
			var params = {};
M
r74  
Mr.doob 已提交
985

M
r83  
Mr.doob 已提交
986 987
			params.faceOffset = offset;
			params.faceNum = m.faceCount;
M
r74  
Mr.doob 已提交
988

M
r83  
Mr.doob 已提交
989
			offset += m.faceCount;
M
r74  
Mr.doob 已提交
990

M
r83  
Mr.doob 已提交
991
			params.name = m.name;
M
r74  
Mr.doob 已提交
992

M
r83  
Mr.doob 已提交
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
			/*
			 * Color
			 *
			 * MMD         MeshToonMaterial
			 * diffuse  -  color
			 * specular -  specular
			 * ambient  -  emissive * a
			 *               (a = 1.0 without map texture or 0.2 with map texture)
			 *
			 * MeshToonMaterial doesn't have ambient. Set it to emissive instead.
			 * It'll be too bright if material has map texture so using coef 0.2.
			 */
			params.color = new THREE.Color( m.diffuse[ 0 ], m.diffuse[ 1 ], m.diffuse[ 2 ] );
			params.opacity = m.diffuse[ 3 ];
			params.specular = new THREE.Color( m.specular[ 0 ], m.specular[ 1 ], m.specular[ 2 ] );
			params.shininess = m.shininess;
M
r74  
Mr.doob 已提交
1009

M
r83  
Mr.doob 已提交
1010
			if ( params.opacity === 1.0 ) {
M
r74  
Mr.doob 已提交
1011

M
r83  
Mr.doob 已提交
1012 1013
				params.side = THREE.FrontSide;
				params.transparent = false;
M
r74  
Mr.doob 已提交
1014 1015 1016

			} else {

M
r83  
Mr.doob 已提交
1017 1018
				params.side = THREE.DoubleSide;
				params.transparent = true;
M
r74  
Mr.doob 已提交
1019 1020 1021

			}

M
r83  
Mr.doob 已提交
1022
			if ( model.metadata.format === 'pmd' ) {
M
r74  
Mr.doob 已提交
1023

M
r83  
Mr.doob 已提交
1024
				if ( m.fileName ) {
M
r76  
Mr.doob 已提交
1025

M
r83  
Mr.doob 已提交
1026 1027
					var fileName = m.fileName;
					var fileNames = [];
M
r76  
Mr.doob 已提交
1028

M
r83  
Mr.doob 已提交
1029
					var index = fileName.lastIndexOf( '*' );
M
r74  
Mr.doob 已提交
1030

M
r83  
Mr.doob 已提交
1031
					if ( index >= 0 ) {
M
r74  
Mr.doob 已提交
1032

M
r83  
Mr.doob 已提交
1033 1034
						fileNames.push( fileName.slice( 0, index ) );
						fileNames.push( fileName.slice( index + 1 ) );
M
r74  
Mr.doob 已提交
1035

M
r83  
Mr.doob 已提交
1036
					} else {
M
r74  
Mr.doob 已提交
1037

M
r83  
Mr.doob 已提交
1038
						fileNames.push( fileName );
M
r74  
Mr.doob 已提交
1039

M
r83  
Mr.doob 已提交
1040
					}
M
r74  
Mr.doob 已提交
1041

M
r88  
Mr.doob 已提交
1042
					for ( var j = 0; j < fileNames.length; j ++ ) {
M
r74  
Mr.doob 已提交
1043

M
r83  
Mr.doob 已提交
1044
						var n = fileNames[ j ];
M
r74  
Mr.doob 已提交
1045

M
r83  
Mr.doob 已提交
1046
						if ( n.indexOf( '.sph' ) >= 0 || n.indexOf( '.spa' ) >= 0 ) {
M
r74  
Mr.doob 已提交
1047

M
r83  
Mr.doob 已提交
1048
							params.envMap = loadTexture( n, { sphericalReflectionMapping: true } );
M
r74  
Mr.doob 已提交
1049

M
r83  
Mr.doob 已提交
1050
							if ( n.indexOf( '.sph' ) >= 0 ) {
M
r74  
Mr.doob 已提交
1051

M
r83  
Mr.doob 已提交
1052
								params.envMapType = THREE.MultiplyOperation;
M
r74  
Mr.doob 已提交
1053

M
r83  
Mr.doob 已提交
1054
							} else {
M
r74  
Mr.doob 已提交
1055

M
r83  
Mr.doob 已提交
1056
								params.envMapType = THREE.AddOperation;
M
r74  
Mr.doob 已提交
1057

M
r83  
Mr.doob 已提交
1058
							}
M
r74  
Mr.doob 已提交
1059

M
r83  
Mr.doob 已提交
1060
						} else {
M
r74  
Mr.doob 已提交
1061

M
r83  
Mr.doob 已提交
1062
							params.map = loadTexture( n );
M
r74  
Mr.doob 已提交
1063

M
r83  
Mr.doob 已提交
1064
						}
M
r74  
Mr.doob 已提交
1065 1066 1067 1068 1069

					}

				}

M
r83  
Mr.doob 已提交
1070
			} else {
M
r74  
Mr.doob 已提交
1071

M
r88  
Mr.doob 已提交
1072
				if ( m.textureIndex !== - 1 ) {
M
r74  
Mr.doob 已提交
1073

M
r83  
Mr.doob 已提交
1074 1075
					var n = model.textures[ m.textureIndex ];
					params.map = loadTexture( n );
M
r74  
Mr.doob 已提交
1076

M
r83  
Mr.doob 已提交
1077
				}
M
r74  
Mr.doob 已提交
1078

M
r83  
Mr.doob 已提交
1079
				// TODO: support m.envFlag === 3
M
r88  
Mr.doob 已提交
1080
				if ( m.envTextureIndex !== - 1 && ( m.envFlag === 1 || m.envFlag == 2 ) ) {
M
r74  
Mr.doob 已提交
1081

M
r83  
Mr.doob 已提交
1082 1083
					var n = model.textures[ m.envTextureIndex ];
					params.envMap = loadTexture( n, { sphericalReflectionMapping: true } );
M
r82  
Mr.doob 已提交
1084

M
r83  
Mr.doob 已提交
1085
					if ( m.envFlag === 1 ) {
M
r82  
Mr.doob 已提交
1086

M
r83  
Mr.doob 已提交
1087
						params.envMapType = THREE.MultiplyOperation;
M
r82  
Mr.doob 已提交
1088

M
r83  
Mr.doob 已提交
1089
					} else {
M
r82  
Mr.doob 已提交
1090

M
r83  
Mr.doob 已提交
1091
						params.envMapType = THREE.AddOperation;
M
r82  
Mr.doob 已提交
1092

M
r83  
Mr.doob 已提交
1093
					}
M
r74  
Mr.doob 已提交
1094 1095 1096 1097 1098

				}

			}

M
r83  
Mr.doob 已提交
1099 1100
			var coef = ( params.map === undefined ) ? 1.0 : 0.2;
			params.emissive = new THREE.Color( m.ambient[ 0 ] * coef, m.ambient[ 1 ] * coef, m.ambient[ 2 ] * coef );
M
r74  
Mr.doob 已提交
1101

M
r83  
Mr.doob 已提交
1102
			materialParams.push( params );
M
r74  
Mr.doob 已提交
1103 1104 1105

		}

M
r88  
Mr.doob 已提交
1106
		for ( var i = 0; i < materialParams.length; i ++ ) {
M
r74  
Mr.doob 已提交
1107

M
r83  
Mr.doob 已提交
1108 1109 1110
			var p = materialParams[ i ];
			var p2 = model.materials[ i ];
			var m = new THREE.MeshToonMaterial();
M
r74  
Mr.doob 已提交
1111

M
r83  
Mr.doob 已提交
1112
			geometry.addGroup( p.faceOffset * 3, p.faceNum * 3, i );
M
r74  
Mr.doob 已提交
1113

M
r83  
Mr.doob 已提交
1114
			if ( p.name !== undefined ) m.name = p.name;
M
r74  
Mr.doob 已提交
1115

M
r83  
Mr.doob 已提交
1116 1117 1118 1119 1120 1121
			m.skinning = geometry.bones.length > 0 ? true : false;
			m.morphTargets = geometry.morphTargets.length > 0 ? true : false;
			m.lights = true;
			m.side = ( model.metadata.format === 'pmx' && ( p2.flag & 0x1 ) === 1 ) ? THREE.DoubleSide : p.side;
			m.transparent = p.transparent;
			m.fog = true;
M
r74  
Mr.doob 已提交
1122

M
r83  
Mr.doob 已提交
1123 1124 1125 1126 1127
			m.blending = THREE.CustomBlending;
			m.blendSrc = THREE.SrcAlphaFactor;
			m.blendDst = THREE.OneMinusSrcAlphaFactor;
			m.blendSrcAlpha = THREE.SrcAlphaFactor;
			m.blendDstAlpha = THREE.DstAlphaFactor;
M
r74  
Mr.doob 已提交
1128

M
r83  
Mr.doob 已提交
1129
			if ( p.map !== undefined ) {
M
r74  
Mr.doob 已提交
1130

M
r83  
Mr.doob 已提交
1131 1132
				m.faceOffset = p.faceOffset;
				m.faceNum = p.faceNum;
M
r74  
Mr.doob 已提交
1133

M
r83  
Mr.doob 已提交
1134
				// Check if this part of the texture image the material uses requires transparency
M
r88  
Mr.doob 已提交
1135
				function checkTextureTransparency( m ) {
M
r74  
Mr.doob 已提交
1136

M
r83  
Mr.doob 已提交
1137
					m.map.readyCallbacks.push( function ( t ) {
M
r74  
Mr.doob 已提交
1138

M
r83  
Mr.doob 已提交
1139
						// Is there any efficient ways?
M
r88  
Mr.doob 已提交
1140
						function createImageData( image ) {
M
r74  
Mr.doob 已提交
1141

M
r83  
Mr.doob 已提交
1142 1143 1144
							var c = document.createElement( 'canvas' );
							c.width = image.width;
							c.height = image.height;
M
r74  
Mr.doob 已提交
1145

M
r83  
Mr.doob 已提交
1146 1147
							var ctx = c.getContext( '2d' );
							ctx.drawImage( image, 0, 0 );
M
r74  
Mr.doob 已提交
1148

M
r83  
Mr.doob 已提交
1149
							return ctx.getImageData( 0, 0, c.width, c.height );
M
r74  
Mr.doob 已提交
1150

M
r83  
Mr.doob 已提交
1151
						}
M
r74  
Mr.doob 已提交
1152

M
r83  
Mr.doob 已提交
1153
						function detectTextureTransparency( image, uvs, indices ) {
M
r74  
Mr.doob 已提交
1154

M
r83  
Mr.doob 已提交
1155 1156 1157 1158
							var width = image.width;
							var height = image.height;
							var data = image.data;
							var threshold = 253;
M
r74  
Mr.doob 已提交
1159

M
r83  
Mr.doob 已提交
1160
							if ( data.length / ( width * height ) !== 4 ) {
M
r74  
Mr.doob 已提交
1161

M
r83  
Mr.doob 已提交
1162
								return false;
M
r74  
Mr.doob 已提交
1163

M
r83  
Mr.doob 已提交
1164
							}
M
r74  
Mr.doob 已提交
1165

M
r83  
Mr.doob 已提交
1166
							for ( var i = 0; i < indices.length; i += 3 ) {
M
r74  
Mr.doob 已提交
1167

M
r83  
Mr.doob 已提交
1168
								var centerUV = { x: 0.0, y: 0.0 };
M
r74  
Mr.doob 已提交
1169

M
r88  
Mr.doob 已提交
1170
								for ( var j = 0; j < 3; j ++ ) {
M
r74  
Mr.doob 已提交
1171

M
r83  
Mr.doob 已提交
1172 1173
									var index = indices[ i * 3 + j ];
									var uv = { x: uvs[ index * 2 + 0 ], y: uvs[ index * 2 + 1 ] };
M
r74  
Mr.doob 已提交
1174

M
r83  
Mr.doob 已提交
1175
									if ( getAlphaByUv( image, uv ) < threshold ) {
M
r74  
Mr.doob 已提交
1176

M
r83  
Mr.doob 已提交
1177
										return true;
M
r74  
Mr.doob 已提交
1178

M
r83  
Mr.doob 已提交
1179
									}
M
r74  
Mr.doob 已提交
1180

M
r83  
Mr.doob 已提交
1181 1182
									centerUV.x += uv.x;
									centerUV.y += uv.y;
M
r74  
Mr.doob 已提交
1183

M
r83  
Mr.doob 已提交
1184
								}
M
r74  
Mr.doob 已提交
1185

M
r83  
Mr.doob 已提交
1186 1187
								centerUV.x /= 3;
								centerUV.y /= 3;
M
r74  
Mr.doob 已提交
1188

M
r83  
Mr.doob 已提交
1189
								if ( getAlphaByUv( image, centerUV ) < threshold ) {
M
r74  
Mr.doob 已提交
1190

M
r83  
Mr.doob 已提交
1191
									return true;
M
r74  
Mr.doob 已提交
1192

M
r83  
Mr.doob 已提交
1193
								}
M
r74  
Mr.doob 已提交
1194

M
r83  
Mr.doob 已提交
1195
							}
M
r74  
Mr.doob 已提交
1196

M
r83  
Mr.doob 已提交
1197
							return false;
M
r74  
Mr.doob 已提交
1198

M
r83  
Mr.doob 已提交
1199
						}
M
r74  
Mr.doob 已提交
1200

M
r83  
Mr.doob 已提交
1201 1202 1203 1204 1205 1206 1207
						/*
						 * This method expects
						 *   t.flipY = false
						 *   t.wrapS = THREE.RepeatWrapping
						 *   t.wrapT = THREE.RepeatWrapping
						 * TODO: more precise
						 */
M
r88  
Mr.doob 已提交
1208
						function getAlphaByUv( image, uv ) {
M
r74  
Mr.doob 已提交
1209

M
r83  
Mr.doob 已提交
1210 1211
							var width = image.width;
							var height = image.height;
M
r74  
Mr.doob 已提交
1212

M
r83  
Mr.doob 已提交
1213 1214
							var x = Math.round( uv.x * width ) % width;
							var y = Math.round( uv.y * height ) % height;
M
r74  
Mr.doob 已提交
1215

M
r83  
Mr.doob 已提交
1216
							if ( x < 0 ) {
M
r74  
Mr.doob 已提交
1217

M
r83  
Mr.doob 已提交
1218
								x += width;
M
r74  
Mr.doob 已提交
1219

M
r83  
Mr.doob 已提交
1220
							}
M
r74  
Mr.doob 已提交
1221

M
r83  
Mr.doob 已提交
1222
							if ( y < 0 ) {
M
r74  
Mr.doob 已提交
1223

M
r83  
Mr.doob 已提交
1224
								y += height;
M
r74  
Mr.doob 已提交
1225

M
r83  
Mr.doob 已提交
1226
							}
M
r74  
Mr.doob 已提交
1227

M
r83  
Mr.doob 已提交
1228
							var index = y * width + x;
M
r74  
Mr.doob 已提交
1229

M
r83  
Mr.doob 已提交
1230
							return image.data[ index * 4 + 3 ];
M
r74  
Mr.doob 已提交
1231

M
r83  
Mr.doob 已提交
1232
						}
M
r74  
Mr.doob 已提交
1233

M
r83  
Mr.doob 已提交
1234 1235
						var imageData = t.image.data !== undefined ? t.image : createImageData( t.image );
						var indices = geometry.index.array.slice( m.faceOffset * 3, m.faceOffset * 3 + m.faceNum * 3 );
M
r74  
Mr.doob 已提交
1236

M
r83  
Mr.doob 已提交
1237
						if ( detectTextureTransparency( imageData, geometry.attributes.uv.array, indices ) ) m.transparent = true;
M
r74  
Mr.doob 已提交
1238

M
r83  
Mr.doob 已提交
1239 1240
						delete m.faceOffset;
						delete m.faceNum;
M
r74  
Mr.doob 已提交
1241

M
r83  
Mr.doob 已提交
1242
					} );
M
r74  
Mr.doob 已提交
1243

M
r83  
Mr.doob 已提交
1244
				}
M
r74  
Mr.doob 已提交
1245

M
r83  
Mr.doob 已提交
1246 1247
				m.map = getTexture( p.map, textures );
				checkTextureTransparency( m );
M
r74  
Mr.doob 已提交
1248

M
r83  
Mr.doob 已提交
1249
			}
M
r74  
Mr.doob 已提交
1250

M
r83  
Mr.doob 已提交
1251
			if ( p.envMap !== undefined ) {
M
r74  
Mr.doob 已提交
1252

M
r83  
Mr.doob 已提交
1253 1254
				m.envMap = getTexture( p.envMap, textures );
				m.combine = p.envMapType;
M
r74  
Mr.doob 已提交
1255

M
r83  
Mr.doob 已提交
1256
			}
M
r74  
Mr.doob 已提交
1257

M
r83  
Mr.doob 已提交
1258 1259
			m.opacity = p.opacity;
			m.color = p.color;
M
r74  
Mr.doob 已提交
1260

M
r83  
Mr.doob 已提交
1261
			if ( p.emissive !== undefined ) {
M
r74  
Mr.doob 已提交
1262

M
r83  
Mr.doob 已提交
1263
				m.emissive = p.emissive;
M
r74  
Mr.doob 已提交
1264

M
r83  
Mr.doob 已提交
1265
			}
M
r74  
Mr.doob 已提交
1266

M
r83  
Mr.doob 已提交
1267 1268
			m.specular = p.specular;
			m.shininess = Math.max( p.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
M
r74  
Mr.doob 已提交
1269

M
r83  
Mr.doob 已提交
1270
			if ( model.metadata.format === 'pmd' ) {
M
r74  
Mr.doob 已提交
1271

M
r88  
Mr.doob 已提交
1272
				function isDefaultToonTexture( n ) {
M
r74  
Mr.doob 已提交
1273

M
r83  
Mr.doob 已提交
1274
					if ( n.length !== 10 ) {
M
r74  
Mr.doob 已提交
1275

M
r83  
Mr.doob 已提交
1276
						return false;
M
r74  
Mr.doob 已提交
1277

M
r83  
Mr.doob 已提交
1278
					}
M
r74  
Mr.doob 已提交
1279

M
r83  
Mr.doob 已提交
1280
					return n.match( /toon(10|0[0-9]).bmp/ ) === null ? false : true;
M
r74  
Mr.doob 已提交
1281 1282 1283

				}

M
r83  
Mr.doob 已提交
1284 1285 1286 1287 1288 1289
				// parameters for OutlineEffect
				m.outlineParameters = {
					thickness: p2.edgeFlag === 1 ? 0.003 : 0.0,
					color: new THREE.Color( 0.0, 0.0, 0.0 ),
					alpha: 1.0
				};
M
r74  
Mr.doob 已提交
1290

M
r83  
Mr.doob 已提交
1291
				if ( m.outlineParameters.thickness === 0.0 ) m.outlineParameters.visible = false;
M
r74  
Mr.doob 已提交
1292

M
r88  
Mr.doob 已提交
1293
				var toonFileName = ( p2.toonIndex === - 1 ) ? 'toon00.bmp' : model.toonTextures[ p2.toonIndex ].fileName;
M
r83  
Mr.doob 已提交
1294 1295
				var uuid = loadTexture( toonFileName, { isToonTexture: true, defaultTexturePath: isDefaultToonTexture( toonFileName ) } );
				m.gradientMap = getTexture( uuid, textures );
M
r74  
Mr.doob 已提交
1296

M
r83  
Mr.doob 已提交
1297
			} else {
M
r74  
Mr.doob 已提交
1298

M
r83  
Mr.doob 已提交
1299 1300 1301 1302 1303 1304
				// parameters for OutlineEffect
				m.outlineParameters = {
					thickness: p2.edgeSize / 300,
					color: new THREE.Color( p2.edgeColor[ 0 ], p2.edgeColor[ 1 ], p2.edgeColor[ 2 ] ),
					alpha: p2.edgeColor[ 3 ]
				};
M
r74  
Mr.doob 已提交
1305

M
r83  
Mr.doob 已提交
1306
				if ( ( p2.flag & 0x10 ) === 0 || m.outlineParameters.thickness === 0.0 ) m.outlineParameters.visible = false;
M
r74  
Mr.doob 已提交
1307

M
r83  
Mr.doob 已提交
1308
				var toonFileName, isDefaultToon;
M
r74  
Mr.doob 已提交
1309

M
r88  
Mr.doob 已提交
1310
				if ( p2.toonIndex === - 1 || p2.toonFlag !== 0 ) {
M
r74  
Mr.doob 已提交
1311

M
r83  
Mr.doob 已提交
1312 1313 1314
					var num = p2.toonIndex + 1;
					toonFileName = 'toon' + ( num < 10 ? '0' + num : num ) + '.bmp';
					isDefaultToon = true;
M
r74  
Mr.doob 已提交
1315

M
r83  
Mr.doob 已提交
1316
				} else {
M
r74  
Mr.doob 已提交
1317

M
r83  
Mr.doob 已提交
1318 1319
					toonFileName = model.textures[ p2.toonIndex ];
					isDefaultToon = false;
M
r74  
Mr.doob 已提交
1320 1321 1322

				}

M
r83  
Mr.doob 已提交
1323 1324
				var uuid = loadTexture( toonFileName, { isToonTexture: true, defaultTexturePath: isDefaultToon } );
				m.gradientMap = getTexture( uuid, textures );
M
r74  
Mr.doob 已提交
1325 1326 1327

			}

M
r85  
Mr.doob 已提交
1328
			materials.push( m );
M
r74  
Mr.doob 已提交
1329

M
r83  
Mr.doob 已提交
1330
		}
M
r74  
Mr.doob 已提交
1331

M
r83  
Mr.doob 已提交
1332
		if ( model.metadata.format === 'pmx' ) {
M
r74  
Mr.doob 已提交
1333

M
r88  
Mr.doob 已提交
1334
			function checkAlphaMorph( morph, elements ) {
M
r74  
Mr.doob 已提交
1335

M
r83  
Mr.doob 已提交
1336
				if ( morph.type !== 8 ) {
M
r74  
Mr.doob 已提交
1337

M
r83  
Mr.doob 已提交
1338
					return;
M
r74  
Mr.doob 已提交
1339

M
r83  
Mr.doob 已提交
1340
				}
M
r74  
Mr.doob 已提交
1341

M
r88  
Mr.doob 已提交
1342
				for ( var i = 0; i < elements.length; i ++ ) {
M
r74  
Mr.doob 已提交
1343

M
r83  
Mr.doob 已提交
1344
					var e = elements[ i ];
M
r74  
Mr.doob 已提交
1345

M
r88  
Mr.doob 已提交
1346
					if ( e.index === - 1 ) {
M
r74  
Mr.doob 已提交
1347

M
r83  
Mr.doob 已提交
1348
						continue;
M
r74  
Mr.doob 已提交
1349

M
r83  
Mr.doob 已提交
1350
					}
M
r74  
Mr.doob 已提交
1351

M
r85  
Mr.doob 已提交
1352
					var m = materials[ e.index ];
M
r74  
Mr.doob 已提交
1353

M
r83  
Mr.doob 已提交
1354
					if ( m.opacity !== e.diffuse[ 3 ] ) {
M
r74  
Mr.doob 已提交
1355

M
r83  
Mr.doob 已提交
1356
						m.transparent = true;
M
r74  
Mr.doob 已提交
1357

M
r83  
Mr.doob 已提交
1358
					}
M
r74  
Mr.doob 已提交
1359

M
r83  
Mr.doob 已提交
1360
				}
M
r74  
Mr.doob 已提交
1361

M
r83  
Mr.doob 已提交
1362
			}
M
r74  
Mr.doob 已提交
1363

M
r88  
Mr.doob 已提交
1364
			for ( var i = 0; i < model.morphs.length; i ++ ) {
M
r74  
Mr.doob 已提交
1365

M
r83  
Mr.doob 已提交
1366 1367
				var morph = model.morphs[ i ];
				var elements = morph.elements;
M
r74  
Mr.doob 已提交
1368

M
r83  
Mr.doob 已提交
1369
				if ( morph.type === 0 ) {
M
r74  
Mr.doob 已提交
1370

M
r88  
Mr.doob 已提交
1371
					for ( var j = 0; j < elements.length; j ++ ) {
M
r74  
Mr.doob 已提交
1372

M
r83  
Mr.doob 已提交
1373 1374
						var morph2 = model.morphs[ elements[ j ].index ];
						var elements2 = morph2.elements;
M
r74  
Mr.doob 已提交
1375

M
r83  
Mr.doob 已提交
1376
						checkAlphaMorph( morph2, elements2 );
M
r74  
Mr.doob 已提交
1377

M
r83  
Mr.doob 已提交
1378
					}
M
r74  
Mr.doob 已提交
1379

M
r83  
Mr.doob 已提交
1380
				} else {
M
r74  
Mr.doob 已提交
1381

M
r83  
Mr.doob 已提交
1382
					checkAlphaMorph( morph, elements );
M
r74  
Mr.doob 已提交
1383

M
r83  
Mr.doob 已提交
1384
				}
M
r74  
Mr.doob 已提交
1385 1386 1387 1388 1389

			}

		}

M
r83  
Mr.doob 已提交
1390
	};
M
r74  
Mr.doob 已提交
1391

M
r83  
Mr.doob 已提交
1392
	var initPhysics = function () {
M
r74  
Mr.doob 已提交
1393

M
r83  
Mr.doob 已提交
1394 1395
		var rigidBodies = [];
		var constraints = [];
M
r74  
Mr.doob 已提交
1396

M
r88  
Mr.doob 已提交
1397
		for ( var i = 0; i < model.metadata.rigidBodyCount; i ++ ) {
M
r74  
Mr.doob 已提交
1398

M
r83  
Mr.doob 已提交
1399 1400
			var b = model.rigidBodies[ i ];
			var keys = Object.keys( b );
M
r74  
Mr.doob 已提交
1401

M
r83  
Mr.doob 已提交
1402
			var p = {};
M
r74  
Mr.doob 已提交
1403

M
r88  
Mr.doob 已提交
1404
			for ( var j = 0; j < keys.length; j ++ ) {
M
r74  
Mr.doob 已提交
1405

M
r83  
Mr.doob 已提交
1406 1407
				var key = keys[ j ];
				p[ key ] = b[ key ];
M
r74  
Mr.doob 已提交
1408

M
r83  
Mr.doob 已提交
1409
			}
M
r74  
Mr.doob 已提交
1410

M
r83  
Mr.doob 已提交
1411 1412 1413 1414 1415 1416
			/*
			 * RigidBody position parameter in PMX seems global position
			 * while the one in PMD seems offset from corresponding bone.
			 * So unify being offset.
			 */
			if ( model.metadata.format === 'pmx' ) {
M
r74  
Mr.doob 已提交
1417

M
r88  
Mr.doob 已提交
1418
				if ( p.boneIndex !== - 1 ) {
M
r74  
Mr.doob 已提交
1419

M
r83  
Mr.doob 已提交
1420 1421 1422 1423
					var bone = model.bones[ p.boneIndex ];
					p.position[ 0 ] -= bone.position[ 0 ];
					p.position[ 1 ] -= bone.position[ 1 ];
					p.position[ 2 ] -= bone.position[ 2 ];
M
r74  
Mr.doob 已提交
1424

M
r83  
Mr.doob 已提交
1425
				}
M
r74  
Mr.doob 已提交
1426 1427 1428

			}

M
r83  
Mr.doob 已提交
1429 1430
			rigidBodies.push( p );

M
r74  
Mr.doob 已提交
1431 1432
		}

M
r88  
Mr.doob 已提交
1433
		for ( var i = 0; i < model.metadata.constraintCount; i ++ ) {
M
r74  
Mr.doob 已提交
1434

M
r83  
Mr.doob 已提交
1435 1436
			var c = model.constraints[ i ];
			var keys = Object.keys( c );
M
r74  
Mr.doob 已提交
1437

M
r83  
Mr.doob 已提交
1438
			var p = {};
M
r74  
Mr.doob 已提交
1439

M
r88  
Mr.doob 已提交
1440
			for ( var j = 0; j < keys.length; j ++ ) {
M
r74  
Mr.doob 已提交
1441

M
r83  
Mr.doob 已提交
1442 1443
				var key = keys[ j ];
				p[ key ] = c[ key ];
M
r74  
Mr.doob 已提交
1444

M
r83  
Mr.doob 已提交
1445
			}
M
r74  
Mr.doob 已提交
1446

M
r83  
Mr.doob 已提交
1447 1448
			var bodyA = rigidBodies[ p.rigidBodyIndex1 ];
			var bodyB = rigidBodies[ p.rigidBodyIndex2 ];
M
r74  
Mr.doob 已提交
1449

M
r83  
Mr.doob 已提交
1450 1451 1452 1453
			/*
			 * Refer to http://www20.atpages.jp/katwat/wp/?p=4135
			 */
			if ( bodyA.type !== 0 && bodyB.type === 2 ) {
M
r74  
Mr.doob 已提交
1454

M
r88  
Mr.doob 已提交
1455
				if ( bodyA.boneIndex !== - 1 && bodyB.boneIndex !== - 1 &&
M
r83  
Mr.doob 已提交
1456
				     model.bones[ bodyB.boneIndex ].parentIndex === bodyA.boneIndex ) {
M
r74  
Mr.doob 已提交
1457

M
r83  
Mr.doob 已提交
1458
					bodyB.type = 1;
M
r74  
Mr.doob 已提交
1459 1460 1461

				}

M
r83  
Mr.doob 已提交
1462
			}
M
r74  
Mr.doob 已提交
1463

M
r83  
Mr.doob 已提交
1464
			constraints.push( p );
M
r74  
Mr.doob 已提交
1465

M
r83  
Mr.doob 已提交
1466
		}
M
r74  
Mr.doob 已提交
1467

M
r83  
Mr.doob 已提交
1468 1469
		geometry.rigidBodies = rigidBodies;
		geometry.constraints = constraints;
M
r74  
Mr.doob 已提交
1470

M
r83  
Mr.doob 已提交
1471
	};
M
r74  
Mr.doob 已提交
1472

M
r83  
Mr.doob 已提交
1473
	var initGeometry = function () {
M
r74  
Mr.doob 已提交
1474

M
r84  
Mr.doob 已提交
1475
		geometry.setIndex( buffer.indices );
M
r83  
Mr.doob 已提交
1476 1477 1478 1479 1480
		geometry.addAttribute( 'position', new THREE.Float32BufferAttribute( buffer.vertices, 3 ) );
		geometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( buffer.normals, 3 ) );
		geometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( buffer.uvs, 2 ) );
		geometry.addAttribute( 'skinIndex', new THREE.Float32BufferAttribute( buffer.skinIndices, 4 ) );
		geometry.addAttribute( 'skinWeight', new THREE.Float32BufferAttribute( buffer.skinWeights, 4 ) );
M
r74  
Mr.doob 已提交
1481

M
r83  
Mr.doob 已提交
1482 1483
		geometry.computeBoundingSphere();
		geometry.mmdFormat = model.metadata.format;
M
r74  
Mr.doob 已提交
1484

M
r83  
Mr.doob 已提交
1485
	};
M
r74  
Mr.doob 已提交
1486

M
r83  
Mr.doob 已提交
1487 1488 1489 1490 1491 1492 1493 1494 1495
	initVartices();
	initFaces();
	initBones();
	initIKs();
	initGrants();
	initMorphs();
	initMaterials();
	initPhysics();
	initGeometry();
M
r74  
Mr.doob 已提交
1496

M
r85  
Mr.doob 已提交
1497
	var mesh = new THREE.SkinnedMesh( geometry, materials );
M
r74  
Mr.doob 已提交
1498

M
r83  
Mr.doob 已提交
1499
	// console.log( mesh ); // for console debug
M
r74  
Mr.doob 已提交
1500

M
r83  
Mr.doob 已提交
1501
	return mesh;
M
r74  
Mr.doob 已提交
1502

M
r83  
Mr.doob 已提交
1503
};
M
r74  
Mr.doob 已提交
1504

M
r83  
Mr.doob 已提交
1505
THREE.MMDLoader.prototype.createAnimation = function ( mesh, vmd, name ) {
M
r74  
Mr.doob 已提交
1506

M
r83  
Mr.doob 已提交
1507
	var helper = new THREE.MMDLoader.DataCreationHelper();
M
r74  
Mr.doob 已提交
1508

M
r83  
Mr.doob 已提交
1509
	var initMotionAnimations = function () {
M
r74  
Mr.doob 已提交
1510

M
r83  
Mr.doob 已提交
1511
		if ( vmd.metadata.motionCount === 0 ) {
M
r74  
Mr.doob 已提交
1512

M
r83  
Mr.doob 已提交
1513
			return;
M
r74  
Mr.doob 已提交
1514

M
r83  
Mr.doob 已提交
1515
		}
M
r74  
Mr.doob 已提交
1516

M
r83  
Mr.doob 已提交
1517 1518
		var bones = mesh.geometry.bones;
		var orderedMotions = helper.createOrderedMotionArrays( bones, vmd.motions, 'boneName' );
M
r74  
Mr.doob 已提交
1519

M
r83  
Mr.doob 已提交
1520
		var tracks = [];
M
r74  
Mr.doob 已提交
1521

M
r83  
Mr.doob 已提交
1522
		var pushInterpolation = function ( array, interpolation, index ) {
M
r74  
Mr.doob 已提交
1523

M
r88  
Mr.doob 已提交
1524 1525 1526
			array.push( interpolation[ index + 0 ] / 127 ); // x1
			array.push( interpolation[ index + 8 ] / 127 ); // x2
			array.push( interpolation[ index + 4 ] / 127 ); // y1
M
r83  
Mr.doob 已提交
1527
			array.push( interpolation[ index + 12 ] / 127 ); // y2
M
r74  
Mr.doob 已提交
1528

M
r83  
Mr.doob 已提交
1529
		};
M
r74  
Mr.doob 已提交
1530

M
r88  
Mr.doob 已提交
1531
		for ( var i = 0; i < orderedMotions.length; i ++ ) {
M
r74  
Mr.doob 已提交
1532

M
r83  
Mr.doob 已提交
1533 1534 1535 1536 1537
			var times = [];
			var positions = [];
			var rotations = [];
			var pInterpolations = [];
			var rInterpolations = [];
M
r74  
Mr.doob 已提交
1538

M
r83  
Mr.doob 已提交
1539 1540
			var bone = bones[ i ];
			var array = orderedMotions[ i ];
M
r74  
Mr.doob 已提交
1541

M
r88  
Mr.doob 已提交
1542
			for ( var j = 0; j < array.length; j ++ ) {
M
r74  
Mr.doob 已提交
1543

M
r83  
Mr.doob 已提交
1544 1545 1546 1547
				var time = array[ j ].frameNum / 30;
				var pos = array[ j ].position;
				var rot = array[ j ].rotation;
				var interpolation = array[ j ].interpolation;
M
r74  
Mr.doob 已提交
1548

M
r83  
Mr.doob 已提交
1549
				times.push( time );
M
r74  
Mr.doob 已提交
1550

M
r83  
Mr.doob 已提交
1551
				for ( var k = 0; k < 3; k ++ ) {
M
r74  
Mr.doob 已提交
1552

M
r83  
Mr.doob 已提交
1553
					positions.push( bone.pos[ k ] + pos[ k ] );
M
r74  
Mr.doob 已提交
1554

M
r83  
Mr.doob 已提交
1555
				}
M
r74  
Mr.doob 已提交
1556

M
r83  
Mr.doob 已提交
1557
				for ( var k = 0; k < 4; k ++ ) {
M
r74  
Mr.doob 已提交
1558

M
r83  
Mr.doob 已提交
1559
					rotations.push( rot[ k ] );
M
r74  
Mr.doob 已提交
1560

M
r83  
Mr.doob 已提交
1561
				}
M
r74  
Mr.doob 已提交
1562

M
r83  
Mr.doob 已提交
1563
				for ( var k = 0; k < 3; k ++ ) {
M
r74  
Mr.doob 已提交
1564

M
r83  
Mr.doob 已提交
1565
					pushInterpolation( pInterpolations, interpolation, k );
M
r74  
Mr.doob 已提交
1566

M
r83  
Mr.doob 已提交
1567
				}
M
r74  
Mr.doob 已提交
1568

M
r83  
Mr.doob 已提交
1569
				pushInterpolation( rInterpolations, interpolation, 3 );
M
r74  
Mr.doob 已提交
1570

M
r83  
Mr.doob 已提交
1571
			}
M
r74  
Mr.doob 已提交
1572

M
r83  
Mr.doob 已提交
1573
			if ( times.length === 0 ) continue;
M
r74  
Mr.doob 已提交
1574

M
r83  
Mr.doob 已提交
1575
			var boneName = '.bones[' + bone.name + ']';
M
r74  
Mr.doob 已提交
1576

M
r83  
Mr.doob 已提交
1577 1578
			tracks.push( new THREE.MMDLoader.VectorKeyframeTrackEx( boneName + '.position', times, positions, pInterpolations ) );
			tracks.push( new THREE.MMDLoader.QuaternionKeyframeTrackEx( boneName + '.quaternion', times, rotations, rInterpolations ) );
M
r74  
Mr.doob 已提交
1579

M
r83  
Mr.doob 已提交
1580
		}
M
r74  
Mr.doob 已提交
1581

M
r88  
Mr.doob 已提交
1582
		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name, - 1, tracks );
M
r74  
Mr.doob 已提交
1583

M
r86  
Mr.doob 已提交
1584 1585
		if ( mesh.geometry.animations === undefined ) mesh.geometry.animations = [];
		mesh.geometry.animations.push( clip );
M
r74  
Mr.doob 已提交
1586

M
r83  
Mr.doob 已提交
1587
	};
M
r74  
Mr.doob 已提交
1588

M
r83  
Mr.doob 已提交
1589
	var initMorphAnimations = function () {
M
r74  
Mr.doob 已提交
1590

M
r83  
Mr.doob 已提交
1591
		if ( vmd.metadata.morphCount === 0 ) {
M
r74  
Mr.doob 已提交
1592

M
r83  
Mr.doob 已提交
1593
			return;
M
r74  
Mr.doob 已提交
1594

M
r83  
Mr.doob 已提交
1595
		}
M
r74  
Mr.doob 已提交
1596

M
r83  
Mr.doob 已提交
1597
		var orderedMorphs = helper.createOrderedMotionArrays( mesh.geometry.morphTargets, vmd.morphs, 'morphName' );
M
r74  
Mr.doob 已提交
1598

M
r83  
Mr.doob 已提交
1599
		var tracks = [];
M
r74  
Mr.doob 已提交
1600

M
r88  
Mr.doob 已提交
1601
		for ( var i = 0; i < orderedMorphs.length; i ++ ) {
M
r74  
Mr.doob 已提交
1602

M
r83  
Mr.doob 已提交
1603 1604 1605
			var times = [];
			var values = [];
			var array = orderedMorphs[ i ];
M
r74  
Mr.doob 已提交
1606

M
r88  
Mr.doob 已提交
1607
			for ( var j = 0; j < array.length; j ++ ) {
M
r74  
Mr.doob 已提交
1608

M
r83  
Mr.doob 已提交
1609 1610
				times.push( array[ j ].frameNum / 30 );
				values.push( array[ j ].weight );
M
r74  
Mr.doob 已提交
1611

M
r83  
Mr.doob 已提交
1612
			}
M
r74  
Mr.doob 已提交
1613

M
r83  
Mr.doob 已提交
1614
			if ( times.length === 0 ) continue;
M
r74  
Mr.doob 已提交
1615

M
r83  
Mr.doob 已提交
1616
			tracks.push( new THREE.NumberKeyframeTrack( '.morphTargetInfluences[' + i + ']', times, values ) );
M
r74  
Mr.doob 已提交
1617

M
r83  
Mr.doob 已提交
1618
		}
M
r74  
Mr.doob 已提交
1619

M
r88  
Mr.doob 已提交
1620
		var clip = new THREE.AnimationClip( name === undefined ? THREE.Math.generateUUID() : name + 'Morph', - 1, tracks );
M
r74  
Mr.doob 已提交
1621

M
r86  
Mr.doob 已提交
1622 1623
		if ( mesh.geometry.animations === undefined ) mesh.geometry.animations = [];
		mesh.geometry.animations.push( clip );
M
r74  
Mr.doob 已提交
1624

M
r83  
Mr.doob 已提交
1625
	};
M
r74  
Mr.doob 已提交
1626

M
r83  
Mr.doob 已提交
1627 1628
	initMotionAnimations();
	initMorphAnimations();
M
r74  
Mr.doob 已提交
1629

M
r83  
Mr.doob 已提交
1630
};
M
r74  
Mr.doob 已提交
1631

M
r83  
Mr.doob 已提交
1632
THREE.MMDLoader.DataCreationHelper = function () {
M
r74  
Mr.doob 已提交
1633

M
r83  
Mr.doob 已提交
1634
};
M
r74  
Mr.doob 已提交
1635

M
r83  
Mr.doob 已提交
1636
THREE.MMDLoader.DataCreationHelper.prototype = {
M
r74  
Mr.doob 已提交
1637

M
r83  
Mr.doob 已提交
1638
	constructor: THREE.MMDLoader.DataCreationHelper,
M
r74  
Mr.doob 已提交
1639

M
r83  
Mr.doob 已提交
1640
	/*
M
r86  
Mr.doob 已提交
1641
	 * Note: Sometimes to use Japanese Unicode characters runs into problems in Three.js.
M
r83  
Mr.doob 已提交
1642
	 *       In such a case, use this method to convert it to Unicode hex charcode strings,
M
r86  
Mr.doob 已提交
1643 1644 1645
	 *       like 'あいう' -> '0x30420x30440x3046'
	 */

M
r83  
Mr.doob 已提交
1646
	toCharcodeStrings: function ( s ) {
M
r74  
Mr.doob 已提交
1647

M
r83  
Mr.doob 已提交
1648
		var str = '';
M
r74  
Mr.doob 已提交
1649

M
r88  
Mr.doob 已提交
1650
		for ( var i = 0; i < s.length; i ++ ) {
M
r74  
Mr.doob 已提交
1651

M
r88  
Mr.doob 已提交
1652
			str += '0x' + ( '0000' + s[ i ].charCodeAt().toString( 16 ) ).substr( - 4 );
M
r74  
Mr.doob 已提交
1653 1654 1655

		}

M
r83  
Mr.doob 已提交
1656
		return str;
M
r74  
Mr.doob 已提交
1657 1658 1659

	},

M
r83  
Mr.doob 已提交
1660
	createDictionary: function ( array ) {
M
r74  
Mr.doob 已提交
1661

M
r83  
Mr.doob 已提交
1662
		var dict = {};
M
r74  
Mr.doob 已提交
1663

M
r88  
Mr.doob 已提交
1664
		for ( var i = 0; i < array.length; i ++ ) {
M
r74  
Mr.doob 已提交
1665

M
r83  
Mr.doob 已提交
1666
			dict[ array[ i ].name ] = i;
M
r74  
Mr.doob 已提交
1667

M
r83  
Mr.doob 已提交
1668
		}
M
r74  
Mr.doob 已提交
1669

M
r83  
Mr.doob 已提交
1670
		return dict;
M
r74  
Mr.doob 已提交
1671

M
r83  
Mr.doob 已提交
1672
	},
M
r74  
Mr.doob 已提交
1673

M
r83  
Mr.doob 已提交
1674
	initializeMotionArrays: function ( array ) {
M
r74  
Mr.doob 已提交
1675

M
r83  
Mr.doob 已提交
1676
		var result = [];
M
r74  
Mr.doob 已提交
1677

M
r88  
Mr.doob 已提交
1678
		for ( var i = 0; i < array.length; i ++ ) {
M
r74  
Mr.doob 已提交
1679

M
r83  
Mr.doob 已提交
1680 1681 1682
			result[ i ] = [];

		}
M
r74  
Mr.doob 已提交
1683

M
r83  
Mr.doob 已提交
1684
		return result;
M
r74  
Mr.doob 已提交
1685 1686 1687

	},

M
r83  
Mr.doob 已提交
1688
	sortMotionArray: function ( array ) {
M
r74  
Mr.doob 已提交
1689

M
r83  
Mr.doob 已提交
1690
		array.sort( function ( a, b ) {
M
r74  
Mr.doob 已提交
1691

M
r83  
Mr.doob 已提交
1692
			return a.frameNum - b.frameNum;
M
r74  
Mr.doob 已提交
1693

M
r88  
Mr.doob 已提交
1694
		} );
M
r74  
Mr.doob 已提交
1695

M
r83  
Mr.doob 已提交
1696
	},
M
r74  
Mr.doob 已提交
1697

M
r83  
Mr.doob 已提交
1698
	sortMotionArrays: function ( arrays ) {
M
r74  
Mr.doob 已提交
1699

M
r88  
Mr.doob 已提交
1700
		for ( var i = 0; i < arrays.length; i ++ ) {
M
r74  
Mr.doob 已提交
1701

M
r83  
Mr.doob 已提交
1702
			this.sortMotionArray( arrays[ i ] );
M
r74  
Mr.doob 已提交
1703

M
r83  
Mr.doob 已提交
1704
		}
M
r74  
Mr.doob 已提交
1705 1706 1707

	},

M
r83  
Mr.doob 已提交
1708
	createMotionArray: function ( array ) {
M
r74  
Mr.doob 已提交
1709

M
r83  
Mr.doob 已提交
1710
		var result = [];
M
r74  
Mr.doob 已提交
1711

M
r88  
Mr.doob 已提交
1712
		for ( var i = 0; i < array.length; i ++ ) {
M
r74  
Mr.doob 已提交
1713

M
r83  
Mr.doob 已提交
1714
			result.push( array[ i ] );
M
r74  
Mr.doob 已提交
1715 1716 1717

		}

M
r83  
Mr.doob 已提交
1718
		return result;
M
r74  
Mr.doob 已提交
1719 1720 1721

	},

M
r83  
Mr.doob 已提交
1722
	createMotionArrays: function ( array, result, dict, key ) {
M
r74  
Mr.doob 已提交
1723

M
r88  
Mr.doob 已提交
1724
		for ( var i = 0; i < array.length; i ++ ) {
M
r74  
Mr.doob 已提交
1725

M
r83  
Mr.doob 已提交
1726 1727
			var a = array[ i ];
			var num = dict[ a[ key ] ];
M
r74  
Mr.doob 已提交
1728

M
r83  
Mr.doob 已提交
1729
			if ( num === undefined ) {
M
r74  
Mr.doob 已提交
1730

M
r83  
Mr.doob 已提交
1731
				continue;
M
r74  
Mr.doob 已提交
1732

M
r83  
Mr.doob 已提交
1733
			}
M
r74  
Mr.doob 已提交
1734

M
r83  
Mr.doob 已提交
1735
			result[ num ].push( a );
M
r74  
Mr.doob 已提交
1736 1737 1738 1739 1740

		}

	},

M
r83  
Mr.doob 已提交
1741
	createOrderedMotionArray: function ( array ) {
M
r74  
Mr.doob 已提交
1742

M
r83  
Mr.doob 已提交
1743 1744 1745
		var result = this.createMotionArray( array );
		this.sortMotionArray( result );
		return result;
M
r74  
Mr.doob 已提交
1746

M
r83  
Mr.doob 已提交
1747
	},
M
r74  
Mr.doob 已提交
1748

M
r83  
Mr.doob 已提交
1749
	createOrderedMotionArrays: function ( targetArray, motionArray, key ) {
M
r74  
Mr.doob 已提交
1750

M
r83  
Mr.doob 已提交
1751 1752 1753 1754
		var dict = this.createDictionary( targetArray );
		var result = this.initializeMotionArrays( targetArray );
		this.createMotionArrays( motionArray, result, dict, key );
		this.sortMotionArrays( result );
M
r74  
Mr.doob 已提交
1755

M
r83  
Mr.doob 已提交
1756
		return result;
M
r74  
Mr.doob 已提交
1757

M
r83  
Mr.doob 已提交
1758
	}
M
r74  
Mr.doob 已提交
1759

M
r83  
Mr.doob 已提交
1760
};
M
r74  
Mr.doob 已提交
1761

M
r83  
Mr.doob 已提交
1762 1763 1764 1765 1766 1767
/*
 * extends existing KeyframeTrack for bone and camera animation.
 *   - use Float64Array for times
 *   - use Cubic Bezier curves interpolation
 */
THREE.MMDLoader.VectorKeyframeTrackEx = function ( name, times, values, interpolationParameterArray ) {
M
r74  
Mr.doob 已提交
1768

M
r83  
Mr.doob 已提交
1769
	this.interpolationParameters = new Float32Array( interpolationParameterArray );
M
r74  
Mr.doob 已提交
1770

M
r83  
Mr.doob 已提交
1771
	THREE.VectorKeyframeTrack.call( this, name, times, values );
M
r74  
Mr.doob 已提交
1772

M
r83  
Mr.doob 已提交
1773
};
M
r74  
Mr.doob 已提交
1774

M
r83  
Mr.doob 已提交
1775 1776 1777
THREE.MMDLoader.VectorKeyframeTrackEx.prototype = Object.create( THREE.VectorKeyframeTrack.prototype );
THREE.MMDLoader.VectorKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.VectorKeyframeTrackEx;
THREE.MMDLoader.VectorKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
M
r74  
Mr.doob 已提交
1778

M
r88  
Mr.doob 已提交
1779
THREE.MMDLoader.VectorKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function ( result ) {
M
r74  
Mr.doob 已提交
1780

M
r83  
Mr.doob 已提交
1781
	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
M
r74  
Mr.doob 已提交
1782

M
r83  
Mr.doob 已提交
1783
};
M
r74  
Mr.doob 已提交
1784

M
r88  
Mr.doob 已提交
1785
THREE.MMDLoader.VectorKeyframeTrackEx.prototype.setInterpolation = function ( interpolation ) {
M
r74  
Mr.doob 已提交
1786

M
r83  
Mr.doob 已提交
1787
	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
M
r74  
Mr.doob 已提交
1788

M
r83  
Mr.doob 已提交
1789
};
M
r74  
Mr.doob 已提交
1790

M
r83  
Mr.doob 已提交
1791
THREE.MMDLoader.QuaternionKeyframeTrackEx = function ( name, times, values, interpolationParameterArray ) {
M
r74  
Mr.doob 已提交
1792

M
r83  
Mr.doob 已提交
1793
	this.interpolationParameters = new Float32Array( interpolationParameterArray );
M
r74  
Mr.doob 已提交
1794

M
r83  
Mr.doob 已提交
1795
	THREE.QuaternionKeyframeTrack.call( this, name, times, values );
M
r74  
Mr.doob 已提交
1796

M
r83  
Mr.doob 已提交
1797
};
M
r74  
Mr.doob 已提交
1798

M
r83  
Mr.doob 已提交
1799 1800 1801
THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype = Object.create( THREE.QuaternionKeyframeTrack.prototype );
THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.QuaternionKeyframeTrackEx;
THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
M
r74  
Mr.doob 已提交
1802

M
r88  
Mr.doob 已提交
1803
THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function ( result ) {
M
r74  
Mr.doob 已提交
1804

M
r83  
Mr.doob 已提交
1805
	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
M
r74  
Mr.doob 已提交
1806

M
r83  
Mr.doob 已提交
1807
};
M
r74  
Mr.doob 已提交
1808

M
r88  
Mr.doob 已提交
1809
THREE.MMDLoader.QuaternionKeyframeTrackEx.prototype.setInterpolation = function ( interpolation ) {
M
r74  
Mr.doob 已提交
1810

M
r83  
Mr.doob 已提交
1811
	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
M
r74  
Mr.doob 已提交
1812

M
r83  
Mr.doob 已提交
1813
};
M
r74  
Mr.doob 已提交
1814

M
r83  
Mr.doob 已提交
1815
THREE.MMDLoader.NumberKeyframeTrackEx = function ( name, times, values, interpolationParameterArray ) {
M
r74  
Mr.doob 已提交
1816

M
r83  
Mr.doob 已提交
1817
	this.interpolationParameters = new Float32Array( interpolationParameterArray );
M
r74  
Mr.doob 已提交
1818

M
r83  
Mr.doob 已提交
1819
	THREE.NumberKeyframeTrack.call( this, name, times, values );
M
r74  
Mr.doob 已提交
1820

M
r83  
Mr.doob 已提交
1821
};
M
r74  
Mr.doob 已提交
1822

M
r83  
Mr.doob 已提交
1823 1824 1825
THREE.MMDLoader.NumberKeyframeTrackEx.prototype = Object.create( THREE.NumberKeyframeTrack.prototype );
THREE.MMDLoader.NumberKeyframeTrackEx.prototype.constructor = THREE.MMDLoader.NumberKeyframeTrackEx;
THREE.MMDLoader.NumberKeyframeTrackEx.prototype.TimeBufferType = Float64Array;
M
r74  
Mr.doob 已提交
1826

M
r88  
Mr.doob 已提交
1827
THREE.MMDLoader.NumberKeyframeTrackEx.prototype.InterpolantFactoryMethodCubicBezier = function ( result ) {
M
r74  
Mr.doob 已提交
1828

M
r83  
Mr.doob 已提交
1829
	return new THREE.MMDLoader.CubicBezierInterpolation( this.times, this.values, this.getValueSize(), result, this.interpolationParameters );
M
r74  
Mr.doob 已提交
1830

M
r83  
Mr.doob 已提交
1831
};
M
r74  
Mr.doob 已提交
1832

M
r88  
Mr.doob 已提交
1833
THREE.MMDLoader.NumberKeyframeTrackEx.prototype.setInterpolation = function ( interpolation ) {
M
r74  
Mr.doob 已提交
1834

M
r83  
Mr.doob 已提交
1835
	this.createInterpolant = this.InterpolantFactoryMethodCubicBezier;
M
r74  
Mr.doob 已提交
1836

M
r83  
Mr.doob 已提交
1837
};
M
r74  
Mr.doob 已提交
1838

M
r83  
Mr.doob 已提交
1839
THREE.MMDLoader.CubicBezierInterpolation = function ( parameterPositions, sampleValues, sampleSize, resultBuffer, params ) {
M
r74  
Mr.doob 已提交
1840

M
r83  
Mr.doob 已提交
1841
	THREE.Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
M
r74  
Mr.doob 已提交
1842

M
r83  
Mr.doob 已提交
1843
	this.params = params;
M
r74  
Mr.doob 已提交
1844

M
r88  
Mr.doob 已提交
1845
};
M
r74  
Mr.doob 已提交
1846

M
r83  
Mr.doob 已提交
1847 1848
THREE.MMDLoader.CubicBezierInterpolation.prototype = Object.create( THREE.LinearInterpolant.prototype );
THREE.MMDLoader.CubicBezierInterpolation.prototype.constructor = THREE.MMDLoader.CubicBezierInterpolation;
M
r74  
Mr.doob 已提交
1849

M
r88  
Mr.doob 已提交
1850
THREE.MMDLoader.CubicBezierInterpolation.prototype.interpolate_ = function ( i1, t0, t, t1 ) {
M
r74  
Mr.doob 已提交
1851

M
r83  
Mr.doob 已提交
1852 1853 1854
	var result = this.resultBuffer;
	var values = this.sampleValues;
	var stride = this.valueSize;
M
r74  
Mr.doob 已提交
1855

M
r83  
Mr.doob 已提交
1856 1857
	var offset1 = i1 * stride;
	var offset0 = offset1 - stride;
M
r74  
Mr.doob 已提交
1858

M
r83  
Mr.doob 已提交
1859
	var weight1 = ( t - t0 ) / ( t1 - t0 );
M
r74  
Mr.doob 已提交
1860

M
r88  
Mr.doob 已提交
1861
	if ( stride === 4 ) { // Quaternion
M
r74  
Mr.doob 已提交
1862

M
r83  
Mr.doob 已提交
1863 1864 1865 1866
		var x1 = this.params[ i1 * 4 + 0 ];
		var x2 = this.params[ i1 * 4 + 1 ];
		var y1 = this.params[ i1 * 4 + 2 ];
		var y2 = this.params[ i1 * 4 + 3 ];
M
r74  
Mr.doob 已提交
1867

M
r83  
Mr.doob 已提交
1868
		var ratio = this._calculate( x1, x2, y1, y2, weight1 );
M
r74  
Mr.doob 已提交
1869

M
r83  
Mr.doob 已提交
1870
		THREE.Quaternion.slerpFlat( result, 0, values, offset0, values, offset1, ratio );
M
r74  
Mr.doob 已提交
1871

M
r88  
Mr.doob 已提交
1872
	} else if ( stride === 3 ) { // Vector3
M
r74  
Mr.doob 已提交
1873

M
r83  
Mr.doob 已提交
1874
		for ( var i = 0; i !== stride; ++ i ) {
M
r74  
Mr.doob 已提交
1875

M
r83  
Mr.doob 已提交
1876 1877 1878 1879
			var x1 = this.params[ i1 * 12 + i * 4 + 0 ];
			var x2 = this.params[ i1 * 12 + i * 4 + 1 ];
			var y1 = this.params[ i1 * 12 + i * 4 + 2 ];
			var y2 = this.params[ i1 * 12 + i * 4 + 3 ];
M
r74  
Mr.doob 已提交
1880

M
r83  
Mr.doob 已提交
1881
			var ratio = this._calculate( x1, x2, y1, y2, weight1 );
M
r74  
Mr.doob 已提交
1882

M
r83  
Mr.doob 已提交
1883
			result[ i ] = values[ offset0 + i ] * ( 1 - ratio ) + values[ offset1 + i ] * ratio;
M
r74  
Mr.doob 已提交
1884

M
r83  
Mr.doob 已提交
1885
		}
M
r74  
Mr.doob 已提交
1886

M
r88  
Mr.doob 已提交
1887
	} else { // Number
M
r74  
Mr.doob 已提交
1888

M
r83  
Mr.doob 已提交
1889 1890 1891 1892
		var x1 = this.params[ i1 * 4 + 0 ];
		var x2 = this.params[ i1 * 4 + 1 ];
		var y1 = this.params[ i1 * 4 + 2 ];
		var y2 = this.params[ i1 * 4 + 3 ];
M
r74  
Mr.doob 已提交
1893

M
r83  
Mr.doob 已提交
1894
		var ratio = this._calculate( x1, x2, y1, y2, weight1 );
M
r74  
Mr.doob 已提交
1895

M
r83  
Mr.doob 已提交
1896
		result[ 0 ] = values[ offset0 ] * ( 1 - ratio ) + values[ offset1 ] * ratio;
M
r74  
Mr.doob 已提交
1897

M
r83  
Mr.doob 已提交
1898 1899 1900
	}

	return result;
M
r74  
Mr.doob 已提交
1901

M
r83  
Mr.doob 已提交
1902
};
M
r74  
Mr.doob 已提交
1903

M
r88  
Mr.doob 已提交
1904
THREE.MMDLoader.CubicBezierInterpolation.prototype._calculate = function ( x1, x2, y1, y2, x ) {
M
r74  
Mr.doob 已提交
1905

M
r83  
Mr.doob 已提交
1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941
	/*
	 * Cubic Bezier curves
	 *   https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves
	 *
	 * B(t) = ( 1 - t ) ^ 3 * P0
	 *      + 3 * ( 1 - t ) ^ 2 * t * P1
	 *      + 3 * ( 1 - t ) * t^2 * P2
	 *      + t ^ 3 * P3
	 *      ( 0 <= t <= 1 )
	 *
	 * MMD uses Cubic Bezier curves for bone and camera animation interpolation.
	 *   http://d.hatena.ne.jp/edvakf/20111016/1318716097
	 *
	 *    x = ( 1 - t ) ^ 3 * x0
	 *      + 3 * ( 1 - t ) ^ 2 * t * x1
	 *      + 3 * ( 1 - t ) * t^2 * x2
	 *      + t ^ 3 * x3
	 *    y = ( 1 - t ) ^ 3 * y0
	 *      + 3 * ( 1 - t ) ^ 2 * t * y1
	 *      + 3 * ( 1 - t ) * t^2 * y2
	 *      + t ^ 3 * y3
	 *      ( x0 = 0, y0 = 0 )
	 *      ( x3 = 1, y3 = 1 )
	 *      ( 0 <= t, x1, x2, y1, y2 <= 1 )
	 *
	 * Here solves this equation with Bisection method,
	 *   https://en.wikipedia.org/wiki/Bisection_method
	 * gets t, and then calculate y.
	 *
	 * f(t) = 3 * ( 1 - t ) ^ 2 * t * x1
	 *      + 3 * ( 1 - t ) * t^2 * x2
	 *      + t ^ 3 - x = 0
	 *
	 * (Another option: Newton's method
	 *    https://en.wikipedia.org/wiki/Newton%27s_method)
	 */
M
r74  
Mr.doob 已提交
1942

M
r83  
Mr.doob 已提交
1943 1944 1945 1946 1947 1948
	var c = 0.5;
	var t = c;
	var s = 1.0 - t;
	var loop = 15;
	var eps = 1e-5;
	var math = Math;
M
r74  
Mr.doob 已提交
1949

M
r83  
Mr.doob 已提交
1950
	var sst3, stt3, ttt;
M
r74  
Mr.doob 已提交
1951

M
r83  
Mr.doob 已提交
1952
	for ( var i = 0; i < loop; i ++ ) {
M
r77  
Mr.doob 已提交
1953

M
r83  
Mr.doob 已提交
1954 1955 1956
		sst3 = 3.0 * s * s * t;
		stt3 = 3.0 * s * t * t;
		ttt = t * t * t;
M
r77  
Mr.doob 已提交
1957

M
r83  
Mr.doob 已提交
1958
		var ft = ( sst3 * x1 ) + ( stt3 * x2 ) + ( ttt ) - x;
M
r77  
Mr.doob 已提交
1959

M
r83  
Mr.doob 已提交
1960
		if ( math.abs( ft ) < eps ) break;
M
r74  
Mr.doob 已提交
1961

M
r83  
Mr.doob 已提交
1962
		c /= 2.0;
M
r74  
Mr.doob 已提交
1963

M
r88  
Mr.doob 已提交
1964
		t += ( ft < 0 ) ? c : - c;
M
r83  
Mr.doob 已提交
1965
		s = 1.0 - t;
M
r74  
Mr.doob 已提交
1966

M
r83  
Mr.doob 已提交
1967
	}
M
r74  
Mr.doob 已提交
1968

M
r83  
Mr.doob 已提交
1969
	return ( sst3 * y1 ) + ( stt3 * y2 ) + ttt;
M
r74  
Mr.doob 已提交
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983

};

THREE.MMDAudioManager = function ( audio, listener, p ) {

	var params = ( p === null || p === undefined ) ? {} : p;

	this.audio = audio;
	this.listener = listener;

	this.elapsedTime = 0.0;
	this.currentTime = 0.0;
	this.delayTime = params.delayTime !== undefined ? params.delayTime : 0.0;

M
r83  
Mr.doob 已提交
1984
	this.audioDuration = this.audio.buffer.duration;
M
r74  
Mr.doob 已提交
1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057
	this.duration = this.audioDuration + this.delayTime;

};

THREE.MMDAudioManager.prototype = {

	constructor: THREE.MMDAudioManager,

	control: function ( delta ) {

		this.elapsed += delta;
		this.currentTime += delta;

		if ( this.checkIfStopAudio() ) {

			this.audio.stop();

		}

		if ( this.checkIfStartAudio() ) {

			this.audio.play();

		}

	},

	checkIfStartAudio: function () {

		if ( this.audio.isPlaying ) {

			return false;

		}

		while ( this.currentTime >= this.duration ) {

			this.currentTime -= this.duration;

		}

		if ( this.currentTime < this.delayTime ) {

			return false;

		}

		this.audio.startTime = this.currentTime - this.delayTime;

		return true;

	},

	checkIfStopAudio: function () {

		if ( ! this.audio.isPlaying ) {

			return false;

		}

		if ( this.currentTime >= this.duration ) {

			return true;

		}

		return false;

	}

};

M
r76  
Mr.doob 已提交
2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116
THREE.MMDGrantSolver = function ( mesh ) {

	this.mesh = mesh;

};

THREE.MMDGrantSolver.prototype = {

	constructor: THREE.MMDGrantSolver,

	update: function () {

		var q = new THREE.Quaternion();

		return function () {

			for ( var i = 0; i < this.mesh.geometry.grants.length; i ++ ) {

				var g = this.mesh.geometry.grants[ i ];
				var b = this.mesh.skeleton.bones[ g.index ];
				var pb = this.mesh.skeleton.bones[ g.parentIndex ];

				if ( g.isLocal ) {

					// TODO: implement
					if ( g.affectPosition ) {

					}

					// TODO: implement
					if ( g.affectRotation ) {

					}

				} else {

					// TODO: implement
					if ( g.affectPosition ) {

					}

					if ( g.affectRotation ) {

						q.set( 0, 0, 0, 1 );
						q.slerp( pb.quaternion, g.ratio );
						b.quaternion.multiply( q );

					}

				}

			}

		};

	}()

};

M
r83  
Mr.doob 已提交
2117
THREE.MMDHelper = function () {
M
r82  
Mr.doob 已提交
2118

M
r74  
Mr.doob 已提交
2119 2120 2121 2122
	this.meshes = [];

	this.doAnimation = true;
	this.doIk = true;
M
r76  
Mr.doob 已提交
2123
	this.doGrant = true;
M
r74  
Mr.doob 已提交
2124 2125 2126
	this.doPhysics = true;
	this.doCameraAnimation = true;

M
r83  
Mr.doob 已提交
2127 2128 2129
	this.sharedPhysics = false;
	this.masterPhysics = null;

M
r74  
Mr.doob 已提交
2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140
	this.audioManager = null;
	this.camera = null;

};

THREE.MMDHelper.prototype = {

	constructor: THREE.MMDHelper,

	add: function ( mesh ) {

M
r80  
Mr.doob 已提交
2141 2142 2143 2144 2145 2146
		if ( ! ( mesh instanceof THREE.SkinnedMesh ) ) {

			throw new Error( 'THREE.MMDHelper.add() accepts only THREE.SkinnedMesh instance.' );

		}

M
r83  
Mr.doob 已提交
2147 2148 2149 2150 2151 2152
		if ( mesh.mixer === undefined ) mesh.mixer = null;
		if ( mesh.ikSolver === undefined ) mesh.ikSolver = null;
		if ( mesh.grantSolver === undefined ) mesh.grantSolver = null;
		if ( mesh.physics === undefined ) mesh.physics = null;
		if ( mesh.looped === undefined ) mesh.looped = false;

M
r74  
Mr.doob 已提交
2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174
		this.meshes.push( mesh );

		// workaround until I make IK and Physics Animation plugin
		this.initBackupBones( mesh );

	},

	setAudio: function ( audio, listener, params ) {

		this.audioManager = new THREE.MMDAudioManager( audio, listener, params );

	},

	setCamera: function ( camera ) {

		camera.mixer = null;
		this.camera = camera;

	},

	setPhysicses: function ( params ) {

M
r88  
Mr.doob 已提交
2175
		for ( var i = 0; i < this.meshes.length; i ++ ) {
M
r74  
Mr.doob 已提交
2176 2177 2178 2179 2180 2181 2182 2183 2184

			this.setPhysics( this.meshes[ i ], params );

		}

	},

	setPhysics: function ( mesh, params ) {

M
r83  
Mr.doob 已提交
2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227
		params = ( params === undefined ) ? {} : Object.assign( {}, params );

		if ( params.world === undefined && this.sharedPhysics ) {

			var masterPhysics = this.getMasterPhysics();

			if ( masterPhysics !== null ) params.world = masterPhysics.world;

		}

		var warmup = params.warmup !== undefined ? params.warmup : 60;

		var physics = new THREE.MMDPhysics( mesh, params );

		if ( mesh.mixer !== null && mesh.mixer !== undefined && params.preventAnimationWarmup !== true ) {

			this.animateOneMesh( 0, mesh );
			physics.reset();

		}

		physics.warmup( warmup );

		this.updateIKParametersDependingOnPhysicsEnabled( mesh, true );

		mesh.physics = physics;

	},

	getMasterPhysics: function () {

		if ( this.masterPhysics !== null ) return this.masterPhysics;

		for ( var i = 0, il = this.meshes.length; i < il; i ++ ) {

			var physics = this.meshes[ i ].physics;

			if ( physics !== undefined && physics !== null ) {

				this.masterPhysics = physics;
				return this.masterPhysics;

			}
M
r88  
Mr.doob 已提交
2228

M
r83  
Mr.doob 已提交
2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283
		}

		return null;

	},

	enablePhysics: function ( enabled ) {

		if ( enabled === true ) {

			this.doPhysics = true;

		} else {

			this.doPhysics = false;

		}

		for ( var i = 0, il = this.meshes.length; i < il; i ++ ) {

			this.updateIKParametersDependingOnPhysicsEnabled( this.meshes[ i ], enabled );

		}

	},

	updateIKParametersDependingOnPhysicsEnabled: function ( mesh, physicsEnabled ) {

		var iks = mesh.geometry.iks;
		var bones = mesh.geometry.bones;

		for ( var j = 0, jl = iks.length; j < jl; j ++ ) {

			var ik = iks[ j ];
			var links = ik.links;

			for ( var k = 0, kl = links.length; k < kl; k ++ ) {

				var link = links[ k ];

				if ( physicsEnabled === true ) {

					// disable IK of the bone the corresponding rigidBody type of which is 1 or 2
					// because its rotation will be overriden by physics
					link.enabled = bones[ link.index ].rigidBodyType > 0 ? false : true;

				} else {

					link.enabled = true;

				}

			}

		}
M
r74  
Mr.doob 已提交
2284 2285 2286 2287 2288

	},

	setAnimations: function () {

M
r88  
Mr.doob 已提交
2289
		for ( var i = 0; i < this.meshes.length; i ++ ) {
M
r74  
Mr.doob 已提交
2290 2291 2292 2293 2294 2295 2296 2297 2298

			this.setAnimation( this.meshes[ i ] );

		}

	},

	setAnimation: function ( mesh ) {

M
Mr.doob 已提交
2299
		if ( mesh.geometry.animations !== undefined ) {
M
r74  
Mr.doob 已提交
2300 2301 2302

			mesh.mixer = new THREE.AnimationMixer( mesh );

M
r83  
Mr.doob 已提交
2303 2304 2305 2306
			// TODO: find a workaround not to access (seems like) private properties
			//       the name of them begins with "_".
			mesh.mixer.addEventListener( 'loop', function ( e ) {

M
r87  
Mr.doob 已提交
2307 2308
				if ( e.action._clip.tracks.length > 0 &&
				     e.action._clip.tracks[ 0 ].name.indexOf( '.bones' ) !== 0 ) return;
M
r83  
Mr.doob 已提交
2309 2310 2311 2312 2313 2314

				var mesh = e.target._root;
				mesh.looped = true;

			} );

M
Mr.doob 已提交
2315 2316
			var foundAnimation = false;
			var foundMorphAnimation = false;
M
r74  
Mr.doob 已提交
2317

M
r88  
Mr.doob 已提交
2318
			for ( var i = 0; i < mesh.geometry.animations.length; i ++ ) {
M
r74  
Mr.doob 已提交
2319

M
Mr.doob 已提交
2320
				var clip = mesh.geometry.animations[ i ];
M
r74  
Mr.doob 已提交
2321

M
Mr.doob 已提交
2322
				var action = mesh.mixer.clipAction( clip );
M
r74  
Mr.doob 已提交
2323

M
r87  
Mr.doob 已提交
2324
				if ( clip.tracks.length > 0 && clip.tracks[ 0 ].name.indexOf( '.morphTargetInfluences' ) === 0 ) {
M
r74  
Mr.doob 已提交
2325

M
Mr.doob 已提交
2326
					if ( ! foundMorphAnimation ) {
M
r74  
Mr.doob 已提交
2327

M
Mr.doob 已提交
2328 2329
						action.play();
						foundMorphAnimation = true;
M
r74  
Mr.doob 已提交
2330

M
Mr.doob 已提交
2331
					}
M
r76  
Mr.doob 已提交
2332

M
Mr.doob 已提交
2333
				} else {
M
r76  
Mr.doob 已提交
2334

M
Mr.doob 已提交
2335
					if ( ! foundAnimation ) {
M
r76  
Mr.doob 已提交
2336

M
Mr.doob 已提交
2337 2338
						action.play();
						foundAnimation = true;
M
r76  
Mr.doob 已提交
2339

M
Mr.doob 已提交
2340
					}
M
r74  
Mr.doob 已提交
2341

M
Mr.doob 已提交
2342 2343 2344
				}

			}
M
r74  
Mr.doob 已提交
2345

M
Mr.doob 已提交
2346
			if ( foundAnimation ) {
M
r74  
Mr.doob 已提交
2347

M
Mr.doob 已提交
2348
				mesh.ikSolver = new THREE.CCDIKSolver( mesh );
M
r74  
Mr.doob 已提交
2349

M
Mr.doob 已提交
2350
				if ( mesh.geometry.grants !== undefined ) {
M
r74  
Mr.doob 已提交
2351

M
Mr.doob 已提交
2352
					mesh.grantSolver = new THREE.MMDGrantSolver( mesh );
M
r74  
Mr.doob 已提交
2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373

				}

			}

		}

	},

	setCameraAnimation: function ( camera ) {

		if ( camera.animations !== undefined ) {

			camera.mixer = new THREE.AnimationMixer( camera );
			camera.mixer.clipAction( camera.animations[ 0 ] ).play();

		}

	},

	/*
M
r82  
Mr.doob 已提交
2374
	 * detect the longest duration among model, camera, and audio animations and then
M
r74  
Mr.doob 已提交
2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388
	 * set it to them to sync.
	 * TODO: touching private properties ( ._actions and ._clip ) so consider better way
	 *       to access them for safe and modularity.
	 */
	unifyAnimationDuration: function ( params ) {

		params = params === undefined ? {} : params;

		var max = 0.0;

		var camera = this.camera;
		var audioManager = this.audioManager;

		// check the longest duration
M
r88  
Mr.doob 已提交
2389
		for ( var i = 0; i < this.meshes.length; i ++ ) {
M
r74  
Mr.doob 已提交
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399

			var mesh = this.meshes[ i ];
			var mixer = mesh.mixer;

			if ( mixer === null ) {

				continue;

			}

M
r88  
Mr.doob 已提交
2400
			for ( var j = 0; j < mixer._actions.length; j ++ ) {
M
r74  
Mr.doob 已提交
2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412

				var action = mixer._actions[ j ];
				max = Math.max( max, action._clip.duration );

			}

		}

		if ( camera !== null && camera.mixer !== null ) {

			var mixer = camera.mixer;

M
r88  
Mr.doob 已提交
2413
			for ( var i = 0; i < mixer._actions.length; i ++ ) {
M
r74  
Mr.doob 已提交
2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434

				var action = mixer._actions[ i ];
				max = Math.max( max, action._clip.duration );

			}

		}

		if ( audioManager !== null ) {

			max = Math.max( max, audioManager.duration );

		}

		if ( params.afterglow !== undefined ) {

			max += params.afterglow;

		}

		// set the duration
M
r88  
Mr.doob 已提交
2435
		for ( var i = 0; i < this.meshes.length; i ++ ) {
M
r74  
Mr.doob 已提交
2436 2437 2438 2439 2440 2441 2442 2443 2444 2445

			var mesh = this.meshes[ i ];
			var mixer = mesh.mixer;

			if ( mixer === null ) {

				continue;

			}

M
r88  
Mr.doob 已提交
2446
			for ( var j = 0; j < mixer._actions.length; j ++ ) {
M
r74  
Mr.doob 已提交
2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458

				var action = mixer._actions[ j ];
				action._clip.duration = max;

			}

		}

		if ( camera !== null && camera.mixer !== null ) {

			var mixer = camera.mixer;

M
r88  
Mr.doob 已提交
2459
			for ( var i = 0; i < mixer._actions.length; i ++ ) {
M
r74  
Mr.doob 已提交
2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491

				var action = mixer._actions[ i ];
				action._clip.duration = max;

			}

		}

		if ( audioManager !== null ) {

			audioManager.duration = max;

		}

	},

	controlAudio: function ( delta ) {

		if ( this.audioManager === null ) {

			return;

		}

		this.audioManager.control( delta );

	},

	animate: function ( delta ) {

		this.controlAudio( delta );

M
r88  
Mr.doob 已提交
2492
		for ( var i = 0; i < this.meshes.length; i ++ ) {
M
r74  
Mr.doob 已提交
2493 2494 2495 2496 2497

			this.animateOneMesh( delta, this.meshes[ i ] );

		}

M
r83  
Mr.doob 已提交
2498 2499
		if ( this.sharedPhysics ) this.updateSharedPhysics( delta );

M
r74  
Mr.doob 已提交
2500 2501 2502 2503 2504 2505 2506 2507
		this.animateCamera( delta );

	},

	animateOneMesh: function ( delta, mesh ) {

		var mixer = mesh.mixer;
		var ikSolver = mesh.ikSolver;
M
r76  
Mr.doob 已提交
2508
		var grantSolver = mesh.grantSolver;
M
r74  
Mr.doob 已提交
2509 2510 2511 2512
		var physics = mesh.physics;

		if ( mixer !== null && this.doAnimation === true ) {

M
r82  
Mr.doob 已提交
2513 2514 2515 2516
			// restore/backupBones are workaround
			// until I make IK, Grant, and Physics Animation plugin
			this.restoreBones( mesh );

M
r74  
Mr.doob 已提交
2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528
			mixer.update( delta );

			this.backupBones( mesh );

		}

		if ( ikSolver !== null && this.doIk === true ) {

			ikSolver.update();

		}

M
r76  
Mr.doob 已提交
2529 2530 2531 2532 2533 2534
		if ( grantSolver !== null && this.doGrant === true ) {

			grantSolver.update();

		}

M
r83  
Mr.doob 已提交
2535
		if ( mesh.looped === true ) {
M
r74  
Mr.doob 已提交
2536

M
r83  
Mr.doob 已提交
2537
			if ( physics !== null ) physics.reset();
M
r74  
Mr.doob 已提交
2538

M
r83  
Mr.doob 已提交
2539
			mesh.looped = false;
M
r74  
Mr.doob 已提交
2540 2541 2542

		}

M
r83  
Mr.doob 已提交
2543
		if ( physics !== null && this.doPhysics && ! this.sharedPhysics ) {
M
r74  
Mr.doob 已提交
2544

M
r83  
Mr.doob 已提交
2545
			physics.update( delta );
M
r74  
Mr.doob 已提交
2546 2547 2548 2549 2550

		}

	},

M
r83  
Mr.doob 已提交
2551
	updateSharedPhysics: function ( delta ) {
M
r74  
Mr.doob 已提交
2552

M
r83  
Mr.doob 已提交
2553
		if ( this.meshes.length === 0 || ! this.doPhysics || ! this.sharedPhysics ) return;
M
r80  
Mr.doob 已提交
2554

M
r83  
Mr.doob 已提交
2555
		var physics = this.getMasterPhysics();
M
r80  
Mr.doob 已提交
2556

M
r83  
Mr.doob 已提交
2557
		if ( physics === null ) return;
M
r80  
Mr.doob 已提交
2558

M
r83  
Mr.doob 已提交
2559
		for ( var i = 0, il = this.meshes.length; i < il; i ++ ) {
M
r80  
Mr.doob 已提交
2560

M
r83  
Mr.doob 已提交
2561
			var p = this.meshes[ i ].physics;
M
r80  
Mr.doob 已提交
2562

M
r83  
Mr.doob 已提交
2563
			if ( p !== null && p !== undefined ) {
M
r80  
Mr.doob 已提交
2564

M
r83  
Mr.doob 已提交
2565
				p.updateRigidBodies();
M
r80  
Mr.doob 已提交
2566 2567 2568

			}

M
r82  
Mr.doob 已提交
2569
		}
M
r80  
Mr.doob 已提交
2570

M
r83  
Mr.doob 已提交
2571
		physics.stepSimulation( delta );
M
r80  
Mr.doob 已提交
2572

M
r83  
Mr.doob 已提交
2573
		for ( var i = 0, il = this.meshes.length; i < il; i ++ ) {
M
r80  
Mr.doob 已提交
2574

M
r83  
Mr.doob 已提交
2575
			var p = this.meshes[ i ].physics;
M
r80  
Mr.doob 已提交
2576

M
r83  
Mr.doob 已提交
2577
			if ( p !== null && p !== undefined ) {
M
r76  
Mr.doob 已提交
2578

M
r83  
Mr.doob 已提交
2579
				p.updateBones();
M
r76  
Mr.doob 已提交
2580

M
r83  
Mr.doob 已提交
2581
			}
M
r76  
Mr.doob 已提交
2582 2583 2584

		}

M
r83  
Mr.doob 已提交
2585
	},
M
r76  
Mr.doob 已提交
2586

M
r83  
Mr.doob 已提交
2587
	animateCamera: function ( delta ) {
M
r74  
Mr.doob 已提交
2588

M
r83  
Mr.doob 已提交
2589
		if ( this.camera === null ) {
M
r74  
Mr.doob 已提交
2590

M
r83  
Mr.doob 已提交
2591
			return;
M
r74  
Mr.doob 已提交
2592 2593 2594

		}

M
r83  
Mr.doob 已提交
2595
		var mixer = this.camera.mixer;
M
r74  
Mr.doob 已提交
2596

M
r83  
Mr.doob 已提交
2597
		if ( mixer !== null && this.camera.center !== undefined && this.doCameraAnimation === true ) {
M
r74  
Mr.doob 已提交
2598

M
r83  
Mr.doob 已提交
2599
			mixer.update( delta );
M
r74  
Mr.doob 已提交
2600

M
r83  
Mr.doob 已提交
2601 2602
			// TODO: Let PerspectiveCamera automatically update?
			this.camera.updateProjectionMatrix();
M
r74  
Mr.doob 已提交
2603

M
r83  
Mr.doob 已提交
2604 2605 2606
			this.camera.up.set( 0, 1, 0 );
			this.camera.up.applyQuaternion( this.camera.quaternion );
			this.camera.lookAt( this.camera.center );
M
r74  
Mr.doob 已提交
2607 2608 2609

		}

M
r83  
Mr.doob 已提交
2610
	},
M
r74  
Mr.doob 已提交
2611 2612 2613

	poseAsVpd: function ( mesh, vpd, params ) {

M
r83  
Mr.doob 已提交
2614
		if ( params === undefined ) params = {};
M
r74  
Mr.doob 已提交
2615

M
r83  
Mr.doob 已提交
2616
		if ( params.preventResetPose !== true ) mesh.pose();
M
r74  
Mr.doob 已提交
2617 2618 2619 2620 2621 2622

		var bones = mesh.skeleton.bones;
		var bones2 = vpd.bones;

		var table = {};

M
r88  
Mr.doob 已提交
2623
		for ( var i = 0; i < bones.length; i ++ ) {
M
r74  
Mr.doob 已提交
2624

M
r83  
Mr.doob 已提交
2625
			table[ bones[ i ].name ] = i;
M
r74  
Mr.doob 已提交
2626 2627 2628 2629 2630 2631

		}

		var thV = new THREE.Vector3();
		var thQ = new THREE.Quaternion();

M
r88  
Mr.doob 已提交
2632
		for ( var i = 0; i < bones2.length; i ++ ) {
M
r74  
Mr.doob 已提交
2633 2634 2635 2636

			var b = bones2[ i ];
			var index = table[ b.name ];

M
r83  
Mr.doob 已提交
2637
			if ( index === undefined ) continue;
M
r74  
Mr.doob 已提交
2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650

			var b2 = bones[ index ];
			var t = b.translation;
			var q = b.quaternion;

			thV.set( t[ 0 ], t[ 1 ], t[ 2 ] );
			thQ.set( q[ 0 ], q[ 1 ], q[ 2 ], q[ 3 ] );

			b2.position.add( thV );
			b2.quaternion.multiply( thQ );

		}

M
r83  
Mr.doob 已提交
2651 2652 2653
		mesh.updateMatrixWorld( true );

		if ( params.preventIk !== true ) {
M
r74  
Mr.doob 已提交
2654

M
r76  
Mr.doob 已提交
2655
			var solver = new THREE.CCDIKSolver( mesh );
M
r83  
Mr.doob 已提交
2656
			solver.update( params.saveOriginalBonesBeforeIK );
M
r74  
Mr.doob 已提交
2657 2658 2659

		}

M
r83  
Mr.doob 已提交
2660
		if ( params.preventGrant !== true && mesh.geometry.grants !== undefined ) {
M
r76  
Mr.doob 已提交
2661

M
r83  
Mr.doob 已提交
2662 2663
			var solver = new THREE.MMDGrantSolver( mesh );
			solver.update();
M
r76  
Mr.doob 已提交
2664 2665

		}
M
r74  
Mr.doob 已提交
2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682

	},

	/*
	 * Note: These following three functions are workaround for r74dev.
	 *       THREE.PropertyMixer.apply() seems to save values into buffer cache
	 *       when mixer.update() is called.
	 *       ikSolver.update() and physics.update() change bone position/quaternion
	 *       without mixer.update() then buffer cache will be inconsistent.
	 *       So trying to avoid buffer cache inconsistency by doing
	 *       backup bones position/quaternion right after mixer.update() call
	 *       and then restore them after rendering.
	 */
	initBackupBones: function ( mesh ) {

		mesh.skeleton.backupBones = [];

M
r88  
Mr.doob 已提交
2683
		for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
M
r74  
Mr.doob 已提交
2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694

			mesh.skeleton.backupBones.push( mesh.skeleton.bones[ i ].clone() );

		}

	},

	backupBones: function ( mesh ) {

		mesh.skeleton.backupBoneIsSaved = true;

M
r88  
Mr.doob 已提交
2695
		for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
M
r74  
Mr.doob 已提交
2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715

			var b = mesh.skeleton.backupBones[ i ];
			var b2 = mesh.skeleton.bones[ i ];
			b.position.copy( b2.position );
			b.quaternion.copy( b2.quaternion );

		}

	},

	restoreBones: function ( mesh ) {

		if ( mesh.skeleton.backupBoneIsSaved !== true ) {

			return;

		}

		mesh.skeleton.backupBoneIsSaved = false;

M
r88  
Mr.doob 已提交
2716
		for ( var i = 0; i < mesh.skeleton.bones.length; i ++ ) {
M
r74  
Mr.doob 已提交
2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727

			var b = mesh.skeleton.bones[ i ];
			var b2 = mesh.skeleton.backupBones[ i ];
			b.position.copy( b2.position );
			b.quaternion.copy( b2.quaternion );

		}

	}

};