( function () { /** * MDD is a special format that stores a position for every vertex in a model for every frame in an animation. * Similar to BVH, it can be used to transfer animation data between different 3D applications or engines. * * MDD stores its data in binary format (big endian) in the following way: * * number of frames (a single uint32) * number of vertices (a single uint32) * time values for each frame (sequence of float32) * vertex data for each frame (sequence of float32) */ class MDDLoader extends THREE.Loader { constructor( manager ) { super( manager ); } load( url, onLoad, onProgress, onError ) { const scope = this; const loader = new THREE.FileLoader( this.manager ); loader.setPath( this.path ); loader.setResponseType( 'arraybuffer' ); loader.load( url, function ( data ) { onLoad( scope.parse( data ) ); }, onProgress, onError ); } parse( data ) { const view = new DataView( data ); const totalFrames = view.getUint32( 0 ); const totalPoints = view.getUint32( 4 ); let offset = 8; // animation clip const times = new Float32Array( totalFrames ); const values = new Float32Array( totalFrames * totalFrames ).fill( 0 ); for ( let i = 0; i < totalFrames; i ++ ) { times[ i ] = view.getFloat32( offset ); offset += 4; values[ totalFrames * i + i ] = 1; } const track = new THREE.NumberKeyframeTrack( '.morphTargetInfluences', times, values ); const clip = new THREE.AnimationClip( 'default', times[ times.length - 1 ], [ track ] ); // morph targets const morphTargets = []; for ( let i = 0; i < totalFrames; i ++ ) { const morphTarget = new Float32Array( totalPoints * 3 ); for ( let j = 0; j < totalPoints; j ++ ) { const stride = j * 3; morphTarget[ stride + 0 ] = view.getFloat32( offset ); offset += 4; // x morphTarget[ stride + 1 ] = view.getFloat32( offset ); offset += 4; // y morphTarget[ stride + 2 ] = view.getFloat32( offset ); offset += 4; // z } const attribute = new THREE.BufferAttribute( morphTarget, 3 ); attribute.name = 'morph_' + i; morphTargets.push( attribute ); } return { morphTargets: morphTargets, clip: clip }; } } THREE.MDDLoader = MDDLoader; } )();