Skip to content

Commit

Permalink
[Batch table] getDataForId and 3DTILES_batch_table_hierarchy supp…
Browse files Browse the repository at this point in the history
…ort (#627)

* separate file for BatchTable

* add getDataFromId method

* add BatchTableHierarchy extension support

* use batch table hierarchy extension in example
  • Loading branch information
mgermerie authored Jul 25, 2024
1 parent 8237b94 commit e6c7e8f
Show file tree
Hide file tree
Showing 15 changed files with 322 additions and 122 deletions.
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,8 @@ if ( intersects.length ) {
// Log the batch data
const batchTable = batchTableObject.batchTable;
const hoveredBatchid = batchidAttr.getX( face.a );
const batchData = batchTable.getData( 'BatchTableKey' );
if ( batchData ) {

console.log( batchData[ hoveredBatchid ] );

}
const batchData = batchTable.getDataFromId( hoveredBatchid );
console.log( batchData );

}

Expand Down
23 changes: 18 additions & 5 deletions example/b3dmExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ function init() {
scene.add( offsetGroup );

new B3DMLoader()
.loadAsync( 'https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/1.0/TilesetWithRequestVolume/city/lr.b3dm' )
.loadAsync( 'https://raw.githubusercontent.com/CesiumGS/cesium/main/Apps/SampleData/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm' )
.then( res => {

console.log( res );
Expand Down Expand Up @@ -186,12 +186,25 @@ function onMouseMove( e ) {
// Log the batch data
const batchTable = batchTableObject.batchTable;
hoveredBatchid = batchidAttr.getX( face.a );
const batchData = batchTable.getDataFromId( hoveredBatchid );

infoEl.innerText =
`_batchid : ${ hoveredBatchid }\n` +
`Latitude : ${ batchTable.getData( 'Latitude' )[ hoveredBatchid ].toFixed( 3 ) }\n` +
`Longitude : ${ batchTable.getData( 'Longitude' )[ hoveredBatchid ].toFixed( 3 ) }\n` +
`Height : ${ batchTable.getData( 'Height' )[ hoveredBatchid ].toFixed( 3 ) }\n`;
`_batchid : ${ hoveredBatchid }\n` +
`Area : ${ batchData[ 'height' ].toFixed( 3 ) }\n` +
`Height : ${ batchData[ 'height' ].toFixed( 3 ) }\n`;

const hierarchyData = batchData[ '3DTILES_batch_table_hierarchy' ];
for ( const className in hierarchyData ) {


for ( const instance in hierarchyData[ className ] ) {

infoEl.innerText +=
`${ instance } : ${ hierarchyData[ className ][ instance ] }\n`;

}

}

}

Expand Down
3 changes: 2 additions & 1 deletion src/base/loaders/B3DMLoaderBase.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FeatureTable, BatchTable } from '../../utilities/FeatureTable';
import { BatchTable } from '../../utilities/BatchTable';
import { FeatureTable } from '../../utilities/FeatureTable';

export interface B3DMBaseResult {

Expand Down
3 changes: 2 additions & 1 deletion src/base/loaders/B3DMLoaderBase.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// B3DM File Format
// https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/Batched3DModel/README.md

import { FeatureTable, BatchTable } from '../../utilities/FeatureTable.js';
import { BatchTable } from '../../utilities/BatchTable.js';
import { FeatureTable } from '../../utilities/FeatureTable.js';
import { LoaderBase } from './LoaderBase.js';
import { readMagicBytes } from '../../utilities/readMagicBytes.js';

Expand Down
3 changes: 2 additions & 1 deletion src/base/loaders/I3DMLoaderBase.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FeatureTable, BatchTable } from '../../utilities/FeatureTable';
import { BatchTable } from '../../utilities/BatchTable';
import { FeatureTable } from '../../utilities/FeatureTable';

export interface I3DMBaseResult {

Expand Down
3 changes: 2 additions & 1 deletion src/base/loaders/I3DMLoaderBase.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// I3DM File Format
// https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/Instanced3DModel/README.md

import { FeatureTable, BatchTable } from '../../utilities/FeatureTable.js';
import { BatchTable } from '../../utilities/BatchTable.js';
import { FeatureTable } from '../../utilities/FeatureTable.js';
import { arrayToString } from '../../utilities/arrayToString.js';
import { LoaderBase } from './LoaderBase.js';
import { readMagicBytes } from '../../utilities/readMagicBytes.js';
Expand Down
3 changes: 2 additions & 1 deletion src/base/loaders/PNTSLoaderBase.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FeatureTable, BatchTable } from '../../utilities/FeatureTable';
import { BatchTable } from '../../utilities/BatchTable';
import { FeatureTable } from '../../utilities/FeatureTable';

export interface PNTSBaseResult {

Expand Down
3 changes: 2 additions & 1 deletion src/base/loaders/PNTSLoaderBase.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// PNTS File Format
// https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/PointCloud/README.md

import { FeatureTable, BatchTable } from '../../utilities/FeatureTable.js';
import { BatchTable } from '../../utilities/BatchTable.js';
import { FeatureTable } from '../../utilities/FeatureTable.js';
import { readMagicBytes } from '../../utilities/readMagicBytes.js';
import { LoaderBase } from './LoaderBase.js';

Expand Down
3 changes: 2 additions & 1 deletion src/three/loaders/B3DMLoader.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { B3DMBaseResult } from '../../base/loaders/B3DMLoaderBase';
import { FeatureTable, BatchTable } from '../../utilities/FeatureTable';
import { BatchTable } from '../../utilities/BatchTable';
import { FeatureTable } from '../../utilities/FeatureTable';
import { LoadingManager, Group } from 'three';
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';

Expand Down
3 changes: 2 additions & 1 deletion src/three/loaders/I3DMLoader.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { I3DMBaseResult } from '../../base/loaders/I3DMLoaderBase';
import { FeatureTable, BatchTable } from '../../utilities/FeatureTable';
import { BatchTable } from '../../utilities/BatchTable';
import { FeatureTable } from '../../utilities/FeatureTable';
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
import { Group, LoadingManager } from 'three';

Expand Down
18 changes: 18 additions & 0 deletions src/utilities/BatchTable.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export class BatchTable {

constructor(
buffer : ArrayBuffer,
batchSize : Number,
start : Number,
headerLength : Number,
binLength : Number
);

getKeys() : Array< String >;

getDataFromId(
id: Number,
target?: Object
) : Object;

}
67 changes: 67 additions & 0 deletions src/utilities/BatchTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { BatchTableHierarchyExtension } from './BatchTableHierarchyExtension.js';
import { FeatureTable } from './FeatureTable.js';

export class BatchTable extends FeatureTable {

constructor( buffer, batchSize, start, headerLength, binLength ) {

super( buffer, start, headerLength, binLength );
this.batchSize = batchSize;

this.extensions = {};
const extensions = this.header.extensions;
if ( extensions ) {

if ( extensions[ '3DTILES_batch_table_hierarchy' ] ) {

this.extensions[ '3DTILES_batch_table_hierarchy' ] = new BatchTableHierarchyExtension( this );

}

}

}

getData( key, componentType = null, type = null ) {

console.warn( 'BatchTable: BatchTable.getData is deprecated. Use BatchTable.getDataFromId instead.' );
return super.getData( key, this.batchSize, componentType, type );

}

getDataFromId( id, target = {} ) {

if ( id < 0 || id >= this.batchSize ) {

throw new Error( `BatchTable: id value "${ id }" out of bounds for "${ this.batchSize }" features number.` );

}

for ( const key of this.getKeys() ) {

if ( key !== 'extensions' ) {

target[ key ] = super.getData( key, this.batchSize )[ id ];

}

}

for ( const extensionName in this.extensions ) {

const extension = this.extensions[ extensionName ];

if ( extension.getDataFromId instanceof Function ) {

target[ extensionName ] = target[ extensionName ] || {};
extension.getDataFromId( id, target[ extensionName ] );

}

}

return target;

}

}
127 changes: 127 additions & 0 deletions src/utilities/BatchTableHierarchyExtension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
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;

}

}
20 changes: 0 additions & 20 deletions src/utilities/FeatureTable.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,3 @@ export class FeatureTable {
getBuffer( byteOffset : Number, byteLength : Number ) : ArrayBuffer;

}

export class BatchTable {

constructor(
buffer : ArrayBuffer,
batchSize : Number,
start : Number,
headerLength : Number,
binLength : Number
);

getKeys() : Array< String >;

getData(
key : String,
componentType : String | null,
type : String | null
) : Number | String | ArrayBufferView;

}
Loading

0 comments on commit e6c7e8f

Please sign in to comment.