-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
update loader to support google maps 3d tiles #39
Changes from 13 commits
3b8313f
2713397
3adade6
7ad6130
3ec802f
ae60d1e
1829eea
6dcd399
55478b5
2d343b6
fe1c114
ca9517f
9057f16
5a21624
75adece
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,19 @@ | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | ||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | ||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | ||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | ||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | ||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
PERFORMANCE OF THIS SOFTWARE. | ||
***************************************************************************** */ | ||
/** | ||
* @license | ||
* Copyright 2009 The Closure Library Authors | ||
* Copyright 2020 Daniel Wirtz / The long.js Authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>A-Frame 3D Tiles Component - Basic example</title> | ||
<meta name="description" content="Basic example for 3D Tiles component showing google 3d Tiles."></meta> | ||
<script src="https://aframe.io/releases/1.5.0/aframe.min.js"></script> | ||
<script src="../../dist/aframe-loader-3dtiles-component.js"></script> | ||
<!-- <script src="https://unpkg.com/3dstreet@0.4.5/dist/aframe-street-component.js"></script> --> | ||
|
||
<!-- vr teleport controls --> | ||
<!-- <script src="https://cdn.jsdelivr.net/npm/aframe-blink-controls@0.4.3/dist/aframe-blink-controls.min.js"></script> --> | ||
<style> | ||
#guide { | ||
position: fixed; | ||
top: 0; | ||
right: 0; | ||
width: 300px; | ||
padding: 1rem 2rem; | ||
font-family:'Courier New', Courier, monospace; | ||
line-height: 1.2; | ||
background-color: white; | ||
color: black; | ||
} | ||
|
||
#guide p { | ||
margin-top: 10px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<a-scene vr-mode-ui="enabled: false" renderer="colorManagement: true;"> | ||
<a-entity camera="fov:45; near:1; far: 1000" look-controls="reverseMouseDrag: true" wasd-controls="enabled: true" id="camera" cursor-teleport="cameraRig: #camera; cameraHead: #camera;"></a-entity> | ||
<a-entity | ||
id="tileset" | ||
loader-3dtiles=" | ||
url: https://tile.googleapis.com/v1/3dtiles/root.json; | ||
lat: 37.77522354250163; | ||
long: -122.41931773049723; | ||
height: -16.5; | ||
googleApiKey: INSERTYOURKEYHERE; | ||
geoTransform: WGS84Cartesian; | ||
maximumSSE: 48; | ||
maximumMem: 400; | ||
cameraEl: #camera" | ||
> | ||
</a-entity> | ||
</a-scene> | ||
|
||
<!-- GitHub Corner. --> | ||
<a href="https://github.com/nytimes/aframe-loader-3dtiles-component" class="github-corner"> | ||
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#222; color:#fff; position: absolute; top: 0; border: 0; right: 0;"> | ||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path> | ||
</svg> | ||
</a> | ||
<div id="guide"> | ||
<span id="example-desc"> | ||
<b>Google 3D Tiles example.</b> | ||
</span> | ||
<p>Use arrow/WASD keys to move around and click and drag to turn/rotate the camera.</p> | ||
<p> | ||
<u>Available component parameters:</u> | ||
<ul> | ||
<li><b>lat, long</b>: coordinates of Google Map.</li> | ||
<li><b>height</b>: camera height.</li> | ||
<li><b>googleApiKey</b>: Google Api Key.</li> | ||
</ul> | ||
</p> | ||
</div> | ||
<script> | ||
const queryParams = new URLSearchParams(document.location.search); | ||
|
||
if (queryParams.get('tilesetUrl')) { | ||
document.querySelector('#tileset').addEventListener('object3dset', (e) => { | ||
e.target.setAttribute('loader-3dtiles', { | ||
url: queryParams.get('tilesetUrl') | ||
}) | ||
}) | ||
} | ||
</script> | ||
<style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style> | ||
<!-- End GitHub Corner. --> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { Loader3DTiles, PointCloudColoring } from 'three-loader-3dtiles'; | ||
import { Vector3 } from 'three'; | ||
import { Loader3DTiles, PointCloudColoring, GeoTransform } from 'three-loader-3dtiles'; | ||
import './textarea'; | ||
import { Vector3 } from 'three'; | ||
|
||
if (typeof AFRAME === 'undefined') { | ||
throw new Error('Component attempted to register before AFRAME was available.'); | ||
|
@@ -28,24 +28,33 @@ AFRAME.registerComponent('loader-3dtiles', { | |
pointcloudElevationRange: { type: 'array', default: ['0', '400'] }, | ||
wireframe: { type: 'boolean', default: false }, | ||
showStats: { type: 'boolean', default: false }, | ||
cesiumIONToken: { type: 'string' } | ||
cesiumIONToken: { type: 'string' }, | ||
googleApiKey: { type: 'string' }, | ||
lat: { type: 'number' }, | ||
long: { type: 'number' }, | ||
height: { type: 'number' }, | ||
geoTransform: { type: 'string', default: 'Reset' } | ||
}, | ||
init: async function () { | ||
this.camera = this.data.cameraEl?.object3D.children[0] ?? document.querySelector('a-scene').camera; | ||
if (!this.camera) { | ||
throw new Error('3D Tiles: Please add an active camera or specify the target camera via the cameraEl property'); | ||
} | ||
const { model, runtime } = await this._initTileset(); | ||
|
||
this.el.setObject3D('tileset', model); | ||
|
||
this.originalCamera = this.camera; | ||
this.el.sceneEl.renderer.preserveDrawingBuffer = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll check with Alex, but I'm pretty sure this is not needed and was only included to improve generation of screenshots for our use case. We can remove this and add elsewhere in our application instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok this has been removed. Just to make sure I tested with and without and didn't notice any effect. |
||
|
||
this.el.sceneEl.addEventListener('camera-set-active', (e) => { | ||
// TODO: For some reason after closing the inspector this event is fired with an empty camera, | ||
// so revert to the original camera used. | ||
// | ||
// TODO: Does not provide the right Inspector perspective camera | ||
this.camera = e.detail.cameraEl.object3D.children[0] ?? this.originalCamera; | ||
}); | ||
|
||
this.el.sceneEl.addEventListener('enter-vr', (e) => { | ||
this.originalCamera = this.camera; | ||
try { | ||
|
@@ -86,7 +95,9 @@ AFRAME.registerComponent('loader-3dtiles', { | |
this.runtime = null; | ||
} | ||
const { model, runtime } = await this._initTileset(); | ||
|
||
this.el.setObject3D('tileset', model); | ||
|
||
await this._nextFrame(); | ||
this.runtime = runtime; | ||
} else if (this.runtime) { | ||
|
@@ -103,10 +114,24 @@ AFRAME.registerComponent('loader-3dtiles', { | |
this.el.sceneEl.removeChild(this.stats); | ||
this.stats = null; | ||
} | ||
|
||
// set parameters for google 3dtiles API | ||
if (this.data.lat && this.data.long && this.data.height) { | ||
// eslint-disable-next-line no-unused-vars | ||
const { model, runtime } = await this._initTileset(); | ||
|
||
console.log(this.data.lat, this.data.long, this.data.height); | ||
|
||
this.runtime.orientToGeocoord({ | ||
lat: Number(this.data.lat), | ||
long: Number(this.data.long), | ||
height: Number(this.data.height) | ||
}); | ||
} | ||
}, | ||
tick: function (t, dt) { | ||
if (this.runtime) { | ||
this.runtime.update(dt, this.el.sceneEl.renderer, this.camera); | ||
this.runtime.update(dt, this.el.sceneEl.clientHeight, this.camera); | ||
if (this.stats) { | ||
const worldPos = new Vector3(); | ||
this.camera.getWorldPosition(worldPos); | ||
|
@@ -139,20 +164,22 @@ AFRAME.registerComponent('loader-3dtiles', { | |
}, | ||
_initTileset: async function () { | ||
const pointCloudColoring = this._resolvePointcloudColoring(this.data.pointcloudColoring); | ||
|
||
return Loader3DTiles.load({ | ||
url: this.data.url, | ||
renderer: this.el.sceneEl.renderer, | ||
options: { | ||
dracoDecoderPath: 'https://unpkg.com/three@0.137.0/examples/js/libs/draco', | ||
basisTranscoderPath: 'https://unpkg.com/three@0.137.0/examples/js/libs/basis', | ||
googleApiKey: this.data.googleApiKey, | ||
cesiumIONToken: this.data.cesiumIONToken, | ||
dracoDecoderPath: 'https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco', | ||
basisTranscoderPath: 'https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/basis', | ||
maximumScreenSpaceError: this.data.maximumSSE, | ||
maximumMemoryUsage: this.data.maximumMem, | ||
memoryCacheOverflow: 128, | ||
pointCloudColoring: pointCloudColoring, | ||
viewDistanceScale: this.data.distanceScale, | ||
wireframe: this.data.wireframe, | ||
pointCloudColoring: pointCloudColoring, | ||
updateTransforms: true | ||
updateTransforms: true, | ||
geoTransform: GeoTransform[this.data.geoTransform] | ||
} | ||
}); | ||
}, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The example demo states that this and also lat/long/height are available parameters but there is no option to insert them via the query string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, the expected behavior in this example is only to place tiles with a long / lat / height specified in the index.html centered at scene origin 0 0 0. Supporting a dynamic, user-specified querystring with lat / long / height was not intended to be part of this example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it.
It's maybe OK since the example is anyway not exposed in the demo showcase, but if it works well we should probably consider adding it in the future and also make the example usable without editing the code. Maybe after we have occlusion culling and teleport controls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes agreed. I've added these tickets to track: