mirror of https://github.com/CesiumGS/cesium.git
Compare commits
11 Commits
bdcd200d47
...
b4ee10c6df
| Author | SHA1 | Date |
|---|---|---|
|
|
b4ee10c6df | |
|
|
48bbf6fd4f | |
|
|
59b9f79c4a | |
|
|
6a07d54781 | |
|
|
e2024b33bb | |
|
|
165d426689 | |
|
|
0daebfe832 | |
|
|
9bd92a616f | |
|
|
df75727e02 | |
|
|
f79f19f6fc | |
|
|
9311afbe3d |
|
|
@ -790,7 +790,17 @@ Resource.prototype.appendForwardSlash = function () {
|
||||||
* @returns {Promise<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority.
|
* @returns {Promise<ArrayBuffer>|undefined} a promise that will resolve to the requested data when loaded. Returns undefined if <code>request.throttle</code> is true and the request does not have high enough priority.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // load a single URL asynchronously
|
* // load a single URL asynchronously.
|
||||||
|
* // Note that fetchArrayBuffer may return 'undefined', and this will cause
|
||||||
|
* // an error here. There is no way to know when it will return 'undefined'
|
||||||
|
* // or an actual promise. If it returns 'undefined', it is necessary to
|
||||||
|
* // call it again, until it returns the actual promise. But it may not be
|
||||||
|
* // called again after it returned a promise, because then there will be
|
||||||
|
* // multiple promises. Also note that the returned promise may be
|
||||||
|
* // rejected and receive 'undefined' as the error, so it's impossible to
|
||||||
|
* // know WHY it was rejected. So you can either ignore that, or just try
|
||||||
|
* // it again, hoping that it will not be rejected next time.
|
||||||
|
* // If you are reading this: GOOD LUCK!
|
||||||
* resource.fetchArrayBuffer().then(function(arrayBuffer) {
|
* resource.fetchArrayBuffer().then(function(arrayBuffer) {
|
||||||
* // use the data
|
* // use the data
|
||||||
* }).catch(function(error) {
|
* }).catch(function(error) {
|
||||||
|
|
|
||||||
|
|
@ -21,16 +21,12 @@ import RequestState from "../Core/RequestState.js";
|
||||||
import RequestType from "../Core/RequestType.js";
|
import RequestType from "../Core/RequestType.js";
|
||||||
import Resource from "../Core/Resource.js";
|
import Resource from "../Core/Resource.js";
|
||||||
import RuntimeError from "../Core/RuntimeError.js";
|
import RuntimeError from "../Core/RuntimeError.js";
|
||||||
import Cesium3DContentGroup from "./Cesium3DContentGroup.js";
|
|
||||||
import Cesium3DTileContentFactory from "./Cesium3DTileContentFactory.js";
|
|
||||||
import Cesium3DTileContentState from "./Cesium3DTileContentState.js";
|
import Cesium3DTileContentState from "./Cesium3DTileContentState.js";
|
||||||
import Cesium3DTileContentType from "./Cesium3DTileContentType.js";
|
import Cesium3DTileContentType from "./Cesium3DTileContentType.js";
|
||||||
import Cesium3DTileOptimizationHint from "./Cesium3DTileOptimizationHint.js";
|
import Cesium3DTileOptimizationHint from "./Cesium3DTileOptimizationHint.js";
|
||||||
import Cesium3DTilePass from "./Cesium3DTilePass.js";
|
import Cesium3DTilePass from "./Cesium3DTilePass.js";
|
||||||
import Cesium3DTileRefine from "./Cesium3DTileRefine.js";
|
import Cesium3DTileRefine from "./Cesium3DTileRefine.js";
|
||||||
import Empty3DTileContent from "./Empty3DTileContent.js";
|
import Empty3DTileContent from "./Empty3DTileContent.js";
|
||||||
import findContentMetadata from "./findContentMetadata.js";
|
|
||||||
import findGroupMetadata from "./findGroupMetadata.js";
|
|
||||||
import findTileMetadata from "./findTileMetadata.js";
|
import findTileMetadata from "./findTileMetadata.js";
|
||||||
import hasExtension from "./hasExtension.js";
|
import hasExtension from "./hasExtension.js";
|
||||||
import Multiple3DTileContent from "./Multiple3DTileContent.js";
|
import Multiple3DTileContent from "./Multiple3DTileContent.js";
|
||||||
|
|
@ -43,6 +39,8 @@ import TileBoundingSphere from "./TileBoundingSphere.js";
|
||||||
import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js";
|
import TileOrientedBoundingBox from "./TileOrientedBoundingBox.js";
|
||||||
import Pass from "../Renderer/Pass.js";
|
import Pass from "../Renderer/Pass.js";
|
||||||
import VerticalExaggeration from "../Core/VerticalExaggeration.js";
|
import VerticalExaggeration from "../Core/VerticalExaggeration.js";
|
||||||
|
import finishContent from "./finishContent.js";
|
||||||
|
import Dynamic3DTileContent from "./Dynamic3DTileContent.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A tile in a {@link Cesium3DTileset}. When a tile is first created, its content is not loaded;
|
* A tile in a {@link Cesium3DTileset}. When a tile is first created, its content is not loaded;
|
||||||
|
|
@ -62,19 +60,6 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
this._tileset = tileset;
|
this._tileset = tileset;
|
||||||
this._header = header;
|
this._header = header;
|
||||||
|
|
||||||
const hasContentsArray = defined(header.contents);
|
|
||||||
const hasMultipleContents =
|
|
||||||
(hasContentsArray && header.contents.length > 1) ||
|
|
||||||
hasExtension(header, "3DTILES_multiple_contents");
|
|
||||||
|
|
||||||
// In the 1.0 schema, content is stored in tile.content instead of tile.contents
|
|
||||||
const contentHeader =
|
|
||||||
hasContentsArray && !hasMultipleContents
|
|
||||||
? header.contents[0]
|
|
||||||
: header.content;
|
|
||||||
|
|
||||||
this._contentHeader = contentHeader;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The local transform of this tile.
|
* The local transform of this tile.
|
||||||
* @type {Matrix4}
|
* @type {Matrix4}
|
||||||
|
|
@ -131,22 +116,6 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
);
|
);
|
||||||
this._boundingVolume2D = undefined;
|
this._boundingVolume2D = undefined;
|
||||||
|
|
||||||
let contentBoundingVolume;
|
|
||||||
|
|
||||||
if (defined(contentHeader) && defined(contentHeader.boundingVolume)) {
|
|
||||||
// Non-leaf tiles may have a content bounding-volume, which is a tight-fit bounding volume
|
|
||||||
// around only the features in the tile. This box is useful for culling for rendering,
|
|
||||||
// but not for culling for traversing the tree since it does not guarantee spatial coherence, i.e.,
|
|
||||||
// since it only bounds features in the tile, not the entire tile, children may be
|
|
||||||
// outside of this box.
|
|
||||||
contentBoundingVolume = this.createBoundingVolume(
|
|
||||||
contentHeader.boundingVolume,
|
|
||||||
computedTransform,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
this._contentBoundingVolume = contentBoundingVolume;
|
|
||||||
this._contentBoundingVolume2D = undefined;
|
|
||||||
|
|
||||||
let viewerRequestVolume;
|
let viewerRequestVolume;
|
||||||
if (defined(header.viewerRequestVolume)) {
|
if (defined(header.viewerRequestVolume)) {
|
||||||
viewerRequestVolume = this.createBoundingVolume(
|
viewerRequestVolume = this.createBoundingVolume(
|
||||||
|
|
@ -178,27 +147,6 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
|
|
||||||
this.updateGeometricErrorScale();
|
this.updateGeometricErrorScale();
|
||||||
|
|
||||||
let refine;
|
|
||||||
if (defined(header.refine)) {
|
|
||||||
if (header.refine === "replace" || header.refine === "add") {
|
|
||||||
Cesium3DTile._deprecationWarning(
|
|
||||||
"lowercase-refine",
|
|
||||||
`This tile uses a lowercase refine "${
|
|
||||||
header.refine
|
|
||||||
}". Instead use "${header.refine.toUpperCase()}".`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
refine =
|
|
||||||
header.refine.toUpperCase() === "REPLACE"
|
|
||||||
? Cesium3DTileRefine.REPLACE
|
|
||||||
: Cesium3DTileRefine.ADD;
|
|
||||||
} else if (defined(parent)) {
|
|
||||||
// Inherit from parent tile if omitted.
|
|
||||||
refine = parent.refine;
|
|
||||||
} else {
|
|
||||||
refine = Cesium3DTileRefine.REPLACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the type of refinement that is used when traversing this tile for rendering.
|
* Specifies the type of refinement that is used when traversing this tile for rendering.
|
||||||
*
|
*
|
||||||
|
|
@ -206,7 +154,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
* @readonly
|
* @readonly
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.refine = refine;
|
this.refine = determineRefine(header.refine, parent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the tile's children.
|
* Gets the tile's children.
|
||||||
|
|
@ -229,58 +177,6 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
*/
|
*/
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
|
||||||
let content;
|
|
||||||
let hasEmptyContent = false;
|
|
||||||
let contentState;
|
|
||||||
let contentResource;
|
|
||||||
let serverKey;
|
|
||||||
|
|
||||||
baseResource = Resource.createIfNeeded(baseResource);
|
|
||||||
|
|
||||||
if (hasMultipleContents) {
|
|
||||||
contentState = Cesium3DTileContentState.UNLOADED;
|
|
||||||
// Each content may have its own URI, but they all need to be resolved
|
|
||||||
// relative to the tileset, so the base resource is used.
|
|
||||||
contentResource = baseResource.clone();
|
|
||||||
} else if (defined(contentHeader)) {
|
|
||||||
let contentHeaderUri = contentHeader.uri;
|
|
||||||
if (defined(contentHeader.url)) {
|
|
||||||
Cesium3DTile._deprecationWarning(
|
|
||||||
"contentUrl",
|
|
||||||
'This tileset JSON uses the "content.url" property which has been deprecated. Use "content.uri" instead.',
|
|
||||||
);
|
|
||||||
contentHeaderUri = contentHeader.url;
|
|
||||||
}
|
|
||||||
if (contentHeaderUri === "") {
|
|
||||||
Cesium3DTile._deprecationWarning(
|
|
||||||
"contentUriEmpty",
|
|
||||||
"content.uri property is an empty string, which creates a circular dependency, making this tileset invalid. Omit the content property instead",
|
|
||||||
);
|
|
||||||
content = new Empty3DTileContent(tileset, this);
|
|
||||||
hasEmptyContent = true;
|
|
||||||
contentState = Cesium3DTileContentState.READY;
|
|
||||||
} else {
|
|
||||||
contentState = Cesium3DTileContentState.UNLOADED;
|
|
||||||
contentResource = baseResource.getDerivedResource({
|
|
||||||
url: contentHeaderUri,
|
|
||||||
});
|
|
||||||
serverKey = RequestScheduler.getServerKey(
|
|
||||||
contentResource.getUrlComponent(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
content = new Empty3DTileContent(tileset, this);
|
|
||||||
hasEmptyContent = true;
|
|
||||||
contentState = Cesium3DTileContentState.READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._content = content;
|
|
||||||
this._contentResource = contentResource;
|
|
||||||
this._contentState = contentState;
|
|
||||||
this._expiredContent = undefined;
|
|
||||||
|
|
||||||
this._serverKey = serverKey;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When <code>true</code>, the tile has no content.
|
* When <code>true</code>, the tile has no content.
|
||||||
*
|
*
|
||||||
|
|
@ -289,7 +185,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.hasEmptyContent = hasEmptyContent;
|
this.hasEmptyContent = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When <code>true</code>, the tile's content points to an external tileset.
|
* When <code>true</code>, the tile's content points to an external tileset.
|
||||||
|
|
@ -334,7 +230,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.hasRenderableContent = !hasEmptyContent;
|
this.hasRenderableContent = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When <code>true</code>, the tile contains content metadata from implicit tiling. This flag is set
|
* When <code>true</code>, the tile contains content metadata from implicit tiling. This flag is set
|
||||||
|
|
@ -362,7 +258,17 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
this.hasMultipleContents = hasMultipleContents;
|
this.hasMultipleContents = false;
|
||||||
|
|
||||||
|
// Initialize the content-related properties
|
||||||
|
this._contentBoundingVolume = undefined;
|
||||||
|
this._contentBoundingVolume2D = undefined;
|
||||||
|
this._content = undefined;
|
||||||
|
this._contentResource = undefined;
|
||||||
|
this._contentState = undefined;
|
||||||
|
this._expiredContent = undefined;
|
||||||
|
this._serverKey = undefined;
|
||||||
|
initializeContent(this, baseResource, header);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The node in the tileset's LRU cache, used to determine when to unload a tile's content.
|
* The node in the tileset's LRU cache, used to determine when to unload a tile's content.
|
||||||
|
|
@ -483,7 +389,7 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
*/
|
*/
|
||||||
this.implicitSubtree = undefined;
|
this.implicitSubtree = undefined;
|
||||||
|
|
||||||
// Members that are updated every frame for tree traversal and rendering optimizations:
|
// Members that are updated every frame for tree traversal and rendering optimizations.
|
||||||
this._distanceToCamera = 0.0;
|
this._distanceToCamera = 0.0;
|
||||||
this._centerZDepth = 0.0;
|
this._centerZDepth = 0.0;
|
||||||
this._screenSpaceError = 0.0;
|
this._screenSpaceError = 0.0;
|
||||||
|
|
@ -535,6 +441,161 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
|
||||||
this._request = undefined;
|
this._request = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the content-related properties of the given tile.
|
||||||
|
*
|
||||||
|
* This assumes that the <code>_tileset</code> and the
|
||||||
|
* <code>computedTransform</code> of the given tile have
|
||||||
|
* already been set.
|
||||||
|
*
|
||||||
|
* It will initialize the following properties of the tile, based
|
||||||
|
* on the given resource and header information:
|
||||||
|
*
|
||||||
|
* - _contentHeader
|
||||||
|
* - _contentBoundingVolume
|
||||||
|
* - _contentBoundingVolume2D
|
||||||
|
* - _content
|
||||||
|
* - _contentResource
|
||||||
|
* - _contentState
|
||||||
|
* - _expiredContent
|
||||||
|
* - _serverKey
|
||||||
|
* - hasEmptyContent
|
||||||
|
* - hasRenderableContent
|
||||||
|
* - hasMultipleContents
|
||||||
|
*
|
||||||
|
* The exact meaning of these properties has to be derived from
|
||||||
|
* the code. This function was just introduced as first cleanup.
|
||||||
|
*
|
||||||
|
* @param {Cesium3DTile} tile The tile
|
||||||
|
* @param {Resource} baseResource The base resource for the tileset
|
||||||
|
* @param {object} header The JSON header for the tile
|
||||||
|
*/
|
||||||
|
function initializeContent(tile, baseResource, header) {
|
||||||
|
const hasContentsArray = defined(header.contents);
|
||||||
|
const hasMultipleContents =
|
||||||
|
(hasContentsArray && header.contents.length > 1) ||
|
||||||
|
hasExtension(header, "3DTILES_multiple_contents");
|
||||||
|
|
||||||
|
// In the 1.0 schema, content is stored in tile.content instead of tile.contents
|
||||||
|
const contentHeader =
|
||||||
|
hasContentsArray && !hasMultipleContents
|
||||||
|
? header.contents[0]
|
||||||
|
: header.content;
|
||||||
|
|
||||||
|
let contentBoundingVolume;
|
||||||
|
|
||||||
|
if (defined(contentHeader) && defined(contentHeader.boundingVolume)) {
|
||||||
|
// Non-leaf tiles may have a content bounding-volume, which is a tight-fit bounding volume
|
||||||
|
// around only the features in the tile. This box is useful for culling for rendering,
|
||||||
|
// but not for culling for traversing the tree since it does not guarantee spatial coherence, i.e.,
|
||||||
|
// since it only bounds features in the tile, not the entire tile, children may be
|
||||||
|
// outside of this box.
|
||||||
|
contentBoundingVolume = tile.createBoundingVolume(
|
||||||
|
contentHeader.boundingVolume,
|
||||||
|
tile.computedTransform,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let content;
|
||||||
|
let contentState;
|
||||||
|
let contentResource;
|
||||||
|
let serverKey;
|
||||||
|
let hasEmptyContent = false;
|
||||||
|
|
||||||
|
baseResource = Resource.createIfNeeded(baseResource);
|
||||||
|
|
||||||
|
if (hasMultipleContents) {
|
||||||
|
contentState = Cesium3DTileContentState.UNLOADED;
|
||||||
|
// Each content may have its own URI, but they all need to be resolved
|
||||||
|
// relative to the tileset, so the base resource is used.
|
||||||
|
contentResource = baseResource.clone();
|
||||||
|
} else if (defined(contentHeader)) {
|
||||||
|
let contentHeaderUri = contentHeader.uri;
|
||||||
|
if (defined(contentHeader.url)) {
|
||||||
|
Cesium3DTile._deprecationWarning(
|
||||||
|
"contentUrl",
|
||||||
|
'This tileset JSON uses the "content.url" property which has been deprecated. Use "content.uri" instead.',
|
||||||
|
);
|
||||||
|
contentHeaderUri = contentHeader.url;
|
||||||
|
}
|
||||||
|
if (contentHeaderUri === "") {
|
||||||
|
Cesium3DTile._deprecationWarning(
|
||||||
|
"contentUriEmpty",
|
||||||
|
"content.uri property is an empty string, which creates a circular dependency, making this tileset invalid. Omit the content property instead",
|
||||||
|
);
|
||||||
|
content = new Empty3DTileContent(tile._tileset, tile);
|
||||||
|
hasEmptyContent = true;
|
||||||
|
contentState = Cesium3DTileContentState.READY;
|
||||||
|
} else {
|
||||||
|
contentState = Cesium3DTileContentState.UNLOADED;
|
||||||
|
contentResource = baseResource.getDerivedResource({
|
||||||
|
url: contentHeaderUri,
|
||||||
|
});
|
||||||
|
serverKey = RequestScheduler.getServerKey(
|
||||||
|
contentResource.getUrlComponent(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content = new Empty3DTileContent(tile._tileset, tile);
|
||||||
|
hasEmptyContent = true;
|
||||||
|
contentState = Cesium3DTileContentState.READY;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile._contentHeader = contentHeader;
|
||||||
|
tile._contentBoundingVolume = contentBoundingVolume;
|
||||||
|
tile._contentBoundingVolume2D = undefined;
|
||||||
|
tile._content = content;
|
||||||
|
tile._contentResource = contentResource;
|
||||||
|
tile._contentState = contentState;
|
||||||
|
tile._expiredContent = undefined;
|
||||||
|
tile._serverKey = serverKey;
|
||||||
|
tile.hasEmptyContent = hasEmptyContent;
|
||||||
|
tile.hasRenderableContent = !hasEmptyContent;
|
||||||
|
tile.hasMultipleContents = hasMultipleContents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value for the 'refine' property of a tile.
|
||||||
|
*
|
||||||
|
* If the given value from the header is one of the known, deprecated
|
||||||
|
* lowercase values ("add" or "remove"), then a deprecation warning
|
||||||
|
* will be printed, and the corresponding constant will be returned.
|
||||||
|
*
|
||||||
|
* If the value is <code>undefined</code>, and the parent is not
|
||||||
|
* <code>undefined</code>, then the value from the parent will
|
||||||
|
* be inherited and returned.
|
||||||
|
*
|
||||||
|
* Otherwise, <code>REPLACE</code> is returned as the default.
|
||||||
|
*
|
||||||
|
* @param {string|undefined} headerRefine The refine value from the JSON
|
||||||
|
* @param {Cesium3DTile|undefined} parent The parent tile
|
||||||
|
* @returns {number} The <code>Cesium3DTileRefine</code> value
|
||||||
|
*/
|
||||||
|
function determineRefine(headerRefine, parent) {
|
||||||
|
// Note: This will not create a warning for strings like "RePlAcE",
|
||||||
|
// but still handle them by uppercasing them.
|
||||||
|
if (defined(headerRefine)) {
|
||||||
|
if (headerRefine === "replace" || headerRefine === "add") {
|
||||||
|
Cesium3DTile._deprecationWarning(
|
||||||
|
"lowercase-refine",
|
||||||
|
`This tile uses a lowercase refine "${
|
||||||
|
headerRefine
|
||||||
|
}". Instead use "${headerRefine.toUpperCase()}".`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const refine =
|
||||||
|
headerRefine.toUpperCase() === "REPLACE"
|
||||||
|
? Cesium3DTileRefine.REPLACE
|
||||||
|
: Cesium3DTileRefine.ADD;
|
||||||
|
return refine;
|
||||||
|
}
|
||||||
|
if (defined(parent)) {
|
||||||
|
// Inherit from parent tile if omitted.
|
||||||
|
return parent.refine;
|
||||||
|
}
|
||||||
|
return Cesium3DTileRefine.REPLACE;
|
||||||
|
}
|
||||||
|
|
||||||
// This can be overridden for testing purposes
|
// This can be overridden for testing purposes
|
||||||
Cesium3DTile._deprecationWarning = deprecationWarning;
|
Cesium3DTile._deprecationWarning = deprecationWarning;
|
||||||
|
|
||||||
|
|
@ -1128,11 +1189,9 @@ Cesium3DTile.prototype.requestContent = function () {
|
||||||
if (this.hasEmptyContent) {
|
if (this.hasEmptyContent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.hasMultipleContents) {
|
if (this.hasMultipleContents) {
|
||||||
return requestMultipleContents(this);
|
return requestMultipleContents(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestSingleContent(this);
|
return requestSingleContent(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1350,52 +1409,12 @@ async function makeContent(tile, arrayBuffer) {
|
||||||
tile.hasRenderableContent = false;
|
tile.hasRenderableContent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let content;
|
|
||||||
const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType];
|
|
||||||
if (tile.isDestroyed()) {
|
if (tile.isDestroyed()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const resource = tile._contentResource;
|
||||||
if (defined(preprocessed.binaryPayload)) {
|
|
||||||
content = await Promise.resolve(
|
|
||||||
contentFactory(
|
|
||||||
tileset,
|
|
||||||
tile,
|
|
||||||
tile._contentResource,
|
|
||||||
preprocessed.binaryPayload.buffer,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// JSON formats
|
|
||||||
content = await Promise.resolve(
|
|
||||||
contentFactory(
|
|
||||||
tileset,
|
|
||||||
tile,
|
|
||||||
tile._contentResource,
|
|
||||||
preprocessed.jsonPayload,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentHeader = tile._contentHeader;
|
const contentHeader = tile._contentHeader;
|
||||||
|
return finishContent(tile, resource, preprocessed, contentHeader, 0);
|
||||||
if (tile.hasImplicitContentMetadata) {
|
|
||||||
const subtree = tile.implicitSubtree;
|
|
||||||
const coordinates = tile.implicitCoordinates;
|
|
||||||
content.metadata = subtree.getContentMetadataView(coordinates, 0);
|
|
||||||
} else if (!tile.hasImplicitContent) {
|
|
||||||
content.metadata = findContentMetadata(tileset, contentHeader);
|
|
||||||
}
|
|
||||||
|
|
||||||
const groupMetadata = findGroupMetadata(tileset, contentHeader);
|
|
||||||
if (defined(groupMetadata)) {
|
|
||||||
content.group = new Cesium3DContentGroup({
|
|
||||||
metadata: groupMetadata,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1405,8 +1424,13 @@ async function makeContent(tile, arrayBuffer) {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Cesium3DTile.prototype.cancelRequests = function () {
|
Cesium3DTile.prototype.cancelRequests = function () {
|
||||||
|
// XXX_DYNAMIC: This actually happens sometimes, but only when the tile is
|
||||||
|
// in the "LOADING" state. Now... what do do with dynamic tiles?
|
||||||
|
console.log("Cesium3DTile.cancelRequests is called");
|
||||||
if (this.hasMultipleContents) {
|
if (this.hasMultipleContents) {
|
||||||
this._content.cancelRequests();
|
this._content.cancelRequests();
|
||||||
|
} else if (this._content instanceof Dynamic3DTileContent) {
|
||||||
|
this._content.cancelRequests();
|
||||||
} else {
|
} else {
|
||||||
this._request.cancel();
|
this._request.cancel();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,8 +309,8 @@ Cesium3DTileContent.prototype.getFeature = function (batchId) {
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param {boolean} enabled Whether to enable or disable debug settings.
|
* @param {boolean} enabled Whether to enable or disable debug settings.
|
||||||
* @returns {Cesium3DTileFeature} The corresponding {@link Cesium3DTileFeature} object.
|
* @param {Color|undefined} color The color to apply
|
||||||
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Cesium3DTileContent.prototype.applyDebugSettings = function (enabled, color) {
|
Cesium3DTileContent.prototype.applyDebugSettings = function (enabled, color) {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import Tileset3DTileContent from "./Tileset3DTileContent.js";
|
||||||
import Vector3DTileContent from "./Vector3DTileContent.js";
|
import Vector3DTileContent from "./Vector3DTileContent.js";
|
||||||
import GaussianSplat3DTileContent from "./GaussianSplat3DTileContent.js";
|
import GaussianSplat3DTileContent from "./GaussianSplat3DTileContent.js";
|
||||||
import RuntimeError from "../Core/RuntimeError.js";
|
import RuntimeError from "../Core/RuntimeError.js";
|
||||||
|
import Dynamic3DTileContent from "./Dynamic3DTileContent.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a tile's magic field in its header to a new content object for the tile's payload.
|
* Maps a tile's magic field in its header to a new content object for the tile's payload.
|
||||||
|
|
@ -54,6 +55,9 @@ const Cesium3DTileContentFactory = {
|
||||||
externalTileset: function (tileset, tile, resource, json) {
|
externalTileset: function (tileset, tile, resource, json) {
|
||||||
return Tileset3DTileContent.fromJson(tileset, tile, resource, json);
|
return Tileset3DTileContent.fromJson(tileset, tile, resource, json);
|
||||||
},
|
},
|
||||||
|
dynamicContents: function (tileset, tile, resource, json) {
|
||||||
|
return Dynamic3DTileContent.fromJson(tileset, tile, resource, json);
|
||||||
|
},
|
||||||
geom: function (tileset, tile, resource, arrayBuffer, byteOffset) {
|
geom: function (tileset, tile, resource, arrayBuffer, byteOffset) {
|
||||||
return new Geometry3DTileContent(
|
return new Geometry3DTileContent(
|
||||||
tileset,
|
tileset,
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,16 @@ const Cesium3DTileContentType = {
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
EXTERNAL_TILESET: "externalTileset",
|
EXTERNAL_TILESET: "externalTileset",
|
||||||
|
/**
|
||||||
|
* The content is a dynamic content, which contains an array of
|
||||||
|
* content objects with 'keys' that identify which content is
|
||||||
|
* active at a certain point in time.
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @constant
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
DYNAMIC_CONTENTS: "dynamicContents",
|
||||||
/**
|
/**
|
||||||
* Multiple contents are handled separately from the other content types
|
* Multiple contents are handled separately from the other content types
|
||||||
* due to differences in request scheduling.
|
* due to differences in request scheduling.
|
||||||
|
|
|
||||||
|
|
@ -216,10 +216,82 @@ function Cesium3DTileset(options) {
|
||||||
this._modelUpAxis = undefined;
|
this._modelUpAxis = undefined;
|
||||||
this._modelForwardAxis = undefined;
|
this._modelForwardAxis = undefined;
|
||||||
this._cache = new Cesium3DTilesetCache();
|
this._cache = new Cesium3DTilesetCache();
|
||||||
this._processingQueue = [];
|
|
||||||
this._selectedTiles = [];
|
|
||||||
this._emptyTiles = [];
|
this._emptyTiles = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tiles that are 'selected' by the traversal.
|
||||||
|
*
|
||||||
|
* During the 'Cesium3DTileset.update' call, the tile traversal is
|
||||||
|
* executed. This includes the execution of the 'selectTiles'
|
||||||
|
* function of the traversal (which exists in different forms,
|
||||||
|
* depending on the traversal - but it's not really an interface,
|
||||||
|
* just different functions).
|
||||||
|
*
|
||||||
|
* The 'selectTiles' function will first clear this list of
|
||||||
|
* selected tiles, and then fill it with the tiles that are
|
||||||
|
* 'selected'.
|
||||||
|
*
|
||||||
|
* (This usually/roughly means that they are in the view frustum
|
||||||
|
* and have the right level of detail, but the details may vary)
|
||||||
|
*
|
||||||
|
* Some of these tiles may also be moved into the '_requestedTiles'
|
||||||
|
* as part of the traversal.
|
||||||
|
*/
|
||||||
|
this._selectedTiles = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tiles that are 'requested' according to the traversal.
|
||||||
|
*
|
||||||
|
* This is usually a subset of the '_selectedTiles': The list
|
||||||
|
* of requested tiles is cleared at the beginning of the traversal,
|
||||||
|
* and then some tiles that are 'selected' will also be added to
|
||||||
|
* these 'requested' tiles.
|
||||||
|
*
|
||||||
|
* There is no clear definition of what a 'requested' tile is.
|
||||||
|
* It roughly means that ~"their content has to be loaded".
|
||||||
|
* The tiles are added to this list, usually in a function
|
||||||
|
* called 'loadTile', which is literally saying that the tile
|
||||||
|
* is added to this list "if appropriate".
|
||||||
|
*
|
||||||
|
* The important point is that AFTER the traversal, the
|
||||||
|
* contents of these tiles will be loaded, meaning that
|
||||||
|
* 'Cesium3DTile.requestContent' will be called for them,
|
||||||
|
* and they will be added to the '_requestedTilesInFlight'.
|
||||||
|
*
|
||||||
|
* (Once the content is loaded, the tiles will be added to
|
||||||
|
* the '_processingQueue');
|
||||||
|
*/
|
||||||
this._requestedTiles = [];
|
this._requestedTiles = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tiles for which a content request is currently "in flight".
|
||||||
|
*
|
||||||
|
* This list is filled with tiles from the '_requestedTiles'
|
||||||
|
* in each frame. Tiles are removed from this list after each
|
||||||
|
* frame (when 'cancelOutOfViewRequests' is called), if their
|
||||||
|
* '_contentState' is no longer 'LOADING'.
|
||||||
|
*
|
||||||
|
* So a tile being in this list roughly means that its content
|
||||||
|
* is currently being loaded.
|
||||||
|
*/
|
||||||
|
this._requestedTilesInFlight = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tiles that are currently being processed.
|
||||||
|
*
|
||||||
|
* These are the tiles that have been 'selected' and 'requested'
|
||||||
|
* and whose content was eventually obtained. Before the next
|
||||||
|
* rendering pass, these tiles will be "processed", meaning that
|
||||||
|
* their 'Cesium3DTile.process' method will be called.
|
||||||
|
*
|
||||||
|
* This mainly means that the 'Cesium3DTileContent.update' function
|
||||||
|
* of their content is called, loading data and creating WebGL
|
||||||
|
* resources and doing other random stuff, which eventually leads
|
||||||
|
* to the tile moving from the 'PROCESSING' state into the 'READY' state.
|
||||||
|
*/
|
||||||
|
this._processingQueue = [];
|
||||||
|
|
||||||
this._selectedTilesToStyle = [];
|
this._selectedTilesToStyle = [];
|
||||||
this._loadTimestamp = undefined;
|
this._loadTimestamp = undefined;
|
||||||
this._timeSinceLoad = 0.0;
|
this._timeSinceLoad = 0.0;
|
||||||
|
|
@ -276,8 +348,6 @@ function Cesium3DTileset(options) {
|
||||||
this._statisticsPerPass[i] = new Cesium3DTilesetStatistics();
|
this._statisticsPerPass[i] = new Cesium3DTilesetStatistics();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._requestedTilesInFlight = [];
|
|
||||||
|
|
||||||
this._maximumPriority = {
|
this._maximumPriority = {
|
||||||
foveatedFactor: -Number.MAX_VALUE,
|
foveatedFactor: -Number.MAX_VALUE,
|
||||||
depth: -Number.MAX_VALUE,
|
depth: -Number.MAX_VALUE,
|
||||||
|
|
@ -1077,6 +1147,17 @@ function Cesium3DTileset(options) {
|
||||||
instanceFeatureIdLabel = `instanceFeatureId_${instanceFeatureIdLabel}`;
|
instanceFeatureIdLabel = `instanceFeatureId_${instanceFeatureIdLabel}`;
|
||||||
}
|
}
|
||||||
this._instanceFeatureIdLabel = instanceFeatureIdLabel;
|
this._instanceFeatureIdLabel = instanceFeatureIdLabel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function that determines which inner contents of a dynamic
|
||||||
|
* contents object are currently active.
|
||||||
|
*
|
||||||
|
* See the setter of this property for details.
|
||||||
|
*
|
||||||
|
* @type {Function|undefined}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this._dynamicContentPropertyProvider = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperties(Cesium3DTileset.prototype, {
|
Object.defineProperties(Cesium3DTileset.prototype, {
|
||||||
|
|
@ -2103,6 +2184,34 @@ Object.defineProperties(Cesium3DTileset.prototype, {
|
||||||
this._instanceFeatureIdLabel = value;
|
this._instanceFeatureIdLabel = value;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The function that provides the properties based on which inner
|
||||||
|
* contents of a dynamic content should be active.
|
||||||
|
*
|
||||||
|
* This is a function that returns a JSON plain object. This object corresponds
|
||||||
|
* to one 'key' of a dynamic content definition. It will cause the content
|
||||||
|
* with this key to be the currently active content, namely, when the
|
||||||
|
* "update" function of that content is called.
|
||||||
|
*
|
||||||
|
* @memberof Cesium3DTileset.prototype
|
||||||
|
* @readonly
|
||||||
|
* @type {Function|undefined}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
dynamicContentPropertyProvider: {
|
||||||
|
get: function () {
|
||||||
|
return this._dynamicContentPropertyProvider;
|
||||||
|
},
|
||||||
|
set: function (value) {
|
||||||
|
if (defined(value) && !defined(this._dynamicContentsDimensions)) {
|
||||||
|
console.log(
|
||||||
|
"This tileset does not contain the 3DTILES_dynamic extension. The given function will not have an effect.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this._dynamicContentPropertyProvider = value;
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -2261,6 +2370,18 @@ Cesium3DTileset.fromUrl = async function (url, options) {
|
||||||
tileset._initialClippingPlanesOriginMatrix,
|
tileset._initialClippingPlanesOriginMatrix,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Extract the information about the "dimensions" of the dynamic contents,
|
||||||
|
// if present.
|
||||||
|
// XXX_DYNAMIC This should probably not be done here, but ...
|
||||||
|
// maybe in the constructor or so...? The lifecycle, though...
|
||||||
|
const hasDynamicContents = hasExtension(tilesetJson, "3DTILES_dynamic");
|
||||||
|
if (hasDynamicContents) {
|
||||||
|
const dynamicContentsExtension = tilesetJson.extensions["3DTILES_dynamic"];
|
||||||
|
tileset._dynamicContentsDimensions = dynamicContentsExtension.dimensions;
|
||||||
|
} else {
|
||||||
|
tileset._dynamicContentsDimensions = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
return tileset;
|
return tileset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2362,6 +2483,54 @@ Cesium3DTileset.prototype.loadTileset = function (
|
||||||
return rootTile;
|
return rootTile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XXX_DYNAMIC A draft for a convenience function for the dynamic content
|
||||||
|
* properties provider. Whether or not this should be offered depends on
|
||||||
|
* how much we want to specialize all this for single ISO8601 date strings.
|
||||||
|
* We could even omit the "timeDimensionName" if this was a fixed, specified
|
||||||
|
* string like "isoTimeStamp" or so.
|
||||||
|
*
|
||||||
|
* ---
|
||||||
|
*
|
||||||
|
* Set the function that determines which dynamic content is currently active,
|
||||||
|
* based on the ISO8601 string representation of the current time of the given
|
||||||
|
* clock.
|
||||||
|
*
|
||||||
|
* @param {string} timeDimensionName The name of the property that will
|
||||||
|
* contain the ISO8601 date string of the current time of the clock
|
||||||
|
* @param {Clock} clock The clock that provides the current time
|
||||||
|
*/
|
||||||
|
Cesium3DTileset.prototype.setDefaultTimeDynamicContentPropertyProvider =
|
||||||
|
function (timeDimensionName, clock) {
|
||||||
|
//>>includeStart('debug', pragmas.debug);
|
||||||
|
Check.typeOf.string("timeDimensionName", timeDimensionName);
|
||||||
|
Check.typeOf.object("clock", clock);
|
||||||
|
//>>includeEnd('debug');
|
||||||
|
|
||||||
|
const dimensions = this._dynamicContentsDimensions;
|
||||||
|
if (defined(dimensions)) {
|
||||||
|
const dimensionNames = dimensions.map((d) => d.name);
|
||||||
|
if (!dimensionNames.includes(timeDimensionName)) {
|
||||||
|
console.log(
|
||||||
|
`The time dimension name ${timeDimensionName} is not a valid dimension name. Valid dimension names are`,
|
||||||
|
dimensionNames,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dynamicContentPropertyProvider = () => {
|
||||||
|
const currentTime = clock.currentTime;
|
||||||
|
if (!defined(currentTime)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const currentTimeString = JulianDate.toIso8601(currentTime);
|
||||||
|
return {
|
||||||
|
[timeDimensionName]: currentTimeString,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
this.dynamicContentPropertyProvider = dynamicContentPropertyProvider;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a {@link Cesium3DTile} for a specific tile. If the tile's header has implicit
|
* Make a {@link Cesium3DTile} for a specific tile. If the tile's header has implicit
|
||||||
* tiling (3D Tiles 1.1) or uses the <code>3DTILES_implicit_tiling</code> extension,
|
* tiling (3D Tiles 1.1) or uses the <code>3DTILES_implicit_tiling</code> extension,
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -6,12 +6,9 @@ import Request from "../Core/Request.js";
|
||||||
import RequestScheduler from "../Core/RequestScheduler.js";
|
import RequestScheduler from "../Core/RequestScheduler.js";
|
||||||
import RequestState from "../Core/RequestState.js";
|
import RequestState from "../Core/RequestState.js";
|
||||||
import RequestType from "../Core/RequestType.js";
|
import RequestType from "../Core/RequestType.js";
|
||||||
import Cesium3DContentGroup from "./Cesium3DContentGroup.js";
|
|
||||||
import Cesium3DTileContentType from "./Cesium3DTileContentType.js";
|
import Cesium3DTileContentType from "./Cesium3DTileContentType.js";
|
||||||
import Cesium3DTileContentFactory from "./Cesium3DTileContentFactory.js";
|
|
||||||
import findContentMetadata from "./findContentMetadata.js";
|
|
||||||
import findGroupMetadata from "./findGroupMetadata.js";
|
|
||||||
import preprocess3DTileContent from "./preprocess3DTileContent.js";
|
import preprocess3DTileContent from "./preprocess3DTileContent.js";
|
||||||
|
import finishContent from "./finishContent.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A collection of contents for tiles that have multiple contents, either via the tile JSON (3D Tiles 1.1) or the <code>3DTILES_multiple_contents</code> extension.
|
* A collection of contents for tiles that have multiple contents, either via the tile JSON (3D Tiles 1.1) or the <code>3DTILES_multiple_contents</code> extension.
|
||||||
|
|
@ -35,7 +32,11 @@ import preprocess3DTileContent from "./preprocess3DTileContent.js";
|
||||||
function Multiple3DTileContent(tileset, tile, tilesetResource, contentsJson) {
|
function Multiple3DTileContent(tileset, tile, tilesetResource, contentsJson) {
|
||||||
this._tileset = tileset;
|
this._tileset = tileset;
|
||||||
this._tile = tile;
|
this._tile = tile;
|
||||||
this._tilesetResource = tilesetResource;
|
|
||||||
|
// XXX_DYNAMIC Was unused... ?!
|
||||||
|
// This could be avoided by writing a COMMENT!!!
|
||||||
|
//this._tilesetResource = tilesetResource;
|
||||||
|
|
||||||
this._contents = [];
|
this._contents = [];
|
||||||
this._contentsCreated = false;
|
this._contentsCreated = false;
|
||||||
|
|
||||||
|
|
@ -532,8 +533,8 @@ async function createInnerContent(multipleContents, arrayBuffer, index) {
|
||||||
try {
|
try {
|
||||||
const preprocessed = preprocess3DTileContent(arrayBuffer);
|
const preprocessed = preprocess3DTileContent(arrayBuffer);
|
||||||
|
|
||||||
const tileset = multipleContents._tileset;
|
|
||||||
const resource = multipleContents._innerContentResources[index];
|
const resource = multipleContents._innerContentResources[index];
|
||||||
|
const contentHeader = multipleContents._innerContentHeaders[index];
|
||||||
const tile = multipleContents._tile;
|
const tile = multipleContents._tile;
|
||||||
|
|
||||||
if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) {
|
if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) {
|
||||||
|
|
@ -546,42 +547,7 @@ async function createInnerContent(multipleContents, arrayBuffer, index) {
|
||||||
preprocessed.contentType === Cesium3DTileContentType.GEOMETRY ||
|
preprocessed.contentType === Cesium3DTileContentType.GEOMETRY ||
|
||||||
preprocessed.contentType === Cesium3DTileContentType.VECTOR;
|
preprocessed.contentType === Cesium3DTileContentType.VECTOR;
|
||||||
|
|
||||||
let content;
|
return finishContent(tile, resource, preprocessed, contentHeader, index);
|
||||||
const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType];
|
|
||||||
if (defined(preprocessed.binaryPayload)) {
|
|
||||||
content = await Promise.resolve(
|
|
||||||
contentFactory(
|
|
||||||
tileset,
|
|
||||||
tile,
|
|
||||||
resource,
|
|
||||||
preprocessed.binaryPayload.buffer,
|
|
||||||
0,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// JSON formats
|
|
||||||
content = await Promise.resolve(
|
|
||||||
contentFactory(tileset, tile, resource, preprocessed.jsonPayload),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const contentHeader = multipleContents._innerContentHeaders[index];
|
|
||||||
|
|
||||||
if (tile.hasImplicitContentMetadata) {
|
|
||||||
const subtree = tile.implicitSubtree;
|
|
||||||
const coordinates = tile.implicitCoordinates;
|
|
||||||
content.metadata = subtree.getContentMetadataView(coordinates, index);
|
|
||||||
} else if (!tile.hasImplicitContent) {
|
|
||||||
content.metadata = findContentMetadata(tileset, contentHeader);
|
|
||||||
}
|
|
||||||
|
|
||||||
const groupMetadata = findGroupMetadata(tileset, contentHeader);
|
|
||||||
if (defined(groupMetadata)) {
|
|
||||||
content.group = new Cesium3DContentGroup({
|
|
||||||
metadata: groupMetadata,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleInnerContentFailed(multipleContents, index, error);
|
handleInnerContentFailed(multipleContents, index, error);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
import defined from "../Core/defined.js";
|
||||||
|
import Cesium3DTileContentFactory from "./Cesium3DTileContentFactory.js";
|
||||||
|
import findContentMetadata from "./findContentMetadata.js";
|
||||||
|
import findGroupMetadata from "./findGroupMetadata.js";
|
||||||
|
import Cesium3DContentGroup from "./Cesium3DContentGroup.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize the creation of a <code>Cesium3DTileContent</code> object.
|
||||||
|
*
|
||||||
|
* This takes the information from the tile and the preprocessed content
|
||||||
|
* data that was fetched from the resource, creates the proper
|
||||||
|
* <code>Cesium3DTileContent</code> instance, and assigns the
|
||||||
|
* content- and group metadata to it.
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* @param {Cesium3DTile} tile The tile that contained the content
|
||||||
|
* @param {Resource} resource The resource
|
||||||
|
* @param {PreprocessedContent} preprocessed The return value of <code>preprocess3DTileContent</code>
|
||||||
|
* @param {object} contentHeader the JSON header for a {@link Cesium3DTileContent}
|
||||||
|
* @param {number} index The content index. This is 0 for a single content, or the index of the inner content for multiple contents.
|
||||||
|
* @return {Cesium3DTileContent} The finished <code>Cesium3DTileContent</code>
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
async function finishContent(
|
||||||
|
tile,
|
||||||
|
resource,
|
||||||
|
preprocessed,
|
||||||
|
contentHeader,
|
||||||
|
index,
|
||||||
|
) {
|
||||||
|
const tileset = tile._tileset;
|
||||||
|
const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType];
|
||||||
|
let content;
|
||||||
|
if (defined(preprocessed.binaryPayload)) {
|
||||||
|
content = await Promise.resolve(
|
||||||
|
contentFactory(
|
||||||
|
tileset,
|
||||||
|
tile,
|
||||||
|
resource,
|
||||||
|
preprocessed.binaryPayload.buffer,
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// JSON formats
|
||||||
|
content = await Promise.resolve(
|
||||||
|
contentFactory(tileset, tile, resource, preprocessed.jsonPayload),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile.hasImplicitContentMetadata) {
|
||||||
|
const subtree = tile.implicitSubtree;
|
||||||
|
const coordinates = tile.implicitCoordinates;
|
||||||
|
content.metadata = subtree.getContentMetadataView(coordinates, index);
|
||||||
|
} else if (!tile.hasImplicitContent) {
|
||||||
|
content.metadata = findContentMetadata(tileset, contentHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
const groupMetadata = findGroupMetadata(tileset, contentHeader);
|
||||||
|
if (defined(groupMetadata)) {
|
||||||
|
content.group = new Cesium3DContentGroup({
|
||||||
|
metadata: groupMetadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
export default finishContent;
|
||||||
|
|
@ -84,6 +84,15 @@ function preprocess3DTileContent(arrayBuffer) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (defined(json.dynamicContents)) {
|
||||||
|
// If this is not dynamic content, someone must have
|
||||||
|
// added that 'dynamicContents' property maliciously.
|
||||||
|
return {
|
||||||
|
contentType: Cesium3DTileContentType.DYNAMIC_CONTENTS,
|
||||||
|
jsonPayload: json,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
throw new RuntimeError("Invalid tile content.");
|
throw new RuntimeError("Invalid tile content.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue