@@ -16,12 +16,12 @@ import {
1616import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js' ;
1717import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' ;
1818import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js' ;
19- import { estimateBytesUsed } from 'three/examples/jsm/utils/BufferGeometryUtils.js' ;
2019import Stats from 'three/examples/jsm/libs/stats.module.js' ;
2120import { CameraTransitionManager } from './src/camera/CameraTransitionManager.js' ;
2221import { TileCompressionPlugin } from './src/plugins/TileCompressionPlugin.js' ;
2322import { UpdateOnChangePlugin } from './src/plugins/UpdateOnChangePlugin.js' ;
2423import { TilesFadePlugin } from './src/plugins/fade/TilesFadePlugin.js' ;
24+ import { BatchedTilesPlugin } from './src/plugins/batched/BatchedTilesPlugin.js' ;
2525
2626let controls , scene , renderer , tiles , transition ;
2727let statsContainer , stats ;
@@ -35,8 +35,10 @@ const params = {
3535 enableCacheDisplay : false ,
3636 enableRendererStats : false ,
3737 apiKey : apiKey ,
38+ useBatchedMesh : Boolean ( new URLSearchParams ( window . location . hash . replace ( / ^ # / , '' ) ) . get ( 'batched' ) ) ,
39+ errorTarget : 40 ,
3840
39- ' reload' : reinstantiateTiles ,
41+ reload : reinstantiateTiles ,
4042
4143} ;
4244
@@ -59,7 +61,17 @@ function reinstantiateTiles() {
5961 tiles . registerPlugin ( new GoogleCloudAuthPlugin ( { apiToken : params . apiKey , autoRefreshToken : true } ) ) ;
6062 tiles . registerPlugin ( new TileCompressionPlugin ( ) ) ;
6163 tiles . registerPlugin ( new UpdateOnChangePlugin ( ) ) ;
62- tiles . registerPlugin ( new TilesFadePlugin ( ) ) ;
64+
65+ if ( params . useBatchedMesh ) {
66+
67+ tiles . registerPlugin ( new BatchedTilesPlugin ( { renderer } ) ) ;
68+
69+ } else {
70+
71+ tiles . registerPlugin ( new TilesFadePlugin ( ) ) ;
72+
73+ }
74+
6375 tiles . group . rotation . x = - Math . PI / 2 ;
6476
6577 // Note the DRACO compression files need to be supplied via an explicit source.
@@ -138,13 +150,19 @@ function init() {
138150
139151 } ) ;
140152
141- const mapsOptions = gui . addFolder ( 'Google Tiles' ) ;
153+ const mapsOptions = gui . addFolder ( 'Google Photorealistic Tiles' ) ;
142154 mapsOptions . add ( params , 'apiKey' ) ;
155+ mapsOptions . add ( params , 'useBatchedMesh' ) . listen ( ) ;
143156 mapsOptions . add ( params , 'reload' ) ;
144157
145158 const exampleOptions = gui . addFolder ( 'Example Options' ) ;
146159 exampleOptions . add ( params , 'enableCacheDisplay' ) ;
147160 exampleOptions . add ( params , 'enableRendererStats' ) ;
161+ exampleOptions . add ( params , 'errorTarget' , 5 , 100 , 1 ) . onChange ( ( ) => {
162+
163+ tiles . getPluginByName ( 'UPDATE_ON_CHANGE_PLUGIN' ) . needsUpdate = true ;
164+
165+ } ) ;
148166
149167 statsContainer = document . createElement ( 'div' ) ;
150168 document . getElementById ( 'info' ) . appendChild ( statsContainer ) ;
@@ -207,22 +225,34 @@ function updateHash() {
207225 cartographicResult . lon *= MathUtils . RAD2DEG ;
208226
209227 // update hash
210- const params = new URLSearchParams ( ) ;
211- params . set ( 'lat' , cartographicResult . lat . toFixed ( 4 ) ) ;
212- params . set ( 'lon' , cartographicResult . lon . toFixed ( 4 ) ) ;
213- params . set ( 'height' , cartographicResult . height . toFixed ( 2 ) ) ;
214- params . set ( 'az' , orientationResult . azimuth . toFixed ( 2 ) ) ;
215- params . set ( 'el' , orientationResult . elevation . toFixed ( 2 ) ) ;
216- params . set ( 'roll' , orientationResult . roll . toFixed ( 2 ) ) ;
217- window . history . replaceState ( undefined , undefined , `#${ params } ` ) ;
228+ const urlParams = new URLSearchParams ( ) ;
229+ urlParams . set ( 'lat' , cartographicResult . lat . toFixed ( 4 ) ) ;
230+ urlParams . set ( 'lon' , cartographicResult . lon . toFixed ( 4 ) ) ;
231+ urlParams . set ( 'height' , cartographicResult . height . toFixed ( 2 ) ) ;
232+ urlParams . set ( 'az' , orientationResult . azimuth . toFixed ( 2 ) ) ;
233+ urlParams . set ( 'el' , orientationResult . elevation . toFixed ( 2 ) ) ;
234+ urlParams . set ( 'roll' , orientationResult . roll . toFixed ( 2 ) ) ;
235+
236+ if ( params . useBatchedMesh ) {
237+
238+ urlParams . set ( 'batched' , 1 ) ;
239+
240+ }
241+ window . history . replaceState ( undefined , undefined , `#${ urlParams } ` ) ;
218242
219243}
220244
221245function initFromHash ( ) {
222246
223247 const hash = window . location . hash . replace ( / ^ # / , '' ) ;
224- const params = new URLSearchParams ( hash ) ;
225- if ( ! params . has ( 'lat' ) && ! params . has ( 'lon' ) ) {
248+ const urlParams = new URLSearchParams ( hash ) ;
249+ if ( urlParams . has ( 'batched' ) ) {
250+
251+ params . useBatchedMesh = Boolean ( urlParams . get ( 'batched' ) ) ;
252+
253+ }
254+
255+ if ( ! urlParams . has ( 'lat' ) && ! urlParams . has ( 'lon' ) ) {
226256
227257 return ;
228258
@@ -233,16 +263,16 @@ function initFromHash() {
233263
234264 // get the position fields
235265 const camera = transition . camera ;
236- const lat = parseFloat ( params . get ( 'lat' ) ) ;
237- const lon = parseFloat ( params . get ( 'lon' ) ) ;
238- const height = parseFloat ( params . get ( 'height' ) ) || 1000 ;
266+ const lat = parseFloat ( urlParams . get ( 'lat' ) ) ;
267+ const lon = parseFloat ( urlParams . get ( 'lon' ) ) ;
268+ const height = parseFloat ( urlParams . get ( 'height' ) ) || 1000 ;
239269
240- if ( params . has ( 'az' ) && params . has ( 'el' ) ) {
270+ if ( urlParams . has ( 'az' ) && urlParams . has ( 'el' ) ) {
241271
242272 // get the az el fields for rotation if present
243- const az = parseFloat ( params . get ( 'az' ) ) ;
244- const el = parseFloat ( params . get ( 'el' ) ) ;
245- const roll = parseFloat ( params . get ( 'roll' ) ) || 0 ;
273+ const az = parseFloat ( urlParams . get ( 'az' ) ) ;
274+ const el = parseFloat ( urlParams . get ( 'el' ) ) ;
275+ const roll = parseFloat ( urlParams . get ( 'roll' ) ) || 0 ;
246276
247277 // extract the east-north-up frame into matrix world
248278 WGS84_ELLIPSOID . getRotationMatrixFromAzElRoll (
@@ -287,6 +317,7 @@ function animate() {
287317
288318 // update tiles
289319 camera . updateMatrixWorld ( ) ;
320+ tiles . errorTarget = params . errorTarget ;
290321 tiles . update ( ) ;
291322
292323 renderer . render ( scene , camera ) ;
@@ -299,48 +330,23 @@ function animate() {
299330function updateHtml ( ) {
300331
301332 // render html text updates
302- const cacheFullness = tiles . lruCache . itemList . length / tiles . lruCache . maxSize ;
303333 let str = '' ;
304334
305335 if ( params . enableCacheDisplay ) {
306336
337+ const lruCache = tiles . lruCache ;
338+ const cacheFullness = lruCache . cachedBytes / lruCache . maxBytesSize ;
307339 str += `Downloading: ${ tiles . stats . downloading } Parsing: ${ tiles . stats . parsing } Visible: ${ tiles . visibleTiles . size } <br/>` ;
308-
309- const geomSet = new Set ( ) ;
310- tiles . traverse ( tile => {
311-
312- const scene = tile . cached . scene ;
313- if ( scene ) {
314-
315- scene . traverse ( c => {
316-
317- if ( c . geometry ) {
318-
319- geomSet . add ( c . geometry ) ;
320-
321- }
322-
323- } ) ;
324-
325- }
326-
327- } ) ;
328-
329- let count = 0 ;
330- geomSet . forEach ( g => {
331-
332- count += estimateBytesUsed ( g ) ;
333-
334- } ) ;
335- str += `Cache: ${ ( 100 * cacheFullness ) . toFixed ( 2 ) } % ~${ ( count / 1000 / 1000 ) . toFixed ( 2 ) } mb<br/>` ;
340+ str += `Cache: ${ ( 100 * cacheFullness ) . toFixed ( 2 ) } % ~${ ( lruCache . cachedBytes / 1000 / 1000 ) . toFixed ( 2 ) } mb<br/>` ;
336341
337342 }
338343
339344 if ( params . enableRendererStats ) {
340345
341346 const memory = renderer . info . memory ;
347+ const render = renderer . info . render ;
342348 const programCount = renderer . info . programs . length ;
343- str += `Geometries: ${ memory . geometries } Textures: ${ memory . textures } Programs: ${ programCount } ` ;
349+ str += `Geometries: ${ memory . geometries } Textures: ${ memory . textures } Programs: ${ programCount } Draw Calls: ${ render . calls } ` ;
344350
345351 }
346352
0 commit comments