| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import { I3DMLoaderBase } from '../base/I3DMLoaderBase.js';
- import { DefaultLoadingManager, Matrix4, InstancedMesh, Vector3, Quaternion } from 'three';
- import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
- const tempPos = new Vector3();
- const tempQuat = new Quaternion();
- const tempSca = new Vector3();
- const tempMat = new Matrix4();
- export class I3DMLoader extends I3DMLoaderBase {
- constructor( manager = DefaultLoadingManager ) {
- super();
- this.manager = manager;
- }
- parse( buffer ) {
- return super
- .parse( buffer )
- .then( i3dm => {
- const { featureTable, batchTable } = i3dm;
- const gltfBuffer = i3dm.glbBytes.slice().buffer;
- return new Promise( ( resolve, reject ) => {
- const manager = this.manager;
- const loader = manager.getHandler( 'path.gltf' ) || new GLTFLoader( manager );
- loader.parse( gltfBuffer, null, model => {
- const INSTANCES_LENGTH = featureTable.getData( 'INSTANCES_LENGTH' );
- // RTC_CENTER
- // QUANTIZED_VOLUME_OFFSET
- // QUANTIZED_VOLUME_SCALE
- // EAST_NORTH_UP
- const POSITION = featureTable.getData( 'POSITION', INSTANCES_LENGTH, 'FLOAT', 'VEC3' );
- // POSITION_QUANTIZED
- // NORMAL_UP
- // NORMAL_RIGHT
- // NORMAL_UP_OCT32P
- // NORMAL_RIGHT_OCT32P
- // SCALE
- // SCALE_NON_UNIFORM
- // BATCH_ID
- const instanceMap = new Map();
- const instances = [];
- model.scene.traverse( child => {
- if ( child.isMesh ) {
- const { geometry, material } = child;
- const instancedMesh = new InstancedMesh( geometry, material, INSTANCES_LENGTH );
- instances.push( instancedMesh );
- instanceMap.set( child, instancedMesh );
- }
- } );
- // replace the meshes with instanced meshes
- instanceMap.forEach( ( instancedMesh, mesh ) => {
- const parent = mesh.parent;
- if ( parent ) {
- // Mesh have no children
- parent.remove( mesh );
- parent.add( instancedMesh );
- }
- } );
- for ( let i = 0; i < INSTANCES_LENGTH; i ++ ) {
- // TODO: handle quantized position
- tempPos.set(
- POSITION[ i * 3 + 0 ],
- POSITION[ i * 3 + 1 ],
- POSITION[ i * 3 + 2 ],
- );
- // TODO: handle normal orientation features
- tempQuat.set( 0, 0, 0, 1 );
- // TODO: handle scale features
- tempSca.set( 1, 1, 1 );
- tempMat.compose( tempPos, tempQuat, tempSca );
- for ( let j = 0, l = instances.length; j < l; j ++ ) {
- const instance = instances[ j ];
- instance.setMatrixAt( i, tempMat );
- }
- }
- model.batchTable = batchTable;
- model.featureTable = featureTable;
- resolve( model );
- }, reject );
- } );
- } );
- }
- }
|