diff --git a/docs/tutorials/Fundamentals.md b/docs/tutorials/Fundamentals.md
index 626bce70a4..71cd75b5d1 100644
--- a/docs/tutorials/Fundamentals.md
+++ b/docs/tutorials/Fundamentals.md
@@ -47,7 +47,7 @@ with `{@link WFSSource}` and [Tile Map Service](https://wiki.osgeo.org/wiki/Tile
iTowns also has sources for many data formats: [vector tile](https://docs.mapbox.com/help/glossary/vector-tiles/) resources from [MapBox](https://www.mapbox.com/) with `{@link VectorTilesSource}`, [Potree](https://github.com/potree/potree) (`{@link PotreeSource}`) and
[Entwine](https://entwine.io/) (`{@link EntwinePointTileSource}`) 3D point clouds, [3DTiles](https://www.ogc.org/standards/3DTiles)
-mesh (b3dm) and point clouds (pnts) from web servers (`{@link C3DTilesSource}`) and from Cesium ion `{@link C3DTilesIonSource}`,
+mesh (b3dm) and point clouds (pnts) from web servers (`{@link C3DTilesSource}`), Cesium ion `{@link C3DTilesIonSource}` and from Google api `{@link C3DTilesGoogleSource}`,
[GeoJSON](https://geojson.org/) with `{@link FileSource}` and `{@link GeoJsonParser}`,
[KML](https://www.ogc.org/standards/kml) with `{@link FileSource}` and `{@link KMLParser}`, [GPX](https://www.topografix.com/gpx.asp)
with `{@link FileSource}` and `{@link GpxParser}` and oriented images with `{@link OrientedImageSource}`.
@@ -68,7 +68,7 @@ Several specific types of `Layers` exist, the use of which depends on the data t
- `{@link PointCloudLayer}` can be used to display 3D point clouds. Any point cloud formats are supported as long as the corresponding `Source` is provided.
Some point clouds formats such as Potree, Las and Entwine already have parsers defined in itowns that you can use. For 3D Tiles point clouds (pnts), use
`C3DTilesLayer`.
-- `{@link C3DTilesLayer}` can be used to display 3D Tiles layer (only b3dm and pnts and Google Photorealistic 3D Tiles).
+- `{@link C3DTilesLayer}` can be used to display 3D Tiles datasets in version 1.0 (b3dm, pnts and gltf tiles are supported).
- `{@link OrientedImageLayer}` can be used to display oriented images.
diff --git a/src/Main.js b/src/Main.js
index a4185e110a..5403d0d491 100644
--- a/src/Main.js
+++ b/src/Main.js
@@ -92,7 +92,7 @@ export { default as LASParser } from 'Parser/LASParser';
export { default as ISGParser } from 'Parser/ISGParser';
export { default as GDFParser } from 'Parser/GDFParser';
export { default as GTXParser } from 'Parser/GTXParser';
-export { enableDracoLoader, glTFLoader, legacyGLTFLoader } from 'Parser/B3dmParser';
+export { enableDracoLoader, glTFLoader, legacyGLTFLoader } from 'Parser/GLTFParser';
// 3D Tiles classes and extensions
// Exported to allow one to implement its own 3D Tiles extension which needs to
diff --git a/src/Parser/B3dmParser.js b/src/Parser/B3dmParser.js
index 603ffb455a..75efc7f7cb 100644
--- a/src/Parser/B3dmParser.js
+++ b/src/Parser/B3dmParser.js
@@ -1,14 +1,8 @@
import * as THREE from 'three';
-import Capabilities from 'Core/System/Capabilities';
import { GLTFLoader } from 'ThreeExtended/loaders/GLTFLoader';
-import { DRACOLoader } from 'ThreeExtended/loaders/DRACOLoader';
import LegacyGLTFLoader from 'Parser/deprecated/LegacyGLTFLoader';
-import shaderUtils from 'Renderer/Shader/ShaderUtils';
import utf8Decoder from 'Utils/Utf8Decoder';
import C3DTBatchTable from 'Core/3DTiles/C3DTBatchTable';
-import ReferLayerProperties from 'Layer/ReferencingLayerProperties';
-import { MeshBasicMaterial } from 'three';
-import disposeThreeMaterial from 'Utils/ThreeUtils';
import GLTFParser from './GLTFParser';
@@ -23,33 +17,6 @@ export const legacyGLTFLoader = new LegacyGLTFLoader();
/**
* @module B3dmParser
*/
-/**
- * Enable Draco decoding for gltf.
- * @param {string} path to draco library folder.
- * This library is mandatory to load b3dm with Draco compression.
- * @param {object} config optional configuration for Draco compression.
- *
- * The Draco library files are in folder itowns/examples/libs/draco/.
- * You are obliged to indicate this path when you want enable the Draco Decoding.
- *
- * For more information on Draco, read file in /itowns/examples/libs/draco/README.md.
- *
- * @example
Enable draco decoder
- * // if you copied the folder from /itowns/examples/libs/draco/ to your root project,
- * // You could set path with './'.
- * itowns.enableDracoLoader('./');
- */
-export function enableDracoLoader(path, config) {
- if (!path) {
- throw new Error('Path to draco folder is mandatory');
- }
- const dracoLoader = new DRACOLoader();
- dracoLoader.setDecoderPath(path);
- if (config) {
- dracoLoader.setDecoderConfig(config);
- }
- glTFLoader.setDRACOLoader(dracoLoader);
-}
export default {
/** Parse b3dm buffer and extract THREE.Scene and batch table
@@ -68,7 +35,6 @@ export default {
*/
parse(buffer, options) {
const gltfUpAxis = options.gltfUpAxis;
- const urlBase = options.urlBase;
if (!buffer) {
throw new Error('No array buffer provided.');
}
diff --git a/src/Parser/GLTFParser.js b/src/Parser/GLTFParser.js
index ee2103209a..f99acb9802 100644
--- a/src/Parser/GLTFParser.js
+++ b/src/Parser/GLTFParser.js
@@ -9,14 +9,9 @@ import ReferLayerProperties from 'Layer/ReferencingLayerProperties';
import { MeshBasicMaterial } from 'three';
import disposeThreeMaterial from 'Utils/ThreeUtils';
-const matrixChangeUpVectorZtoY = (new THREE.Matrix4()).makeRotationX(Math.PI / 2);
+const matrixChangeUpVectorYtoZ = (new THREE.Matrix4()).makeRotationX(Math.PI / 2);
export const glTFLoader = new GLTFLoader();
-const dracoLoader = new DRACOLoader();
-dracoLoader.setDecoderPath('./libs/draco/');
-
-
-glTFLoader.setDRACOLoader(dracoLoader);
export const legacyGLTFLoader = new LegacyGLTFLoader();
@@ -45,6 +40,9 @@ function filterUnsupportedSemantics(obj) {
/**
* @module GLTFParser
+ * Supports GLTF 1.0 and 2.0 loading.
+ * GLTF 2.0 loading is done with THREE.GltfLoader().
+ * Filters out non standard cesium-specific semantic that may have been added to gltf embedded in 3D Tiles.
*/
/**
* Enable Draco decoding for gltf.
@@ -75,23 +73,48 @@ export function enableDracoLoader(path, config) {
}
export default {
- /** Parse gltf buffer and extract THREE.Scene and batch table
+ /** Parse gltf buffer and extract THREE.Scene
* @param {ArrayBuffer} buffer - the gltf buffer.
* @param {Object} options - additional properties.
- * @param {Matrix4=} [options.gltfUpAxisMatrix={}] - Matrix4f up axis transformation, by default Z->Y is applied
+ * @param {Matrix4=} [options.gltfUpAxisMatrix={}] - Matrix4f up axis transformation, by default Y->Z is applied
* @param {string} options.urlBase - the base url of the glTF file (used to fetch textures for the embedded glTF model).
* @param {boolean=} [options.doNotPatchMaterial='false'] - disable patching material with logarithmic depth buffer support.
- * @param {float} [options.opacity=1.0] - the b3dm opacity. // unused here for now
+ * @param {boolean=} [options.frustumCulled='false'] - enable frustum culling.
* @param {boolean|Material=} [options.overrideMaterials='false'] - override b3dm's embedded glTF materials. If
* true, a threejs [MeshBasicMaterial](https://threejs.org/docs/index.html?q=meshbasic#api/en/materials/MeshBasicMaterial)
* is set up. config.overrideMaterials can also be a threejs [Material](https://threejs.org/docs/index.html?q=material#api/en/materials/Material)
* in which case it will be the material used to override.
- * @return {Promise} - a promise that resolves with an object containig a THREE.Scene (gltf) and a batch table (batchTable).
+ * @return {Promise} - a promise that resolves with an object containig a THREE.Scene (gltf)
*
*/
parse(buffer, options) {
const gltfUpAxisMatrix = options.gltfUpAxisMatrix;
const urlBase = options.urlBase;
+ const frustumCulled = !!(options.frustumCulled);
+
+ const init_mesh = function f_init(mesh) {
+ mesh.frustumCulled = frustumCulled;
+ if (mesh.material) {
+ if (options.overrideMaterials) {
+ const oldMat = mesh.material;
+ // Set up new material
+ if (typeof (options.overrideMaterials) === 'object' &&
+ options.overrideMaterials.isMaterial) {
+ mesh.material = options.overrideMaterials;
+ } else {
+ mesh.material = new MeshBasicMaterial();
+ }
+ disposeThreeMaterial(oldMat);
+ } else if (Capabilities.isLogDepthBufferSupported()
+ && mesh.material.isRawShaderMaterial
+ && !options.doNotPatchMaterial) {
+ shaderUtils.patchMaterialForLogDepthSupport(mesh.material);
+ console.warn('glTF shader has been patched to add log depth buffer support');
+ }
+ ReferLayerProperties(mesh.material, options.layer);
+ }
+ };
+
if (!buffer) {
throw new Error('No array buffer provided.');
}
@@ -102,42 +125,22 @@ export default {
const magicNumberByteLength = 4;
gltfHeader.magic = utf8Decoder.decode(new Uint8Array(buffer, 0, magicNumberByteLength));
if (gltfHeader.magic) {
- const promises = [];
- promises.push(new Promise((resolve/* , reject */) => {
+ const promiseGltf = new Promise((resolve/* , reject */) => {
const onload = (gltf) => {
for (const scene of gltf.scenes) {
scene.traverse(filterUnsupportedSemantics);
}
- // for gltf Z->Y is applied
+ // for gltf Y->Z is applied
if (!gltfUpAxisMatrix) {
- gltf.scene.applyMatrix4(matrixChangeUpVectorZtoY);
+ gltf.scene.applyMatrix4(matrixChangeUpVectorYtoZ);
} else {
gltf.scene.applyMatrix4(gltfUpAxisMatrix);
}
- const init_mesh = function f_init(mesh) {
- mesh.frustumCulled = false;
- if (mesh.material) {
- if (options.overrideMaterials) {
- const oldMat = mesh.material;
- // Set up new material
- if (typeof (options.overrideMaterials) === 'object' &&
- options.overrideMaterials.isMaterial) {
- mesh.material = options.overrideMaterials;
- } else {
- mesh.material = new MeshBasicMaterial();
- }
- disposeThreeMaterial(oldMat);
- } else if (Capabilities.isLogDepthBufferSupported()
- && mesh.material.isRawShaderMaterial
- && !options.doNotPatchMaterial) {
- shaderUtils.patchMaterialForLogDepthSupport(mesh.material);
- console.warn('glTF shader has been patched to add log depth buffer support');
- }
- ReferLayerProperties(mesh.material, options.layer);
- }
- };
- gltf.scene.traverse(init_mesh);
+ const shouldBePatchedForLogDepthSupport = Capabilities.isLogDepthBufferSupported() && !options.doNotPatchMaterial;
+ if (options.frustumCulling === false || options.overrideMaterials || shouldBePatchedForLogDepthSupport || options.layer) {
+ gltf.scene.traverse(init_mesh);
+ }
resolve(gltf);
};
@@ -149,8 +152,8 @@ export default {
} else {
glTFLoader.parse(buffer, urlBase, onload);
}
- }));
- return Promise.all(promises).then(values => (values[0]));
+ });
+ return promiseGltf;
} else {
throw new Error('Invalid gLTF file.');
}
diff --git a/src/Process/3dTilesProcessing.js b/src/Process/3dTilesProcessing.js
index 5069aef062..f461bbf88e 100644
--- a/src/Process/3dTilesProcessing.js
+++ b/src/Process/3dTilesProcessing.js
@@ -20,6 +20,7 @@ function requestNewTile(view, scheduler, geometryLayer, metadata, parent, redraw
if (geometryLayer.source.isC3DTilesGoogleSource) {
// special case to handle non-standard 3dTilesGoogle behavior
+ // see also https://github.com/CesiumGS/3d-tiles/issues/746
geometryLayer.source.completeMetadata(metadata);
}
diff --git a/src/Provider/3dTilesProvider.js b/src/Provider/3dTilesProvider.js
index 9fc188d5aa..eaeb0131fd 100644
--- a/src/Provider/3dTilesProvider.js
+++ b/src/Provider/3dTilesProvider.js
@@ -26,7 +26,7 @@ function b3dmToMesh(data, layer, url) {
});
}
-function gltfoMesh(data, layer, url) {
+function gltfToMesh(data, layer, url) {
const urlBase = THREE.LoaderUtils.extractUrlBase(url);
const options = {
gltfUpAxis: layer.tileset.asset.gltfUpAxis,
@@ -94,7 +94,6 @@ function executeCommand(command) {
// Patch for supporting 3D Tiles pre 1.0 (metadata.content.url) and 1.0
// (metadata.content.uri)
- // TODO should be responsability of each C3DTilesSource.completeMetadata to give the correct path.
const path = metadata.content && (metadata.content.url || metadata.content.uri);
const setLayer = (obj) => {
@@ -107,7 +106,7 @@ function executeCommand(command) {
const supportedFormats = {
b3dm: b3dmToMesh,
pnts: pntsParse,
- gltf: gltfoMesh,
+ gltf: gltfToMesh,
};
return Fetcher.arrayBuffer(url, layer.source.networkOptions, layer.source.urlParameters).then((result) => {
if (result !== undefined) {
diff --git a/src/Source/C3DTilesGoogleSource.js b/src/Source/C3DTilesGoogleSource.js
index b45e4db038..80277777bc 100644
--- a/src/Source/C3DTilesGoogleSource.js
+++ b/src/Source/C3DTilesGoogleSource.js
@@ -3,9 +3,9 @@ import C3DTilesSource from './C3DTilesSource';
/**
* @classdesc
- * An object defining the source connection to a 3DTiles asset of a [Google api](https://tile.googleapis.com).
+ * An object defining the source connection to a 3DTiles asset from a [Google api](https://tile.googleapis.com).
*
- * @extends Source
+ * @extends C3DTilesSource
*
* @property {boolean} isC3DTilesGoogleSource - Used to checkout whether this source is a C3DTilesGoogleSource. Default is
* true. You should not change this, as it is used internally for optimisation.
@@ -17,7 +17,7 @@ class C3DTilesGoogleSource extends C3DTilesSource {
* Create a new Source for 3D Tiles data from Google api.
*
* @constructor
- * @extends Source
+ * @extends C3DTilesSource
*
* @property {boolean} isC3DTilesGoogleSource - Used to checkout whether this source is a C3DTilesGoogleSource. Default is
* true. You should not change this, as it is used internally for optimisation.