Skip to content

Commit

Permalink
Merge pull request #11678 from Tamrat-B/feature/i3s_bsl_support
Browse files Browse the repository at this point in the history
Add support for Building Scene Layer (BSL) OGC I3S standard
  • Loading branch information
ggetz committed Feb 28, 2024
2 parents 6db8642 + a3ea292 commit 09cc7e8
Show file tree
Hide file tree
Showing 31 changed files with 5,625 additions and 333 deletions.
12 changes: 1 addition & 11 deletions Apps/Sandcastle/gallery/I3S 3D Object Layer.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,9 @@ <h1>Loading...</h1>
const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl(
"https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer"
);
// Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing
const cesium3dTilesetOptions = {
skipLevelOfDetail: false,
debugShowBoundingVolume: false,
};
// Create i3s options to pass optional parameters useful for debugging and visualizing
const i3sOptions = {
traceFetches: false, // for tracing I3S fetches
geoidTiledTerrainProvider: geoidService, // pass the geoid service
cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset
};

// Create I3S data provider
Expand Down Expand Up @@ -114,9 +108,6 @@ <h1>Loading...</h1>
i3sNode.loadFields().then(function () {
let description = "No attributes";
let name;
console.log(
`pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}`
);

const fields = i3sNode.getFieldsForPickedPosition(
pickedPosition
Expand All @@ -128,7 +119,6 @@ <h1>Loading...</h1>
if (i3sNode.fields.hasOwnProperty(fieldName)) {
description += `<tr><th>${fieldName}</th><td>`;
description += `${fields[fieldName]}</td></tr>`;
console.log(`${fieldName}: ${fields[fieldName]}`);
if (!Cesium.defined(name) && isNameProperty(fieldName)) {
name = fields[fieldName];
}
Expand Down
216 changes: 216 additions & 0 deletions Apps/Sandcastle/gallery/I3S Building Scene Layer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
/>
<meta
name="description"
content="Add I3S Building Scene Layer from a service."
/>
<meta name="cesium-sandcastle-labels" content="DataSources" />
<title>I3S Building Scene Cesium Demo</title>
<script type="text/javascript" src="../Sandcastle-header.js"></script>
<script
type="text/javascript"
src="../../../Build/CesiumUnminified/Cesium.js"
nomodule
></script>
<script type="module" src="../load-cesium-es6.js"></script>
</head>

<body
class="sandcastle-loading"
data-sandcastle-bucket="bucket-requirejs.html"
>
<style>
@import url(../templates/bucket.css);
#toolbar {
background: rgba(42, 42, 42, 0.8);
padding: 10px;
border-radius: 4px;
max-height: 100%;
overflow-y: auto;
}
</style>
<div id="cesiumContainer" class="fullSize"></div>
<div id="loadingOverlay">
<h1>Loading...</h1>
</div>
<div id="toolbar"></div>
<script id="cesium_sandcastle_script">
window.startup = async function (Cesium) {
"use strict";
//Sandcastle_Begin
// Cesium World Terrain height system doesn't match to I3S datasets height system in some locations even with geoid conversion.
// Set ArcGIS Tiled Elevation Terrain gravity related height system to get closer results.
const viewer = new Cesium.Viewer("cesiumContainer", {
terrain: new Cesium.Terrain(
Cesium.ArcGISTiledElevationTerrainProvider.fromUrl(
"https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
)
),
animation: false,
timeline: false,
orderIndependentTranslucency: false,
msaaSamples: 4, // enables multisample antialiasing for improved visual quality
});

// More datasets to tour can be added here...
// The url passed to I3SDataProvider supports loading a single Indexed 3D Scene (I3S) layer (.<host>/SceneServer/layers/<id>) or a collection of scene layers (.<host>/SceneServer) from a SceneServer.
const tours = {
"Turanga Library":
"https://tiles.arcgis.com/tiles/cFEFS0EWrhfDeVw9/arcgis/rest/services/Turanga_Library/SceneServer",
};

try {
// Create i3s options to pass optional parameters useful for debugging and visualizing
const i3sOptions = {
adjustMaterialAlphaMode: true, // force the alpha mode to be set for transparent geometry
showFeatures: true, // creates 3D object for each feature and allows to apply attributes filter
applySymbology: true, // applies outlines based on the I3S layer renderer details
calculateNormals: true, // generates flat normals if they are missing in I3S buffers
};

// Create I3S data provider
const i3sProvider = await Cesium.I3SDataProvider.fromUrl(
tours["Turanga Library"],
i3sOptions
);

Cesium.I3SBuildingSceneLayerExplorer("toolbar", i3sProvider);

// Add the i3s layer provider as a primitive data type
viewer.scene.primitives.add(i3sProvider);

// Center camera on I3S once it's loaded
const center = Cesium.Rectangle.center(i3sProvider.extent);
center.height = 300.0;
// Adjust camera height by the I3S BSL extent
let bslLayer = i3sProvider.data;
if (Cesium.defined(bslLayer.layers) && bslLayer.layers.length > 0) {
bslLayer = bslLayer.layers[0];
}
if (
Cesium.defined(bslLayer.fullExtent) &&
Cesium.defined(bslLayer.fullExtent.zmax)
) {
center.height += bslLayer.fullExtent.zmax;
}
const destination = Cesium.Ellipsoid.WGS84.cartographicToCartesian(
center
);
viewer.camera.setView({
destination: destination,
});

// Override home button to center the camera on I3S
viewer.homeButton.viewModel._command = Cesium.createCommand(
function () {
viewer.camera.flyTo({
destination: destination,
});
}
);
} catch (error) {
console.error(
`There was an error creating the I3S Data Provider: ${error}`
);
}

// Information about the currently selected feature
const selected = {
feature: undefined,
originalColor: new Cesium.Color(),
};

// An entity object which will hold info about the currently selected feature for infobox display
const selectedEntity = new Cesium.Entity();
// Show metadata in the InfoBox.
viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(
movement
) {
const selectedFeature = selected.feature;

// Pick a new feature
const pickedFeature = viewer.scene.pick(movement.position);
if (selectedFeature === pickedFeature) {
return;
}

// If a feature was previously selected, undo the highlight
if (Cesium.defined(selected.feature)) {
selected.feature.color = selected.originalColor;
selected.feature = undefined;
}

if (
!Cesium.defined(pickedFeature) ||
!Cesium.defined(pickedFeature.content) ||
!Cesium.defined(pickedFeature.content.tile.i3sNode)
) {
viewer.selectedEntity = undefined;
return;
}

// Highlight newly selected feature
selected.feature = pickedFeature;
Cesium.Color.clone(pickedFeature.color, selected.originalColor);
pickedFeature.color = Cesium.Color.BLUE;

const i3sNode = pickedFeature.content.tile.i3sNode;
i3sNode.loadFields().then(function () {
let description = "No attributes";
let name;

const fields = i3sNode.getFieldsForFeature(pickedFeature.featureId);
if (Object.keys(fields).length > 0) {
description =
'<table class="cesium-infoBox-defaultTable"><tbody>';
for (const fieldName in fields) {
if (i3sNode.fields.hasOwnProperty(fieldName)) {
description += `<tr><th>${fieldName}</th><td>`;
description += `${fields[fieldName]}</td></tr>`;
if (!Cesium.defined(name) && isNameProperty(fieldName)) {
name = fields[fieldName];
}
}
}
description += `</tbody></table>`;
}
if (!Cesium.defined(name)) {
name = "unknown";
}
selectedEntity.name = name;
selectedEntity.description = description;
viewer.selectedEntity = selectedEntity;
});
},
Cesium.ScreenSpaceEventType.LEFT_CLICK);

function isNameProperty(propertyName) {
const name = propertyName.toLowerCase();
if (
name.localeCompare("name") === 0 ||
name.localeCompare("objname") === 0 ||
name.localeCompare("category") === 0
) {
return true;
}
return false;
} //Sandcastle_End
};
if (typeof Cesium !== "undefined") {
window.startupCalled = true;
window.startup(Cesium).catch((error) => {
"use strict";
console.error(error);
});
Sandcastle.finishedLoading();
}
</script>
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 1 addition & 11 deletions Apps/Sandcastle/gallery/I3S Feature Picking.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,9 @@ <h1>Loading...</h1>
const geoidService = await Cesium.ArcGISTiledElevationTerrainProvider.fromUrl(
"https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer"
);
// Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing
const cesium3dTilesetOptions = {
skipLevelOfDetail: false,
debugShowBoundingVolume: false,
};
// Create i3s options to pass optional parameters useful for debugging and visualizing
const i3sOptions = {
traceFetches: false, // for tracing I3S fetches
geoidTiledTerrainProvider: geoidService, // pass the geoid service
cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset
};

// Create I3S data provider
Expand Down Expand Up @@ -114,9 +108,6 @@ <h1>Loading...</h1>
i3sNode.loadFields().then(function () {
let description = "No attributes";
let name;
console.log(
`pickedPosition(x,y,z) : ${pickedPosition.x}, ${pickedPosition.y}, ${pickedPosition.z}`
);

const fields = i3sNode.getFieldsForPickedPosition(
pickedPosition
Expand All @@ -128,7 +119,6 @@ <h1>Loading...</h1>
if (i3sNode.fields.hasOwnProperty(fieldName)) {
description += `<tr><th>${fieldName}</th><td>`;
description += `${fields[fieldName]}</td></tr>`;
console.log(`${fieldName}: ${fields[fieldName]}`);
if (!Cesium.defined(name) && isNameProperty(fieldName)) {
name = fields[fieldName];
}
Expand Down
8 changes: 1 addition & 7 deletions Apps/Sandcastle/gallery/I3S IntegratedMesh Layer.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,9 @@ <h1>Loading...</h1>
"https://tiles.arcgis.com/tiles/z2tnIkrLQ2BRzr6P/arcgis/rest/services/EGM2008/ImageServer"
);

// Create i3s and Cesium3DTileset options to pass optional parameters useful for debugging and visualizing
const cesium3dTilesetOptions = {
skipLevelOfDetail: false,
debugShowBoundingVolume: false,
};
// Create i3s options to pass optional parameters useful for debugging and visualizing
const i3sOptions = {
traceFetches: false, // for tracing I3S fetches
geoidTiledTerrainProvider: geoidService, // pass the geoid service
cesium3dTilesetOptions: cesium3dTilesetOptions, // options for internal Cesium3dTileset
};

// Create I3S data provider
Expand Down
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@
##### Additions :tada:

- Added `Scene.pickVoxel` to pick individual cells from a `VoxelPrimitive`, and `VoxelCell` to report information about the picked cell. [#11828](https://github.com/CesiumGS/cesium/pull/11828)
- Added support for I3S Building Scene Layer. [#11678](https://github.com/CesiumGS/cesium/pull/11678)

##### Deprecated :hourglass_flowing_sand:

- `Cesium3DTileset.disableCollision` has been deprecated and will be removed in 1.116. Use `Cesium3DTileset.enableCollision` instead.

#### @cesium/engine

##### Additions :tada:

- Added `I3SBuildingSceneLayerExplorer` widget for working with I3S Building Scene Layer data. [#11678](https://github.com/CesiumGS/cesium/pull/11678)

### 1.114 - 2024-02-01

#### @cesium/engine
Expand Down
32 changes: 32 additions & 0 deletions packages/engine/Source/Core/srgbToLinear.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Check from "./Check.js";

/**
* Converts the value from sRGB color space to linear color space.
*
* @function
*
* @param {number} value The color value in sRGB color space.
* @returns {number} Returns the color value in linear color space.
*
* @example
* const srgbColor = [0.5, 0.5, 0.5];
* const linearColor = srgbColor.map(function (c) {
* return Cesium.srgbToLinear(c);
* });
*/
function srgbToLinear(value) {
//>>includeStart('debug', pragmas.debug);
Check.defined("value", value);
//>>includeEnd('debug');

if (value <= 0.04045) {
// eslint-disable-next-line no-loss-of-precision
return value * 0.07739938080495356037151702786378;
}
return Math.pow(
// eslint-disable-next-line no-loss-of-precision
(value + 0.055) * 0.94786729857819905213270142180095,
2.4
);
}
export default srgbToLinear;
Loading

0 comments on commit 09cc7e8

Please sign in to comment.