MDDLoader.js 2.3 KB
Newer Older
M
Marco Fugaro 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
( 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)
 */

15
	class MDDLoader extends THREE.Loader {
M
Marco Fugaro 已提交
16

17
		constructor( manager ) {
M
Marco Fugaro 已提交
18

19
			super( manager );
M
Marco Fugaro 已提交
20

21 22 23
		}

		load( url, onLoad, onProgress, onError ) {
M
Marco Fugaro 已提交
24

25 26
			const scope = this;
			const loader = new THREE.FileLoader( this.manager );
M
Marco Fugaro 已提交
27 28 29 30 31 32 33 34
			loader.setPath( this.path );
			loader.setResponseType( 'arraybuffer' );
			loader.load( url, function ( data ) {

				onLoad( scope.parse( data ) );

			}, onProgress, onError );

35
		}
M
Marco Fugaro 已提交
36

37
		parse( data ) {
M
Marco Fugaro 已提交
38

39 40 41 42
			const view = new DataView( data );
			const totalFrames = view.getUint32( 0 );
			const totalPoints = view.getUint32( 4 );
			let offset = 8; // animation clip
M
Marco Fugaro 已提交
43

44 45 46 47
			const times = new Float32Array( totalFrames );
			const values = new Float32Array( totalFrames * totalFrames ).fill( 0 );

			for ( let i = 0; i < totalFrames; i ++ ) {
M
Marco Fugaro 已提交
48 49 50 51 52 53 54

				times[ i ] = view.getFloat32( offset );
				offset += 4;
				values[ totalFrames * i + i ] = 1;

			}

55 56
			const track = new THREE.NumberKeyframeTrack( '.morphTargetInfluences', times, values );
			const clip = new THREE.AnimationClip( 'default', times[ times.length - 1 ], [ track ] ); // morph targets
M
Marco Fugaro 已提交
57

58
			const morphTargets = [];
M
Marco Fugaro 已提交
59

60
			for ( let i = 0; i < totalFrames; i ++ ) {
M
Marco Fugaro 已提交
61

62
				const morphTarget = new Float32Array( totalPoints * 3 );
M
Marco Fugaro 已提交
63

64
				for ( let j = 0; j < totalPoints; j ++ ) {
M
Marco Fugaro 已提交
65

66
					const stride = j * 3;
M
Marco Fugaro 已提交
67 68 69 70 71 72 73 74 75 76 77
					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

				}

78
				const attribute = new THREE.BufferAttribute( morphTarget, 3 );
M
Marco Fugaro 已提交
79 80 81 82 83 84 85 86 87 88 89
				attribute.name = 'morph_' + i;
				morphTargets.push( attribute );

			}

			return {
				morphTargets: morphTargets,
				clip: clip
			};

		}
90 91

	}
M
Marco Fugaro 已提交
92 93 94 95

	THREE.MDDLoader = MDDLoader;

} )();