TiltLoader.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import {
  2. BufferAttribute,
  3. BufferGeometry,
  4. Color,
  5. FileLoader,
  6. Group,
  7. Loader,
  8. Points,
  9. PointsMaterial
  10. } from "../../../build/three.module.js";
  11. import { JSZip } from "../libs/jszip.module.min.js";
  12. class TiltLoader extends Loader {
  13. load( url, onLoad, onProgress, onError ) {
  14. const scope = this;
  15. const loader = new FileLoader( this.manager );
  16. loader.setPath( this.path );
  17. loader.setResponseType( 'arraybuffer' );
  18. loader.setWithCredentials( this.withCredentials );
  19. loader.load( url, function ( buffer ) {
  20. try {
  21. onLoad( scope.parse( buffer ) );
  22. } catch ( e ) {
  23. if ( onError ) {
  24. onError( e );
  25. } else {
  26. console.error( e );
  27. }
  28. scope.manager.itemError( url );
  29. }
  30. }, onProgress, onError );
  31. }
  32. parse( buffer ) {
  33. const group = new Group();
  34. // https://docs.google.com/document/d/11ZsHozYn9FnWG7y3s3WAyKIACfbfwb4PbaS8cZ_xjvo/edit#
  35. const zip = new JSZip( buffer.slice( 16 ) ); // eslint-disable-line no-undef
  36. /*
  37. const thumbnail = zip.files[ 'thumbnail.png' ].asArrayBuffer();
  38. const img = document.createElement( 'img' );
  39. img.src = URL.createObjectURL( new Blob( [ thumbnail ] ) );
  40. document.body.appendChild( img );
  41. const metadata = JSON.parse( zip.files[ 'metadata.json' ].asText() );
  42. */
  43. /*
  44. const blob = new Blob( [ zip.files[ 'data.sketch' ].asArrayBuffer() ], { type: 'application/octet-stream' } );
  45. window.open( URL.createObjectURL( blob ) );
  46. */
  47. const data = new DataView( zip.files[ 'data.sketch' ].asArrayBuffer() );
  48. const num_strokes = data.getInt32( 16, true );
  49. let offset = 20;
  50. for ( let i = 0; i < num_strokes; i ++ ) {
  51. const brush_index = data.getInt32( offset, true );
  52. const brush_color = [
  53. data.getFloat32( offset + 4, true ),
  54. data.getFloat32( offset + 8, true ),
  55. data.getFloat32( offset + 12, true ),
  56. data.getFloat32( offset + 16, true )
  57. ];
  58. const brush_size = data.getFloat32( offset + 20, true );
  59. const stroke_mask = data.getUint32( offset + 24, true );
  60. const controlpoint_mask = data.getUint32( offset + 28, true );
  61. let offset_stroke_mask = 0;
  62. let offset_controlpoint_mask = 0;
  63. for ( let j = 0; j < 4; j ++ ) {
  64. const byte = 1 << j;
  65. if ( ( stroke_mask & byte ) > 0 ) offset_stroke_mask += 4;
  66. if ( ( controlpoint_mask & byte ) > 0 ) offset_controlpoint_mask += 4;
  67. }
  68. // console.log( { brush_index, brush_color, brush_size, stroke_mask, controlpoint_mask } );
  69. // console.log( offset_stroke_mask, offset_controlpoint_mask );
  70. offset = offset + 28 + offset_stroke_mask + 4; // TOFIX
  71. const num_control_points = data.getInt32( offset, true );
  72. // console.log( { num_control_points } );
  73. const positions = new Float32Array( num_control_points * 3 );
  74. const quaternions = new Float32Array( num_control_points * 4 );
  75. offset = offset + 4;
  76. for ( let j = 0, k = 0; j < positions.length; j += 3, k += 4 ) {
  77. positions[ j + 0 ] = data.getFloat32( offset + 0, true );
  78. positions[ j + 1 ] = data.getFloat32( offset + 4, true );
  79. positions[ j + 2 ] = data.getFloat32( offset + 8, true );
  80. quaternions[ k + 0 ] = data.getFloat32( offset + 12, true );
  81. quaternions[ k + 1 ] = data.getFloat32( offset + 16, true );
  82. quaternions[ k + 2 ] = data.getFloat32( offset + 20, true );
  83. quaternions[ k + 3 ] = data.getFloat32( offset + 24, true );
  84. offset = offset + 28 + offset_controlpoint_mask;
  85. }
  86. // console.log( positions, quaternions );
  87. const geometry = new BufferGeometry();
  88. geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
  89. const material = new PointsMaterial( { color: new Color().fromArray( brush_color ), size: brush_size } );
  90. group.add( new Points( geometry, material ) );
  91. }
  92. return group;
  93. }
  94. }
  95. export { TiltLoader };