MD2Loader.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.MD2Loader = function ( manager ) {
  5. this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
  6. };
  7. THREE.MD2Loader.prototype = {
  8. constructor: THREE.MD2Loader,
  9. load: function ( url, onLoad, onProgress, onError ) {
  10. var scope = this;
  11. var loader = new THREE.XHRLoader( scope.manager );
  12. loader.setCrossOrigin( this.crossOrigin );
  13. loader.setResponseType( 'arraybuffer' );
  14. loader.load( url, function ( buffer ) {
  15. onLoad( scope.parse( buffer ) );
  16. }, onProgress, onError );
  17. },
  18. setCrossOrigin: function ( value ) {
  19. this.crossOrigin = value;
  20. },
  21. parse: function ( buffer ) {
  22. var data = new DataView( buffer );
  23. // http://tfc.duke.free.fr/coding/md2-specs-en.html
  24. var header = {};
  25. var headerNames = [
  26. 'ident', 'version',
  27. 'skinwidth', 'skinheight',
  28. 'framesize',
  29. 'num_skins', 'num_vertices', 'num_st', 'num_tris', 'num_glcmds', 'num_frames',
  30. 'offset_skins', 'offset_st', 'offset_tris', 'offset_frames', 'offset_glcmds', 'offset_end'
  31. ];
  32. for ( var i = 0; i < headerNames.length; i ++ ) {
  33. header[ headerNames[ i ] ] = data.getInt32( i * 4, true );
  34. }
  35. if ( header.ident !== 844121161 || header.version !== 8 ) {
  36. console.error( 'Not a valid MD2 file' );
  37. return;
  38. }
  39. if ( header.offset_end !== data.byteLength ) {
  40. console.error( 'Corrupted MD2 file' );
  41. return;
  42. }
  43. //
  44. var geometry = new THREE.Geometry();
  45. // uvs
  46. var uvs = [];
  47. var offset = header.offset_st;
  48. for ( var i = 0; i < header.num_st; i ++, offset += 4 ) {
  49. var u = data.getInt16( offset + 0, true );
  50. var v = data.getInt16( offset + 2, true );
  51. var uv = new THREE.Vector2( u / header.skinwidth, 1 - ( v / header.skinheight ) );
  52. uvs.push( uv );
  53. }
  54. // triangles
  55. var offset = header.offset_tris;
  56. for ( var i = 0; i < header.num_tris; i ++ ) {
  57. var a = data.getUint16( offset + 0, true );
  58. var b = data.getUint16( offset + 2, true );
  59. var c = data.getUint16( offset + 4, true );
  60. var face = new THREE.Face3( a, b, c );
  61. geometry.faces.push( face );
  62. geometry.faceVertexUvs[ 0 ].push( [
  63. uvs[ data.getUint16( offset + 6, true ) ],
  64. uvs[ data.getUint16( offset + 8, true ) ],
  65. uvs[ data.getUint16( offset + 10, true ) ]
  66. ] );
  67. offset += 12;
  68. }
  69. // frames
  70. var translation = new THREE.Vector3();
  71. var scale = new THREE.Vector3();
  72. var offset = header.offset_frames;
  73. for ( var i = 0; i < header.num_frames; i ++ ) {
  74. scale.set(
  75. data.getFloat32( offset + 0, true ),
  76. data.getFloat32( offset + 4, true ),
  77. data.getFloat32( offset + 8, true )
  78. );
  79. translation.set(
  80. data.getFloat32( offset + 12, true ),
  81. data.getFloat32( offset + 16, true ),
  82. data.getFloat32( offset + 20, true )
  83. );
  84. offset += 24;
  85. var string = [];
  86. for ( var j = 0; j < 16; j ++ ) {
  87. string[ j ] = data.getUint8( offset + j, true );
  88. }
  89. var frame = {
  90. name: String.fromCharCode.apply( null, string ),
  91. vertices: []
  92. };
  93. offset += 16;
  94. for ( var j = 0; j < header.num_vertices; j ++ ) {
  95. var x = data.getUint8( offset ++, true );
  96. var y = data.getUint8( offset ++, true );
  97. var z = data.getUint8( offset ++, true );
  98. var n = data.getUint8( offset ++, true );
  99. var vertex = new THREE.Vector3(
  100. x * scale.x + translation.x,
  101. z * scale.z + translation.z,
  102. y * scale.y + translation.y
  103. );
  104. frame.vertices.push( vertex );
  105. }
  106. geometry.morphTargets.push( frame );
  107. }
  108. geometry.vertices = geometry.morphTargets[ 0 ].vertices;
  109. return geometry;
  110. }
  111. }