MDDLoader.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * @author Mugen87 / https://github.com/Mugen87
  3. *
  4. * MDD is a special format that stores a position for every vertex in a model for every frame in an animation.
  5. * Similar to BVH, it can be used to transfer animation data between different 3D applications or engines.
  6. *
  7. * MDD stores its data in binary format (big endian) in the following way:
  8. *
  9. * number of frames (a single uint32)
  10. * number of vertices (a single uint32)
  11. * time values for each frame (sequence of float32)
  12. * vertex data for each frame (sequence of float32)
  13. */
  14. import {
  15. AnimationClip,
  16. BufferAttribute,
  17. FileLoader,
  18. Loader,
  19. NumberKeyframeTrack
  20. } from "../../../build/three.module.js";
  21. var MDDLoader = function ( manager ) {
  22. Loader.call( this, manager );
  23. };
  24. MDDLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
  25. constructor: MDDLoader,
  26. load: function ( url, onLoad, onProgress, onError ) {
  27. var scope = this;
  28. var loader = new FileLoader( this.manager );
  29. loader.setPath( this.path );
  30. loader.setResponseType( 'arraybuffer' );
  31. loader.load( url, function ( data ) {
  32. onLoad( scope.parse( data ) );
  33. }, onProgress, onError );
  34. },
  35. parse: function ( data ) {
  36. var view = new DataView( data );
  37. var totalFrames = view.getUint32( 0 );
  38. var totalPoints = view.getUint32( 4 );
  39. var offset = 8;
  40. // animation clip
  41. var times = new Float32Array( totalFrames );
  42. var values = new Float32Array( totalFrames * totalFrames ).fill( 0 );
  43. for ( var i = 0; i < totalFrames; i ++ ) {
  44. times[ i ] = view.getFloat32( offset ); offset += 4;
  45. values[ ( totalFrames * i ) + i ] = 1;
  46. }
  47. var track = new NumberKeyframeTrack( '.morphTargetInfluences', times, values );
  48. var clip = new AnimationClip( 'default', times[ times.length - 1 ], [ track ] );
  49. // morph targets
  50. var morphTargets = [];
  51. for ( var i = 0; i < totalFrames; i ++ ) {
  52. var morphTarget = new Float32Array( totalPoints * 3 );
  53. for ( var j = 0; j < totalPoints; j ++ ) {
  54. var stride = ( j * 3 );
  55. morphTarget[ stride + 0 ] = view.getFloat32( offset ); offset += 4; // x
  56. morphTarget[ stride + 1 ] = view.getFloat32( offset ); offset += 4; // y
  57. morphTarget[ stride + 2 ] = view.getFloat32( offset ); offset += 4; // z
  58. }
  59. var attribute = new BufferAttribute( morphTarget, 3 );
  60. attribute.name = 'morph_' + i;
  61. morphTargets.push( attribute );
  62. }
  63. return {
  64. morphTargets: morphTargets,
  65. clip: clip
  66. };
  67. }
  68. } );
  69. export { MDDLoader };