|
@@ -0,0 +1,145 @@
|
|
|
+import {
|
|
|
+ BufferAttribute,
|
|
|
+ BufferGeometry,
|
|
|
+ Color,
|
|
|
+ FileLoader,
|
|
|
+ Group,
|
|
|
+ Loader,
|
|
|
+ Points,
|
|
|
+ PointsMaterial
|
|
|
+} from "../../../build/three.module.js";
|
|
|
+import { JSZip } from "../libs/jszip.module.min.js";
|
|
|
+
|
|
|
+class TiltLoader extends Loader {
|
|
|
+
|
|
|
+ load( url, onLoad, onProgress, onError ) {
|
|
|
+
|
|
|
+ const scope = this;
|
|
|
+
|
|
|
+ const loader = new FileLoader( this.manager );
|
|
|
+ loader.setPath( this.path );
|
|
|
+ loader.setResponseType( 'arraybuffer' );
|
|
|
+ loader.setWithCredentials( this.withCredentials );
|
|
|
+
|
|
|
+ loader.load( url, function ( buffer ) {
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ onLoad( scope.parse( buffer ) );
|
|
|
+
|
|
|
+ } catch ( e ) {
|
|
|
+
|
|
|
+ if ( onError ) {
|
|
|
+
|
|
|
+ onError( e );
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ console.error( e );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ scope.manager.itemError( url );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }, onProgress, onError );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ parse( buffer ) {
|
|
|
+
|
|
|
+ const group = new Group();
|
|
|
+ // https://docs.google.com/document/d/11ZsHozYn9FnWG7y3s3WAyKIACfbfwb4PbaS8cZ_xjvo/edit#
|
|
|
+
|
|
|
+ const zip = new JSZip( buffer.slice( 16 ) ); // eslint-disable-line no-undef
|
|
|
+
|
|
|
+ /*
|
|
|
+ const thumbnail = zip.files[ 'thumbnail.png' ].asArrayBuffer();
|
|
|
+ const img = document.createElement( 'img' );
|
|
|
+ img.src = URL.createObjectURL( new Blob( [ thumbnail ] ) );
|
|
|
+ document.body.appendChild( img );
|
|
|
+
|
|
|
+ const metadata = JSON.parse( zip.files[ 'metadata.json' ].asText() );
|
|
|
+ */
|
|
|
+
|
|
|
+ /*
|
|
|
+ const blob = new Blob( [ zip.files[ 'data.sketch' ].asArrayBuffer() ], { type: 'application/octet-stream' } );
|
|
|
+ window.open( URL.createObjectURL( blob ) );
|
|
|
+ */
|
|
|
+
|
|
|
+ const data = new DataView( zip.files[ 'data.sketch' ].asArrayBuffer() );
|
|
|
+
|
|
|
+ const num_strokes = data.getInt32( 16, true );
|
|
|
+
|
|
|
+ let offset = 20;
|
|
|
+
|
|
|
+ for ( let i = 0; i < num_strokes; i ++ ) {
|
|
|
+
|
|
|
+ const brush_index = data.getInt32( offset, true );
|
|
|
+ const brush_color = [
|
|
|
+ data.getFloat32( offset + 4, true ),
|
|
|
+ data.getFloat32( offset + 8, true ),
|
|
|
+ data.getFloat32( offset + 12, true ),
|
|
|
+ data.getFloat32( offset + 16, true )
|
|
|
+ ];
|
|
|
+ const brush_size = data.getFloat32( offset + 20, true );
|
|
|
+ const stroke_mask = data.getUint32( offset + 24, true );
|
|
|
+ const controlpoint_mask = data.getUint32( offset + 28, true );
|
|
|
+
|
|
|
+ let offset_stroke_mask = 0;
|
|
|
+ let offset_controlpoint_mask = 0;
|
|
|
+
|
|
|
+ for ( let j = 0; j < 4; j ++ ) {
|
|
|
+
|
|
|
+ const byte = 1 << j;
|
|
|
+ if ( ( stroke_mask & byte ) > 0 ) offset_stroke_mask += 4;
|
|
|
+ if ( ( controlpoint_mask & byte ) > 0 ) offset_controlpoint_mask += 4;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log( { brush_index, brush_color, brush_size, stroke_mask, controlpoint_mask } );
|
|
|
+ // console.log( offset_stroke_mask, offset_controlpoint_mask );
|
|
|
+
|
|
|
+ offset = offset + 28 + offset_stroke_mask + 4; // TOFIX
|
|
|
+
|
|
|
+ const num_control_points = data.getInt32( offset, true );
|
|
|
+
|
|
|
+ // console.log( { num_control_points } );
|
|
|
+
|
|
|
+ const positions = new Float32Array( num_control_points * 3 );
|
|
|
+ const quaternions = new Float32Array( num_control_points * 4 );
|
|
|
+
|
|
|
+ offset = offset + 4;
|
|
|
+
|
|
|
+ for ( let j = 0, k = 0; j < positions.length; j += 3, k += 4 ) {
|
|
|
+
|
|
|
+ positions[ j + 0 ] = data.getFloat32( offset + 0, true );
|
|
|
+ positions[ j + 1 ] = data.getFloat32( offset + 4, true );
|
|
|
+ positions[ j + 2 ] = data.getFloat32( offset + 8, true );
|
|
|
+
|
|
|
+ quaternions[ k + 0 ] = data.getFloat32( offset + 12, true );
|
|
|
+ quaternions[ k + 1 ] = data.getFloat32( offset + 16, true );
|
|
|
+ quaternions[ k + 2 ] = data.getFloat32( offset + 20, true );
|
|
|
+ quaternions[ k + 3 ] = data.getFloat32( offset + 24, true );
|
|
|
+
|
|
|
+ offset = offset + 28 + offset_controlpoint_mask;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log( positions, quaternions );
|
|
|
+
|
|
|
+ const geometry = new BufferGeometry();
|
|
|
+ geometry.setAttribute( 'position', new BufferAttribute( positions, 3 ) );
|
|
|
+ const material = new PointsMaterial( { color: new Color().fromArray( brush_color ), size: brush_size } );
|
|
|
+ group.add( new Points( geometry, material ) );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return group;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+export { TiltLoader };
|