SEA3DDraco.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /**
  2. * SEA3D - Google Draco
  3. * @author Sunag / http://www.sunag.com.br/
  4. */
  5. 'use strict';
  6. //
  7. // Lossy Compression
  8. //
  9. SEA3D.GeometryDraco = function ( name, data, sea3d ) {
  10. this.name = name;
  11. this.data = data;
  12. this.sea3d = sea3d;
  13. var attrib = data.readUShort(),
  14. i;
  15. this.isBig = ( attrib & 1 ) !== 0;
  16. data.readVInt = this.isBig ? data.readUInt : data.readUShort;
  17. this.groups = [];
  18. if ( attrib & 32 ) {
  19. this.uv = [];
  20. this.uv.length = data.readUByte();
  21. }
  22. if ( attrib & 1024 ) {
  23. var numGroups = data.readUByte(),
  24. groupOffset = 0;
  25. for ( i = 0; i < numGroups; i ++ ) {
  26. var groupLength = data.readVInt() * 3;
  27. this.groups.push( {
  28. start: groupOffset,
  29. count: groupLength,
  30. } );
  31. groupOffset += groupLength;
  32. }
  33. }
  34. var module = SEA3D.GeometryDraco.getModule(),
  35. dracoData = new Int8Array( data.concat( data.position, data.bytesAvailable ).buffer );
  36. //data.position += 5; // jump "DRACO" magic string
  37. //var version = data.readUByte() + '.' + data.readUByte(); // draco version
  38. var decoder = new module.Decoder();
  39. var buffer = new module.DecoderBuffer();
  40. buffer.Init( dracoData, dracoData.length );
  41. var mesh = new module.Mesh();
  42. var decodingStatus = decoder.DecodeBufferToMesh( buffer, mesh );
  43. if ( ! decodingStatus.ok() ) {
  44. console.error( "SEA3D Draco Decoding failed:", decodingStatus.error_msg() );
  45. }
  46. var index = 0;
  47. this.vertex = this.readFloat32Array( module, decoder, mesh, index ++, module.POSITION );
  48. if ( attrib & 4 ) this.normal = this.readFloat32Array( module, decoder, mesh, index ++, module.NORMAL );
  49. if ( attrib & 32 ) {
  50. for ( i = 0; i < this.uv.length; i ++ ) {
  51. this.uv[ i ] = this.readFloat32Array( module, decoder, mesh, index ++, module.TEX_COORD );
  52. }
  53. }
  54. if ( attrib & 64 ) {
  55. this.jointPerVertex = decoder.GetAttribute( mesh, index ).num_components();
  56. this.joint = this.readUint16Array( module, decoder, mesh, index ++ );
  57. this.weight = this.readFloat32Array( module, decoder, mesh, index ++ );
  58. }
  59. this.indexes = this.readIndices( module, decoder, mesh );
  60. module.destroy( mesh );
  61. module.destroy( buffer );
  62. module.destroy( decoder );
  63. };
  64. SEA3D.GeometryDraco.getModule = function () {
  65. if ( ! this.module ) {
  66. this.module = DracoDecoderModule();
  67. }
  68. return this.module;
  69. };
  70. SEA3D.GeometryDraco.prototype.type = "sdrc";
  71. SEA3D.GeometryDraco.prototype.readIndices = function ( module, decoder, mesh ) {
  72. var numFaces = mesh.num_faces(),
  73. numIndices = numFaces * 3,
  74. indices = new ( numIndices >= 0xFFFE ? Uint32Array : Uint16Array )( numIndices );
  75. var ia = new module.DracoInt32Array();
  76. for ( var i = 0; i < numFaces; ++ i ) {
  77. decoder.GetFaceFromMesh( mesh, i, ia );
  78. var index = i * 3;
  79. indices[ index ] = ia.GetValue( 0 );
  80. indices[ index + 1 ] = ia.GetValue( 1 );
  81. indices[ index + 2 ] = ia.GetValue( 2 );
  82. }
  83. module.destroy( ia );
  84. return indices;
  85. };
  86. SEA3D.GeometryDraco.prototype.readTriangleStripIndices = function ( module, decoder, mesh ) {
  87. var dracoArray = new module.DracoInt32Array();
  88. decoder.GetTriangleStripsFromMesh( mesh, dracoArray );
  89. var size = mesh.num_faces() * 3,
  90. output = new ( size >= 0xFFFE ? Uint32Array : Uint16Array )( size );
  91. for ( var i = 0; i < size; ++ i ) {
  92. output[ i ] = dracoArray.GetValue( i );
  93. }
  94. module.destroy( dracoArray );
  95. return output;
  96. };
  97. SEA3D.GeometryDraco.prototype.readFloat32Array = function ( module, decoder, mesh, attrib, type ) {
  98. var attribute = decoder.GetAttribute( mesh, attrib ),
  99. numPoints = mesh.num_points();
  100. var dracoArray = new module.DracoFloat32Array();
  101. decoder.GetAttributeFloatForAllPoints( mesh, attribute, dracoArray );
  102. var size = numPoints * attribute.num_components(),
  103. output = new Float32Array( size );
  104. for ( var i = 0; i < size; ++ i ) {
  105. output[ i ] = dracoArray.GetValue( i );
  106. }
  107. module.destroy( dracoArray );
  108. return output;
  109. };
  110. SEA3D.GeometryDraco.prototype.readUint16Array = function ( module, decoder, mesh, attrib, type ) {
  111. var attribute = decoder.GetAttribute( mesh, attrib ),
  112. numPoints = mesh.num_points();
  113. var dracoArray = new module.DracoUInt16Array();
  114. decoder.GetAttributeUInt16ForAllPoints( mesh, attribute, dracoArray );
  115. var size = numPoints * attribute.num_components(),
  116. output = new Uint16Array( size );
  117. for ( var i = 0; i < size; ++ i ) {
  118. output[ i ] = dracoArray.GetValue( i );
  119. }
  120. module.destroy( dracoArray );
  121. return output;
  122. };
  123. //
  124. // Extension
  125. //
  126. THREE.SEA3D.EXTENSIONS_LOADER.push( {
  127. setTypeRead: function () {
  128. this.file.addClass( SEA3D.GeometryDraco, true );
  129. this.file.typeRead[ SEA3D.GeometryDraco.prototype.type ] = this.readGeometryBuffer;
  130. }
  131. } );