| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 | 
							- import {
 
- 	Matrix4,
 
- 	Quaternion,
 
- 	Vector3
 
- } from '../../../build/three.module.js';
 
- import { MMDParser } from '../libs/mmdparser.module.js';
 
- /**
 
-  * Dependencies
 
-  *  - mmd-parser https://github.com/takahirox/mmd-parser
 
-  */
 
- class MMDExporter {
 
- 	/* TODO: implement
 
- 	// mesh -> pmd
 
- 	this.parsePmd = function ( object ) {
 
- 	};
 
- 	*/
 
- 	/* TODO: implement
 
- 	// mesh -> pmx
 
- 	this.parsePmx = function ( object ) {
 
- 	};
 
- 	*/
 
- 	/* TODO: implement
 
- 	// animation + skeleton -> vmd
 
- 	this.parseVmd = function ( object ) {
 
- 	};
 
- 	*/
 
- 	/*
 
- 	 * skeleton -> vpd
 
- 	 * Returns Shift_JIS encoded Uint8Array. Otherwise return strings.
 
- 	 */
 
- 	parseVpd( skin, outputShiftJis, useOriginalBones ) {
 
- 		if ( skin.isSkinnedMesh !== true ) {
 
- 			console.warn( 'THREE.MMDExporter: parseVpd() requires SkinnedMesh instance.' );
 
- 			return null;
 
- 		}
 
- 		function toStringsFromNumber( num ) {
 
- 			if ( Math.abs( num ) < 1e-6 ) num = 0;
 
- 			let a = num.toString();
 
- 			if ( a.indexOf( '.' ) === - 1 ) {
 
- 				a += '.';
 
- 			}
 
- 			a += '000000';
 
- 			const index = a.indexOf( '.' );
 
- 			const d = a.slice( 0, index );
 
- 			const p = a.slice( index + 1, index + 7 );
 
- 			return d + '.' + p;
 
- 		}
 
- 		function toStringsFromArray( array ) {
 
- 			const a = [];
 
- 			for ( let i = 0, il = array.length; i < il; i ++ ) {
 
- 				a.push( toStringsFromNumber( array[ i ] ) );
 
- 			}
 
- 			return a.join( ',' );
 
- 		}
 
- 		skin.updateMatrixWorld( true );
 
- 		const bones = skin.skeleton.bones;
 
- 		const bones2 = getBindBones( skin );
 
- 		const position = new Vector3();
 
- 		const quaternion = new Quaternion();
 
- 		const quaternion2 = new Quaternion();
 
- 		const matrix = new Matrix4();
 
- 		const array = [];
 
- 		array.push( 'Vocaloid Pose Data file' );
 
- 		array.push( '' );
 
- 		array.push( ( skin.name !== '' ? skin.name.replace( /\s/g, '_' ) : 'skin' ) + '.osm;' );
 
- 		array.push( bones.length + ';' );
 
- 		array.push( '' );
 
- 		for ( let i = 0, il = bones.length; i < il; i ++ ) {
 
- 			const bone = bones[ i ];
 
- 			const bone2 = bones2[ i ];
 
- 			/*
 
- 			 * use the bone matrix saved before solving IK.
 
- 			 * see CCDIKSolver for the detail.
 
- 			 */
 
- 			if ( useOriginalBones === true &&
 
- 				bone.userData.ik !== undefined &&
 
- 				bone.userData.ik.originalMatrix !== undefined ) {
 
- 				matrix.fromArray( bone.userData.ik.originalMatrix );
 
- 			} else {
 
- 				matrix.copy( bone.matrix );
 
- 			}
 
- 			position.setFromMatrixPosition( matrix );
 
- 			quaternion.setFromRotationMatrix( matrix );
 
- 			const pArray = position.sub( bone2.position ).toArray();
 
- 			const qArray = quaternion2.copy( bone2.quaternion ).conjugate().multiply( quaternion ).toArray();
 
- 			// right to left
 
- 			pArray[ 2 ] = - pArray[ 2 ];
 
- 			qArray[ 0 ] = - qArray[ 0 ];
 
- 			qArray[ 1 ] = - qArray[ 1 ];
 
- 			array.push( 'Bone' + i + '{' + bone.name );
 
- 			array.push( '  ' + toStringsFromArray( pArray ) + ';' );
 
- 			array.push( '  ' + toStringsFromArray( qArray ) + ';' );
 
- 			array.push( '}' );
 
- 			array.push( '' );
 
- 		}
 
- 		array.push( '' );
 
- 		const lines = array.join( '\n' );
 
- 		return ( outputShiftJis === true ) ? unicodeToShiftjis( lines ) : lines;
 
- 	}
 
- }
 
- // Unicode to Shift_JIS table
 
- let u2sTable;
 
- function unicodeToShiftjis( str ) {
 
- 	if ( u2sTable === undefined ) {
 
- 		const encoder = new MMDParser.CharsetEncoder(); // eslint-disable-line no-undef
 
- 		const table = encoder.s2uTable;
 
- 		u2sTable = {};
 
- 		const keys = Object.keys( table );
 
- 		for ( let i = 0, il = keys.length; i < il; i ++ ) {
 
- 			let key = keys[ i ];
 
- 			const value = table[ key ];
 
- 			key = parseInt( key );
 
- 			u2sTable[ value ] = key;
 
- 		}
 
- 	}
 
- 	const array = [];
 
- 	for ( let i = 0, il = str.length; i < il; i ++ ) {
 
- 		const code = str.charCodeAt( i );
 
- 		const value = u2sTable[ code ];
 
- 		if ( value === undefined ) {
 
- 			throw 'cannot convert charcode 0x' + code.toString( 16 );
 
- 		} else if ( value > 0xff ) {
 
- 			array.push( ( value >> 8 ) & 0xff );
 
- 			array.push( value & 0xff );
 
- 		} else {
 
- 			array.push( value & 0xff );
 
- 		}
 
- 	}
 
- 	return new Uint8Array( array );
 
- }
 
- function getBindBones( skin ) {
 
- 	// any more efficient ways?
 
- 	const poseSkin = skin.clone();
 
- 	poseSkin.pose();
 
- 	return poseSkin.skeleton.bones;
 
- }
 
- export { MMDExporter };
 
 
  |