Skip to content

Commit 6aa4473

Browse files
gkjohnsongeorginahalpernGeorgina Halpern
authored
Add support for Babylon tiles renderer (#1389)
* Add babylon renderer * Add a README * Adjust aliases * Move comment * Add demos * Fixups * Remove log * Clean up demos * Add minimum types * Add new demos * Reduce scratch math object creation * Reduce scratch variable creation * Use specific imports * Fixes * Fix frustums * Fix import usage * Add attributions to the index js example * Add initial work for babylon google attributions * simplify styles * Fix lint issue * Update babylon-support branch to use GeospatialCamera, es6 imports, module-level GTLF loader function, auto-detect extension, and observables (#1467) * add PR changes * use geo cam * with debug logs * obb changes * better starting view * cleanup * try * depth buffer * remove reverse depth buffer * geospatial cam * cleanup and packagelock.json * packagelock * Remove space * comments * adjust babylon peer dependencies * Remove the need load the gltf json twice * Update package lock * Remove sample gltf file comment * Remove console log from example * Ensure the babylon packages are marked as optional --------- Co-authored-by: Georgina Halpern <[email protected]> Co-authored-by: Garrett Johnson <[email protected]> * cached -> engineData * Pass the extension in the "parse" function * store metadata from json (#1468) Co-authored-by: Georgina Halpern <[email protected]> * Adjust clear colors * group -> scene * README update --------- Co-authored-by: Georgie <[email protected]> Co-authored-by: Georgina Halpern <[email protected]>
1 parent 5885451 commit 6aa4473

File tree

18 files changed

+2746
-1511
lines changed

18 files changed

+2746
-1511
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>Google Maps Aerial - Babylon.js 3D Tiles</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
7+
<link rel="stylesheet" href="../styles.css">
8+
</head>
9+
10+
<body>
11+
<div id="info">
12+
<div>
13+
Tokyo Tower example using <a href="https://cloud.google.com/blog/products/maps-platform/create-immersive-3d-map-experiences-photorealistic-3d-tiles">Googles Photorealistic 3D Tiles</a> & <a href="https://ion.cesium.com/">Cesium Ion</a>
14+
<br/>
15+
Google Cloud or Cesium Ion API token required
16+
</div>
17+
</div>
18+
19+
<div id="footer">
20+
<div id="credits"></div>
21+
<div id="logos">
22+
<img src="../logos/google.png" />
23+
<img src="../logos/cesiumion.png" />
24+
</div>
25+
</div>
26+
27+
<canvas id="renderCanvas"></canvas>
28+
<script type="module" src="./googleMapsAerial.js"></script>
29+
</body>
30+
31+
</html>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { Scene, Engine, GeospatialCamera, Vector3, Color4 } from '@babylonjs/core';
2+
import { GeospatialClippingBehavior } from '@babylonjs/core/Behaviors/Cameras';
3+
import { TilesRenderer } from '3d-tiles-renderer/babylonjs';
4+
import { CesiumIonAuthPlugin } from '3d-tiles-renderer/core/plugins';
5+
import GUI from 'lil-gui';
6+
7+
const GOOGLE_TILES_ASSET_ID = 2275207;
8+
9+
const PLANET_RADIUS = 6378137;
10+
11+
// gui
12+
const params = {
13+
enabled: true,
14+
visibleTiles: 0,
15+
errorTarget: 20,
16+
minZ: 0,
17+
maxZ: 0,
18+
};
19+
20+
const gui = new GUI();
21+
gui.add( params, 'enabled' );
22+
gui.add( params, 'visibleTiles' ).name( 'Visible Tiles' ).listen().disable();
23+
gui.add( params, 'errorTarget', 1, 100 );
24+
gui.add( params, 'minZ' ).name( 'Camera MinZ' ).listen().disable();
25+
gui.add( params, 'maxZ' ).name( 'Camera MaxZ' ).listen().disable();
26+
27+
// engine
28+
const canvas = document.getElementById( 'renderCanvas' );
29+
const engine = new Engine( canvas, true, { useLargeWorldRendering: true } );
30+
engine.setHardwareScalingLevel( 1 / window.devicePixelRatio );
31+
32+
// scene
33+
const scene = new Scene( engine );
34+
scene.clearColor = new Color4( 0.05, 0.05, 0.05, 1 );
35+
36+
// 3D Tiles data uses right-handed coordinate system
37+
scene.useRightHandedSystem = true;
38+
39+
// camera
40+
const camera = new GeospatialCamera( 'geo', scene, { planetRadius: PLANET_RADIUS } );
41+
42+
camera.attachControl( true );
43+
const clippingBehavior = new GeospatialClippingBehavior();
44+
camera.addBehavior( clippingBehavior );
45+
46+
// Start farther out, then fly in once tiles are loaded
47+
camera.radius = 50000;
48+
49+
// Set center to Tokyo Tower location (ECEF coordinates)
50+
// Tokyo Tower: 35.6586° N, 139.7454° E
51+
camera.center = new Vector3( - 3959611.825621192, 3352599.0363458656, 3697549.0362687325 );
52+
camera.pitch = 1.167625429373872;
53+
camera.yaw = - 0.2513281792775774;
54+
55+
camera.checkCollisions = true;
56+
scene.collisionsEnabled = true;
57+
58+
// Fly to close view once tiles load
59+
let hasZoomedIn = false;
60+
61+
// tiles
62+
const tiles = new TilesRenderer( null, scene );
63+
tiles.registerPlugin( new CesiumIonAuthPlugin( {
64+
apiToken: import.meta.env.VITE_ION_KEY,
65+
assetId: GOOGLE_TILES_ASSET_ID,
66+
autoRefreshToken: true,
67+
} ) );
68+
tiles.errorTarget = params.errorTarget;
69+
70+
// Babylon render loop
71+
72+
scene.onBeforeRenderObservable.add( () => {
73+
74+
if ( params.enabled ) {
75+
76+
tiles.errorTarget = params.errorTarget;
77+
tiles.update();
78+
params.visibleTiles = tiles.visibleTiles.size;
79+
params.minZ = camera.minZ;
80+
params.maxZ = camera.maxZ;
81+
82+
83+
// Once we have some tiles visible, fly in to target
84+
if ( ! hasZoomedIn && tiles.visibleTiles.size > 5 ) {
85+
86+
hasZoomedIn = true;
87+
camera.flyToAsync( undefined, undefined, 300, undefined, 2000 );
88+
89+
}
90+
91+
}
92+
93+
// update attributions
94+
const attributions = tiles.getAttributions();
95+
const creditsEl = document.getElementById( 'credits' );
96+
creditsEl.innerText = attributions[ 0 ]?.value || '';
97+
98+
} );
99+
100+
engine.runRenderLoop( () => {
101+
102+
scene.render();
103+
104+
} );
105+
106+
// Handle window resize
107+
window.addEventListener( 'resize', () => {
108+
109+
engine.resize();
110+
111+
} );

example/babylonjs/index.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>Babylon.js 3D Tiles Demo</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
7+
<link rel="stylesheet" href="../styles.css">
8+
</head>
9+
10+
<body>
11+
<div id="info">
12+
<div>
13+
Dingo Gap site reconstructed from multiple sols of Curiosity Rover and Mars Reconnaissance Orbiter images.
14+
<br/>
15+
See more information <a href="https://github.com/NASA-AMMOS/3DTilesSampleData/tree/master/msl-dingo-gap">here</a>.
16+
</div>
17+
</div>
18+
19+
<canvas id="renderCanvas"></canvas>
20+
<script type="module" src="./index.js"></script>
21+
</body>
22+
23+
</html>

example/babylonjs/index.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { Engine, Scene, ArcRotateCamera, Vector3, Color4 } from '@babylonjs/core';
2+
import { TilesRenderer } from '3d-tiles-renderer/babylonjs';
3+
import GUI from 'lil-gui';
4+
5+
const TILESET_URL = 'https://raw.githubusercontent.com/NASA-AMMOS/3DTilesSampleData/master/msl-dingo-gap/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize_tileset.json';
6+
7+
// gui
8+
const params = {
9+
enabled: true,
10+
visibleTiles: 0,
11+
};
12+
13+
const gui = new GUI();
14+
gui.add( params, 'enabled' );
15+
gui.add( params, 'visibleTiles' ).listen().disable();
16+
17+
// init engine
18+
const canvas = document.getElementById( 'renderCanvas' );
19+
const engine = new Engine( canvas, true, { useLargeWorldRendering: true } );
20+
engine.setHardwareScalingLevel( 1 / window.devicePixelRatio );
21+
22+
// scene
23+
const scene = new Scene( engine );
24+
scene.clearColor = new Color4( 0.05, 0.05, 0.05, 1 );
25+
scene.useRightHandedSystem = true;
26+
27+
// Camera controls
28+
const camera = new ArcRotateCamera(
29+
'camera',
30+
- Math.PI / 2,
31+
Math.PI / 2.5,
32+
50,
33+
new Vector3( 0, 0, 0 ),
34+
scene,
35+
);
36+
camera.attachControl( canvas, true );
37+
camera.minZ = 0.1;
38+
camera.maxZ = 1000;
39+
40+
// instantiate tiles renderer and orient the group so it's Z+ down
41+
const tiles = new TilesRenderer( TILESET_URL, scene );
42+
tiles.group.rotation.x = Math.PI / 2;
43+
44+
// render
45+
scene.onBeforeRenderObservable.add( () => {
46+
47+
if ( params.enabled ) {
48+
49+
tiles.update();
50+
51+
}
52+
53+
params.visibleTiles = tiles.visibleTiles.size;
54+
55+
} );
56+
57+
engine.runRenderLoop( () => {
58+
59+
scene.render();
60+
61+
} );
62+
63+
// resize
64+
window.addEventListener( 'resize', () => {
65+
66+
engine.resize();
67+
68+
} );

example/styles.css

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
padding: 0;
44
}
55

6-
html {
6+
html, body {
77
overflow: hidden;
88
font-family: Arial, Helvetica, sans-serif;
99
user-select: none;
10+
width: 100%;
11+
height: 100%;
12+
1013
}
1114

1215
canvas {
16+
width: 100%;
17+
height: 100%;
1318
image-rendering: pixelated;
1419
outline: none;
1520
}

0 commit comments

Comments
 (0)