SEA3DDraco.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. var decoder = new module.Decoder();
  37. var buffer = new module.DecoderBuffer();
  38. buffer.Init( dracoData, dracoData.length );
  39. var mesh = new module.Mesh();
  40. var decodingStatus = decoder.DecodeBufferToMesh( buffer, mesh );
  41. if ( ! decodingStatus.ok() ) {
  42. data.position += 5; // jump "DRACO" magic string
  43. var version = data.readUByte() + '.' + data.readUByte(); // draco version
  44. console.error( "SEA3D Draco", version, "decoding failed:", decodingStatus.error_msg(), "You may need update 'draco_decoder.js'." );
  45. // use an empty geometry
  46. this.vertex = new Float32Array();
  47. return;
  48. }
  49. var index = 0;
  50. this.vertex = this.readFloat32Array( module, decoder, mesh, index ++ );
  51. if ( attrib & 4 ) this.normal = this.readFloat32Array( module, decoder, mesh, index ++ );
  52. if ( attrib & 32 ) {
  53. for ( i = 0; i < this.uv.length; i ++ ) {
  54. this.uv[ i ] = this.readFloat32Array( module, decoder, mesh, index ++ );
  55. }
  56. }
  57. if ( attrib & 64 ) {
  58. this.jointPerVertex = decoder.GetAttribute( mesh, index ).num_components();
  59. this.joint = this.readUint16Array( module, decoder, mesh, index ++ );
  60. this.weight = this.readFloat32Array( module, decoder, mesh, index ++ );
  61. }
  62. this.indexes = this.readIndices( module, decoder, mesh );
  63. module.destroy( mesh );
  64. module.destroy( buffer );
  65. module.destroy( decoder );
  66. };
  67. SEA3D.GeometryDraco.getModule = function () {
  68. if ( ! this.module ) {
  69. this.module = DracoDecoderModule();
  70. }
  71. return this.module;
  72. };
  73. SEA3D.GeometryDraco.prototype.type = "sdrc";
  74. SEA3D.GeometryDraco.prototype.readIndices = function ( module, decoder, mesh ) {
  75. var numFaces = mesh.num_faces(),
  76. numIndices = numFaces * 3,
  77. indices = new ( numIndices >= 0xFFFE ? Uint32Array : Uint16Array )( numIndices );
  78. var ia = new module.DracoInt32Array();
  79. for ( var i = 0; i < numFaces; ++ i ) {
  80. decoder.GetFaceFromMesh( mesh, i, ia );
  81. var index = i * 3;
  82. indices[ index ] = ia.GetValue( 0 );
  83. indices[ index + 1 ] = ia.GetValue( 1 );
  84. indices[ index + 2 ] = ia.GetValue( 2 );
  85. }
  86. module.destroy( ia );
  87. return indices;
  88. };
  89. SEA3D.GeometryDraco.prototype.readFloat32Array = function ( module, decoder, mesh, attrib ) {
  90. var attribute = decoder.GetAttribute( mesh, attrib ),
  91. numPoints = mesh.num_points();
  92. var dracoArray = new module.DracoFloat32Array();
  93. decoder.GetAttributeFloatForAllPoints( mesh, attribute, dracoArray );
  94. var size = numPoints * attribute.num_components(),
  95. output = new Float32Array( size );
  96. for ( var i = 0; i < size; ++ i ) {
  97. output[ i ] = dracoArray.GetValue( i );
  98. }
  99. module.destroy( dracoArray );
  100. return output;
  101. };
  102. SEA3D.GeometryDraco.prototype.readUint16Array = function ( module, decoder, mesh, attrib, type ) {
  103. var attribute = decoder.GetAttribute( mesh, attrib ),
  104. numPoints = mesh.num_points();
  105. var dracoArray = new module.DracoUInt16Array();
  106. decoder.GetAttributeUInt16ForAllPoints( mesh, attribute, dracoArray );
  107. var size = numPoints * attribute.num_components(),
  108. output = new Uint16Array( size );
  109. for ( var i = 0; i < size; ++ i ) {
  110. output[ i ] = dracoArray.GetValue( i );
  111. }
  112. module.destroy( dracoArray );
  113. return output;
  114. };
  115. //
  116. // Extension
  117. //
  118. THREE.SEA3D.EXTENSIONS_LOADER.push( {
  119. setTypeRead: function () {
  120. this.file.addClass( SEA3D.GeometryDraco, true );
  121. this.file.typeRead[ SEA3D.GeometryDraco.prototype.type ] = this.readGeometryBuffer;
  122. }
  123. } );