Skip to content
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

Allow external tilesets in multiple contents #12440

Merged
merged 8 commits into from
Jan 31, 2025
Merged
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Fixed type error when setting `Viewer.selectedEntity` [#12303](https://github.com/CesiumGS/cesium/issues/12303)
- Fixed urls with https in the documentation `basemap.nationalmap.gov` [#12375](https://github.com/CesiumGS/cesium/issues/12375)
- Fixed error in polyline when sinAngle is < 1. the value of expandWidth was too much. [#12434](https://github.com/CesiumGS/cesium/pull/12434)
- Allow external tilesets in multiple contents. [#12440](https://github.com/CesiumGS/cesium/pull/12440)

## 1.125 - 2025-01-02

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# ExternalInMultipleContents

A tileset that was created as a regression test for
https://github.com/CesiumGS/cesium/issues/11960

It contains a single root node with 4 contents:

- The first one is a GLB of a red unit cube
- The remaining three are external tilesets, containing
a green, blue, and white unit cube, respectively
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"asset" : {
"version" : "1.1"
},
"geometricError" : 4096.0,
"root" : {
"boundingVolume" : {
"box" : [ 0.5, -0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ]
},
"geometricError" : 2048.0,
"refine" : "ADD",
"transform" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0 ],
"content" : {
"uri" : "contentB.glb"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"asset" : {
"version" : "1.1"
},
"geometricError" : 4096.0,
"root" : {
"boundingVolume" : {
"box" : [ 0.5, -0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ]
},
"geometricError" : 2048.0,
"refine" : "ADD",
"transform" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0 ],
"content" : {
"uri" : "contentC.glb"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"asset" : {
"version" : "1.1"
},
"geometricError" : 4096.0,
"root" : {
"boundingVolume" : {
"box" : [ 0.5, -0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ]
},
"geometricError" : 2048.0,
"refine" : "ADD",
"transform" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0 ],
"content" : {
"uri" : "contentD.glb"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"asset": {
"version": "1.1"
},
"geometricError": 4096,
"root": {
"boundingVolume": {
"box": [
1,
0,
0.5,
1,
0,
0,
0,
1,
0,
0,
0,
0.5
]
},
"refine": "ADD",
"geometricError": 4096,
"contents": [
{
"uri": "contentA.glb"
},
{
"uri": "externalB.json"
},
{
"uri": "externalC.json"
},
{
"uri": "externalD.json"
}
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# OnlyExternalInMultipleContents

A tileset that was created as a regression test for
https://github.com/CesiumGS/cesium/issues/11960

It contains a single root node with 4 contents that
are all external tilesets, each containing a GLB of
red, green, blue, and white unit cube, respectively
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"asset" : {
"version" : "1.1"
},
"geometricError" : 4096.0,
"root" : {
"boundingVolume" : {
"box" : [ 0.5, -0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ]
},
"geometricError" : 2048.0,
"refine" : "ADD",
"transform" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
"content" : {
"uri" : "contentA.glb"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"asset" : {
"version" : "1.1"
},
"geometricError" : 4096.0,
"root" : {
"boundingVolume" : {
"box" : [ 0.5, -0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ]
},
"geometricError" : 2048.0,
"refine" : "ADD",
"transform" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0 ],
"content" : {
"uri" : "contentB.glb"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"asset" : {
"version" : "1.1"
},
"geometricError" : 4096.0,
"root" : {
"boundingVolume" : {
"box" : [ 0.5, -0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ]
},
"geometricError" : 2048.0,
"refine" : "ADD",
"transform" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0 ],
"content" : {
"uri" : "contentC.glb"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"asset" : {
"version" : "1.1"
},
"geometricError" : 4096.0,
"root" : {
"boundingVolume" : {
"box" : [ 0.5, -0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5 ]
},
"geometricError" : 2048.0,
"refine" : "ADD",
"transform" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0 ],
"content" : {
"uri" : "contentD.glb"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"asset": {
"version": "1.1"
},
"geometricError": 4096,
"root": {
"boundingVolume": {
"box": [
1,
0,
0.5,
1,
0,
0,
0,
1,
0,
0,
0,
0.5
]
},
"refine": "ADD",
"geometricError": 4096,
"contents": [
{
"uri": "externalA.json"
},
{
"uri": "externalB.json"
},
{
"uri": "externalC.json"
},
{
"uri": "externalD.json"
}
]
}
}
41 changes: 20 additions & 21 deletions packages/engine/Source/Scene/Cesium3DTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,24 @@ function Cesium3DTile(tileset, baseResource, header, parent) {
*/
this.hasImplicitContent = false;

/**
* Determines whether the tile has renderable content.
*
* The loading starts with the assumption that the tile does have
* renderable content, if the content is not empty.<br>
* <br>
* This turns <code>false</code> only when the tile content is loaded
* and turns out to be a single content that points to an external
* tileset or implicit content
* </p>
*
* @type {boolean}
* @readonly
*
* @private
*/
this.hasRenderableContent = !hasEmptyContent;

/**
* When <code>true</code>, the tile contains content metadata from implicit tiling. This flag is set
* for tiles transcoded by <code>Implicit3DTileContent</code>.
Expand Down Expand Up @@ -653,27 +671,6 @@ Object.defineProperties(Cesium3DTile.prototype, {
},
},

/**
* Determines if the tile's content is renderable. <code>false</code> if the
* tile has empty content or if it points to an external tileset or implicit content
*
* @memberof Cesium3DTile.prototype
*
* @type {boolean}
* @readonly
*
* @private
*/
hasRenderableContent: {
get: function () {
return (
!this.hasEmptyContent &&
!this.hasTilesetContent &&
!this.hasImplicitContent
);
},
},

/**
* Determines if the tile has available content to render. <code>true</code> if the tile's
* content is ready or if it has expired content that renders while new content loads; otherwise,
Expand Down Expand Up @@ -1346,10 +1343,12 @@ async function makeContent(tile, arrayBuffer) {
preprocessed.contentType === Cesium3DTileContentType.IMPLICIT_SUBTREE_JSON
) {
tile.hasImplicitContent = true;
tile.hasRenderableContent = false;
}

if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) {
tile.hasTilesetContent = true;
tile.hasRenderableContent = false;
}

let content;
Expand Down
29 changes: 21 additions & 8 deletions packages/engine/Source/Scene/Multiple3DTileContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Request from "../Core/Request.js";
import RequestScheduler from "../Core/RequestScheduler.js";
import RequestState from "../Core/RequestState.js";
import RequestType from "../Core/RequestType.js";
import RuntimeError from "../Core/RuntimeError.js";
import Cesium3DContentGroup from "./Cesium3DContentGroup.js";
import Cesium3DTileContentType from "./Cesium3DTileContentType.js";
import Cesium3DTileContentFactory from "./Cesium3DTileContentFactory.js";
Expand Down Expand Up @@ -52,6 +51,11 @@ function Multiple3DTileContent(tileset, tile, tilesetResource, contentsJson) {
// used to help short-circuit computations after a tile was canceled.
this._cancelCount = 0;

// The number of contents that turned out to be external tilesets
// in createInnerContent. When all contents are external tilesets,
// then tile.hasRenderableContent will become `false`
this._externalTilesetCount = 0;

const contentCount = this._innerContentHeaders.length;
this._arrayFetchPromises = new Array(contentCount);
this._requests = new Array(contentCount);
Expand Down Expand Up @@ -505,6 +509,16 @@ async function createInnerContents(multipleContents) {
const contents = await Promise.all(promises);
multipleContents._contentsCreated = true;
multipleContents._contents = contents.filter(defined);

// If each content is an external tileset, then the tile
// itself does not have any renderable content
if (
multipleContents._externalTilesetCount === multipleContents._contents.length
) {
const tile = multipleContents._tile;
tile.hasRenderableContent = false;
}

return contents;
}

Expand All @@ -518,21 +532,20 @@ async function createInnerContent(multipleContents, arrayBuffer, index) {
try {
const preprocessed = preprocess3DTileContent(arrayBuffer);

const tileset = multipleContents._tileset;
const resource = multipleContents._innerContentResources[index];
const tile = multipleContents._tile;

if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) {
throw new RuntimeError(
"External tilesets are disallowed inside multiple contents",
);
multipleContents._externalTilesetCount++;
tile.hasTilesetContent = true;
}

multipleContents._disableSkipLevelOfDetail =
multipleContents._disableSkipLevelOfDetail ||
preprocessed.contentType === Cesium3DTileContentType.GEOMETRY ||
preprocessed.contentType === Cesium3DTileContentType.VECTOR;

const tileset = multipleContents._tileset;
const resource = multipleContents._innerContentResources[index];
const tile = multipleContents._tile;

let content;
const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType];
if (defined(preprocessed.binaryPayload)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/engine/Specs/Scene/Cesium3DTilesetHeatmapSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ describe("Scene/Cesium3DTilesetHeatmap", function () {
undefined,
);
tile._contentState = Cesium3DTileContentState.READY;
tile.hasEmptyContent = false;
tile.hasRenderableContent = true; // Mock the tile having content
const frameState = scene.frameState;
tile._selectedFrame = frameState.frameNumber;
const originalColor = tile._debugColor;
Expand Down
Loading
Loading