Spaces:
Running
Running
| /** | |
| * @author takahiro / http://github.com/takahirox | |
| * | |
| * Dependencies | |
| * - mmd-parser https://github.com/takahirox/mmd-parser | |
| */ | |
| THREE.MMDExporter = function () { | |
| // Unicode to Shift_JIS table | |
| var u2sTable; | |
| function unicodeToShiftjis( str ) { | |
| if ( u2sTable === undefined ) { | |
| var encoder = new MMDParser.CharsetEncoder(); | |
| var table = encoder.s2uTable; | |
| u2sTable = {}; | |
| var keys = Object.keys( table ); | |
| for ( var i = 0, il = keys.length; i < il; i ++ ) { | |
| var key = keys[ i ]; | |
| var value = table[ key ]; | |
| key = parseInt( key ); | |
| u2sTable[ value ] = key; | |
| } | |
| } | |
| var array = []; | |
| for ( var i = 0, il = str.length; i < il; i ++ ) { | |
| var code = str.charCodeAt( i ); | |
| var 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? | |
| var poseSkin = skin.clone(); | |
| poseSkin.pose(); | |
| return poseSkin.skeleton.bones; | |
| } | |
| /* TODO: implement | |
| // mesh -> pmd | |
| this.parsePmd = function ( object ) { | |
| }; | |
| */ | |
| /* TODO: implement | |
| // mesh -> pmx | |
| this.parsePmx = function ( object ) { | |
| }; | |
| */ | |
| /* | |
| * skeleton -> vpd | |
| * Returns Shift_JIS encoded Uint8Array. Otherwise return strings. | |
| */ | |
| this.parseVpd = function ( 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; | |
| var a = num.toString(); | |
| if ( a.indexOf( '.' ) === - 1 ) { | |
| a += '.'; | |
| } | |
| a += '000000'; | |
| var index = a.indexOf( '.' ); | |
| var d = a.slice( 0, index ); | |
| var p = a.slice( index + 1, index + 7 ); | |
| return d + '.' + p; | |
| } | |
| function toStringsFromArray( array ) { | |
| var a = []; | |
| for ( var i = 0, il = array.length; i < il; i ++ ) { | |
| a.push( toStringsFromNumber( array[ i ] ) ); | |
| } | |
| return a.join( ',' ); | |
| } | |
| skin.updateMatrixWorld( true ); | |
| var bones = skin.skeleton.bones; | |
| var bones2 = getBindBones( skin ); | |
| var position = new THREE.Vector3(); | |
| var quaternion = new THREE.Quaternion(); | |
| var quaternion2 = new THREE.Quaternion(); | |
| var matrix = new THREE.Matrix4(); | |
| var 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 ( var i = 0, il = bones.length; i < il; i ++ ) { | |
| var bone = bones[ i ]; | |
| var 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 ); | |
| var pArray = position.sub( bone2.position ).toArray(); | |
| var 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( '' ); | |
| var lines = array.join( '\n' ); | |
| return ( outputShiftJis === true ) ? unicodeToShiftjis( lines ) : lines; | |
| }; | |
| /* TODO: implement | |
| // animation + skeleton -> vmd | |
| this.parseVmd = function ( object ) { | |
| }; | |
| */ | |
| }; | |