import * as zlib from 'zlib' ; import { InputStream } from './input-stream' ; import { IVector3 , IQuaternion , Matrix3x3 , Transform } from '../svf/schema' ; /**
 * Reader of "packfile" protocol used to encode various types of SVF assets,
 * for example, geometry metadata, or meshes.
 */ export class PackFileReader extends InputStream { protected _type : string ; protected _version : number ; protected _entries : any [ ] = [ ] ; protected _types : any [ ] = [ ] ; constructor ( buffer ) { super ( ( buffer [ 0 ] === 31 && buffer [ 1 ] === 139 ) ? zlib . gunzipSync ( buffer ) : buffer ) ; this . _type = this . getString ( this . getVarint ( ) ) ; this . _version = this . getInt32 ( ) ; this . parseContents ( ) ; } parseContents ( ) { const originalOffset = this . _offset ; this . seek ( this . length - 8 ) ; const entriesOffset = this . getUint32 ( ) ; const typesOffset = this . getUint32 ( ) ; this . _entries = [ ] ; this . seek ( entriesOffset ) ; const entriesCount = this . getVarint ( ) ; for ( let i = 0 ; i < entriesCount ; i ++ ) { this . _entries . push ( this . getUint32 ( ) ) ; } this . seek ( typesOffset ) ; const typesCount = this . getVarint ( ) ; for ( let i = 0 ; i < typesCount ; i ++ ) { const _class = this . getString ( this . getVarint ( ) ) ; const _type = this . getString ( this . getVarint ( ) ) ; this . _types . push ( { _class , _type , version : this . getVarint ( ) } ) ; } this . seek ( originalOffset ) ; } numEntries ( ) { return this . _entries . length ; } seekEntry ( i ) { if ( i >= this . numEntries ( ) ) { return null ; } const offset = this . _entries [ i ] ; this . seek ( offset ) ; const type = this . getUint32 ( ) ; if ( type >= this . _types . length ) { return null ; } return this . _types [ type ] ; } getVector3D ( ) { return { x : this . getFloat64 ( ) , y : this . getFloat64 ( ) , z : this . getFloat64 ( ) } ; } getQuaternion ( ) { return { x : this . getFloat32 ( ) , y : this . getFloat32 ( ) , z : this . getFloat32 ( ) , w : this . getFloat32 ( ) } ; } getMatrix3x3 ( ) { const elements = [ ] ; for ( let i = 0 ; i < 3 ; i ++ ) { for ( let j = 0 ; j < 3 ; j ++ ) { elements . push ( this . getFloat32 ( ) ) ; } } return elements ; } getTransform ( ) { const xformType = this . getUint8 ( ) ; let q , t , s , matrix ; switch ( xformType ) { case 0 : return { t : this . getVector3D ( ) } ; case 1 : q = this . getQuaternion ( ) ; t = this . getVector3D ( ) ; s = { x : 1 , y : 1 , z : 1 } ; return { q , t , s } ; case 2 : const scale = this . getFloat32 ( ) ; q = this . getQuaternion ( ) ; t = this . getVector3D ( ) ; s = { x : scale , y : scale , z : scale } ; return { q , t , s } ; case 3 : matrix = this . getMatrix3x3 ( ) ; t = this . getVector3D ( ) ; return { matrix , t } ; } return null ; } }