diff --git a/examples/3d-tiles/app.js b/examples/3d-tiles/app.js index bbac7c0576..987199a0b7 100644 --- a/examples/3d-tiles/app.js +++ b/examples/3d-tiles/app.js @@ -106,12 +106,6 @@ export default class App extends PureComponent { } }); } else { - this.setState({ - viewState: { - ...this.state.viewState, - ...EXAMPLES_VIEWSTATE - } - }); const selectedExample = examplesByCategory[category].examples[name]; if (selectedExample && selectedExample.tileset) { tilesetUrl = `${DATA_URI}/${selectedExample.path}/${selectedExample.tileset}`; @@ -174,7 +168,21 @@ export default class App extends PureComponent { isWGS84, depthLimit, color, - onTileLoaded: tileHeader => this.forceUpdate() + onTileLoaded: tileHeader => { + const {name} = this.state; + // cannot parse the center from royalExhibitionBuilding dataset + if (tileHeader.depth === 0 && name !== 'royalExhibitionBuilding') { + const {center} = tileHeader.boundingVolume; + this.setState({ + viewState: { + ...this.state.viewState, + longitude: center[0], + latitude: center[1] + } + }); + } + this.forceUpdate(); + } }) ); } diff --git a/examples/3d-tiles/tileset-3d-layer.js b/examples/3d-tiles/tileset-3d-layer.js index f7621fc61c..6c0c283251 100644 --- a/examples/3d-tiles/tileset-3d-layer.js +++ b/examples/3d-tiles/tileset-3d-layer.js @@ -145,7 +145,7 @@ export default class Tileset3DLayer extends CompositeLayer { let parsedColors = colors; if (isRGB565) { - parsedColors = new Uint8Array(pointsCount * 4); + parsedColors = new Uint8ClampedArray(pointsCount * 4); for (let i = 0; i < pointsCount; i++) { const color = parseRGB565(colors[i]); parsedColors[i * 4] = color[0]; @@ -156,7 +156,7 @@ export default class Tileset3DLayer extends CompositeLayer { } if (colors && colors.length === pointsCount * 3) { - parsedColors = new Uint8Array(pointsCount * 4); + parsedColors = new Uint8ClampedArray(pointsCount * 4); for (let i = 0; i < pointsCount; i++) { parsedColors[i * 4] = colors[i * 3]; parsedColors[i * 4 + 1] = colors[i * 3 + 1]; @@ -166,7 +166,7 @@ export default class Tileset3DLayer extends CompositeLayer { } if (batchIds && batchTable) { - parsedColors = new Uint8Array(pointsCount * 4); + parsedColors = new Uint8ClampedArray(pointsCount * 4); for (let i = 0; i < pointsCount; i++) { const batchId = batchIds[i]; // TODO figure out what is `dimensions` used for diff --git a/modules/3d-tiles/src/tileset/helpers/bounding-volume.js b/modules/3d-tiles/src/tileset/helpers/bounding-volume.js index 578b8fe954..447043e68b 100644 --- a/modules/3d-tiles/src/tileset/helpers/bounding-volume.js +++ b/modules/3d-tiles/src/tileset/helpers/bounding-volume.js @@ -2,9 +2,10 @@ // See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md /* eslint-disable */ -import {Vector3, Matrix3, Matrix4} from 'math.gl'; +import {Vector3, Matrix3, Matrix4, degrees} from 'math.gl'; import {BoundingSphere, OrientedBoundingBox} from '@loaders.gl/math'; import assert from '../../utils/assert'; +import {Ellipsoid} from '@loaders.gl/math'; // const scratchProjectedBoundingSphere = new BoundingSphere(); @@ -26,15 +27,44 @@ const scratchTransform = new Matrix4(); export function createBoundingVolume(boundingVolumeHeader, transform, result) { assert(boundingVolumeHeader, '3D Tile: boundingVolume must be defined'); if (boundingVolumeHeader.box) { - return null; + // The first three elements define the x, y, and z values for the center of the box. + const [x, y, z] = boundingVolumeHeader.box; + let center = new Vector3(x, y, z); + center = new Matrix4(transform).transformVector(center); + center = Ellipsoid.WGS84.cartesianToCartographic(center, center); + + Object.assign(boundingVolumeHeader, {center}); + + return boundingVolumeHeader; // return createBox(boundingVolumeHeader.box, transform, result); } if (boundingVolumeHeader.region) { - return null; + // [west, south, east, north, minimum height, maximum height] + // Latitudes and longitudes are in the WGS 84 datum as defined in EPSG 4979 and are in radians. + // Heights are in meters above (or below) the WGS 84 ellipsoid. + const [west, south, east, north, minHeight, maxHeight] = boundingVolumeHeader.region; + + const center = new Vector3( + degrees((west + east) / 2), + degrees((north + south) / 2), + (minHeight + maxHeight) / 2 + ); + Object.assign(boundingVolumeHeader, {center}); + + return boundingVolumeHeader; // return createRegion(boundingVolumeHeader.region, transform, this._initialTransform, result); } if (boundingVolumeHeader.sphere) { - return null; + // The first three elements define the x, y, and z values for the center of the sphere in a right-handed 3-axis (x, y, z) + const [x, y, z] = boundingVolumeHeader.sphere; + let center = new Vector3(x, y, z); + + center = new Matrix4(transform).transformVector(center); + center = Ellipsoid.WGS84.cartesianToCartographic(center, center); + + Object.assign(boundingVolumeHeader, {center}); + + return boundingVolumeHeader; // return createSphere(boundingVolumeHeader.sphere, transform, result); } throw new Error('3D Tile: boundingVolume must contain a sphere, region, or box'); diff --git a/modules/3d-tiles/src/tileset/tile-3d-header.js b/modules/3d-tiles/src/tileset/tile-3d-header.js index 928612227c..1063ded647 100644 --- a/modules/3d-tiles/src/tileset/tile-3d-header.js +++ b/modules/3d-tiles/src/tileset/tile-3d-header.js @@ -139,6 +139,16 @@ export default class Tile3DHeader { return this._contentBoundingVolume || this._boundingVolume; } + // Get the bounding region derived from the tile's bounding volume. + get boundingRegion() { + return this._boundingVolume.boundingBox; + } + + // Get the bounding box derived from the tile's bounding volume. + get boundingBox() { + return this._boundingVolume.boundingRegion; + } + // Get the bounding sphere derived from the tile's bounding volume. get boundingSphere() { return this._boundingVolume.boundingSphere; @@ -151,6 +161,14 @@ export default class Tile3DHeader { return this._header.extras; } + get depth() { + return this._depth; + } + + get viewState() { + return this._viewState; + } + // Get the tile's screen space error. getScreenSpaceError({frustum, width, height}, useParentGeometricError) { const tileset = this._tileset; @@ -446,7 +464,7 @@ export default class Tile3DHeader { this._initialTransform = new Matrix4(parentInitialTransform).multiplyRight(this.transform); // TODO ? - this.computedTransform = new Matrix4(); // computedTransform; + // this.computedTransform = new Matrix4(); // computedTransform; } _initializeBoundingVolumes(tileHeader) { @@ -570,6 +588,8 @@ export default class Tile3DHeader { return; } + this.computedTransform = computedTransform; + // Matrix4.clone(computedTransform, this.computedTransform); // Update the bounding volumes