UNPKG

3d-tiles-renderer

Version:

https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification

128 lines (71 loc) 2.83 kB
import { parseBinArray } from './FeatureTable.js'; export class BatchTableHierarchyExtension { constructor( batchTable ) { this.batchTable = batchTable; const extensionHeader = batchTable.header.extensions[ '3DTILES_batch_table_hierarchy' ]; this.classes = extensionHeader.classes; for ( const classDef of this.classes ) { const instances = classDef.instances; for ( const property in instances ) { classDef.instances[ property ] = this._parseProperty( instances[ property ], classDef.length, property ); } } this.instancesLength = extensionHeader.instancesLength; this.classIds = this._parseProperty( extensionHeader.classIds, this.instancesLength, 'classIds' ); if ( extensionHeader.parentCounts ) { this.parentCounts = this._parseProperty( extensionHeader.parentCounts, this.instancesLength, 'parentCounts' ); } else { this.parentCounts = new Array( this.instancesLength ).fill( 1 ); } if ( extensionHeader.parentIds ) { const parentIdsLength = this.parentCounts.reduce( ( a, b ) => a + b, 0 ); this.parentIds = this._parseProperty( extensionHeader.parentIds, parentIdsLength, 'parentIds' ); } else { this.parentIds = null; } this.instancesIds = []; const classCounter = {}; for ( const classId of this.classIds ) { classCounter[ classId ] = classCounter[ classId ] ?? 0; this.instancesIds.push( classCounter[ classId ] ); classCounter[ classId ] ++; } } _parseProperty( property, propertyLength, propertyName ) { if ( Array.isArray( property ) ) { return property; } else { const { buffer, binOffset } = this.batchTable; const byteOffset = property.byteOffset; const componentType = property.componentType || 'UNSIGNED_SHORT'; const arrayStart = binOffset + byteOffset; return parseBinArray( buffer, arrayStart, propertyLength, 'SCALAR', componentType, propertyName ); } } getDataFromId( id, target = {} ) { // Get properties inherited from parents const parentCount = this.parentCounts[ id ]; if ( this.parentIds && parentCount > 0 ) { let parentIdsOffset = 0; for ( let i = 0; i < id; i ++ ) { parentIdsOffset += this.parentCounts[ i ]; } for ( let i = 0; i < parentCount; i ++ ) { const parentId = this.parentIds[ parentIdsOffset + i ]; if ( parentId !== id ) { this.getDataFromId( parentId, target ); } } } // Get properties proper to this instance const classId = this.classIds[ id ]; const instances = this.classes[ classId ].instances; const className = this.classes[ classId ].name; const instanceId = this.instancesIds[ id ]; for ( const key in instances ) { target[ className ] = target[ className ] || {}; target[ className ][ key ] = instances[ key ][ instanceId ]; } return target; } }