Skip to content

I3S Support#1371

Draft
calebbuffa wants to merge 12 commits into
CesiumGS:mainfrom
calebbuffa:i3s
Draft

I3S Support#1371
calebbuffa wants to merge 12 commits into
CesiumGS:mainfrom
calebbuffa:i3s

Conversation

@calebbuffa
Copy link
Copy Markdown
Contributor

@calebbuffa calebbuffa commented May 19, 2026

Description

Adds initial I3S (Indexed 3D Scene Layer) support to cesium-native, enabling scene services published by Esri ArcGIS (both hosted and on-premises) to be streamed using the same Tileset API as 3D Tiles.

What was added

Four new libraries, all gated behind -DCESIUM_ENABLE_I3S=ON (off by default, no impact to existing builds):

CesiumI3S — Strongly-typed C++ data model for the full I3S spec. Covers CMN (3DObject, IntegratedMesh), PSL (Point), PCSL (PointCloud), and BLD (Building) layer types, including node pages, geometry definitions, PBR materials, spatial references, and drawing info.

CesiumI3SReader — JSON deserialization layer for I3S documents (SceneLayerReader, NodePageReader, NodeIndexDocumentReader). Built on CesiumJsonReader with JSON handler classes and a template-based enum deserializer.

CesiumI3SContent — I3S-to-glTF geometry conversion pipeline. Supports legacy (< 1.7) and modern (≥ 1.7) geometry schemas, raw binary and Draco-compressed buffers, optional EGM96 geoid correction, UV region atlas cropping, and per-feature metadata via EXT_mesh_features / EXT_structural_metadata.

CesiumI3SSelectionTilesetContentLoader implementation (I3STilesetLoader, I3STilesetLoaderFactory) that drives Cesium's tile selection loop for I3S services. Includes IResourceLocator, HttpResourceLocator (live ArcGIS services), and SlpkResourceLocator (local SLPK ZIP archives). Key behaviours:

  • Fetches node pages on demand and pre-fetches child pages as a side-effect of loadTileContent to avoid blocking createTileChildren.
  • Converts lodThreshold to Cesium geometricError per metric type (MaxScreenThreshold, MaxScreenThresholdSQ, DistanceRangeFromDefaultCamera).
  • Uses setUnconditionallyRefine() on mesh-less organisational nodes so the tree is always traversed through them.
  • Participates in Cesium's memory-budget system via onTileContentUnloaded (new virtual hook on TilesetContentLoader): a ref-counted, shared_ptr-based cache evicts parsed NodePage objects when all tiles derived from a page are unloaded.

Changes to existing code

  • TilesetContentLoader: added virtual void onTileContentUnloaded(const Tile&) noexcept {} as an opt-in hook for loaders that maintain auxiliary in-memory data keyed on tiles.
  • TilesetContentManager::notifyTileUnloading: calls onTileContentUnloaded so the above hook fires at the single exit point for all tile unloads.
  • CI: added -DCESIUM_ENABLE_I3S=ON to all build/test steps and -E "[live]" to ctest to exclude network-dependent tests from automated runs.

Issue number or link

#1341

Author checklist

  • I have submitted a Contributor License Agreement (only needed once).
  • I have done a full self-review of my code.
  • I have updated CHANGES.md with a short summary of my change (for user-facing changes).
  • I have added or updated unit tests to ensure consistent code coverage as necessary.
  • I have updated the documentation as necessary.

Remaining Tasks

  • LEPCC-compressed geometry - Point-cloud layers use LEPCC encoding (cesiumjs lib handles this). LEPCC is verylightwight - but it does add an extra dependency. It is not included in this PR - but is required for point cloud support. Need to consider how to gracefully handle is users provide a Point Cloud Scene Layer gracefully, or if maintainers would like this fully supported and are ok with the extra dependency.
  • LOD Selection Metrics - I3S uses multiple error metrics, SrcreenSpaceRelative, EffectiveDensity, DensityThreshold which do not have a clean mapping to Cesium's geometricError. Currently these log an error and return 0.0 (treat as leaf). Metrics that do map well follow the already implemented pattern in cesiumjs. Decide how to handle unsupported metrics gracefully.
  • Non-WGS84 CRS - I3S supports any horizotal/vertical CRS. without the proj lib, this PR only supports 4326 horizontal CRS. Any other returns a conversion error.
  • Legacy Geometry Format (I3S < 1.7) - Legacy geometry encoding is supported in the Gltf conversion / spec - but is not included in the loading.
  • SLPK loading requires a caller-supplied SLPK-aware IAssetAccessor; none is included yet.

Testing plan

Unit tests in CesiumI3SContent/test/ cover: unsupported CRS, legacy binary geometry, Draco-compressed geometry, UV region atlas cropping, modern binary geometry (position-only, normals, face ranges), truncated buffer error paths, and EXT_mesh_features generation.

A live integration test in CesiumI3SSelection/test/TestI3STilesetLoader.cpp loads the public San Francisco Buildings ArcGIS Online service (no authentication required), drives a single-frame tile update from a camera positioned 500 m above the dataset centre, and asserts that at least one tile with non-empty glTF meshes is in the render list. This test is tagged [live] and excluded from CI via ctest -E "[live]".

To run locally:

cmake --preset=vcpkg-windows -DCESIUM_ENABLE_I3S=ON
cmake --build build
cesium-native-tests.exe "--test-case=I3S HTTP*"

Reviewer checklist

Thank you for taking the time to review this PR. By approving a PR you are taking as much responsibility for these changes as the author.

As you review, please go through the checklist below:

  • Review and run all parts of the test plan on this branch and verify it matches expectations.
    • If the issue is a bug please make sure you can reproduce the bug in the main branch and then checkout this branch to make sure it actually solved the issue.
  • Review the code and make sure you do not have any remaining questions or concerns. You should understand the code change and the chosen approach. If you are not confident or have doubts about the code, please do not hesitate to ask questions.
  • Review the unit tests and make sure there are no missing tests or edge cases.
  • Review documentation changes and updates to CHANGES.md to make sure they accurately cover the work in this PR.
  • Verify that the Contributor License Agreement has been submitted, if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant