@bimangle/cesium-scene-tree
v2.0.0
Published
A Cesium plugin providing a scene tree panel for BimAngle-exported 3D Tiles datasets.
Maintainers
Readme
cesium-scene-tree
A CesiumJS plugin that provides an interactive scene tree panel for BimAngle-exported 3D Tiles datasets.
基于 CesiumJS 的场景树扩展插件,用于在 Cesium Viewer 中加载和管理 BimAngle 导出的 3D Tiles 数据集时提供可交互的场景树面板。
Features / 特性
- 🔍 Auto-detect BimAngle 3D Tiles datasets via
asset.extras.engine.info
自动识别 BimAngle 3D Tiles 数据集 - 🌲 Floating scene tree panel — collapsible, draggable, resizable
悬浮场景树面板 — 可折叠、可拖拽、可调整大小 - ⚡ Virtual scrolling — DOM rows capped at ~50, supports datasets with tens of thousands of nodes
虚拟滚动 — DOM 行上限约 50,支持数万节点的大型数据集 - 🔀 Multi-dataset switching — dropdown selector manages multiple simultaneous tilesets
多数据集切换 — 下拉选择器管理多个同时加载的 tileset - 👁 Node visibility toggle — checkbox cascades to all descendants
节点显示/隐藏 — 勾选框级联控制子孙节点 - 📍 Zoom to node — double-click flies the camera to the node's bounding sphere
缩放定位 — 双击飞行至节点包围盒(兼容 ECEF 和 ENU 坐标模式) - 🔗 Bidirectional sync with
cesium-info-accessor— click a tree node to show properties; pick a feature in the viewport to highlight the tree node
与cesium-info-accessor双向联动 — 点击树节点显示属性;在 Cesium 画面点选构件后场景树自动高亮对应节点 - 🌐 Bilingual UI — automatically uses Simplified Chinese or English based on
navigator.language
双语界面 — 根据navigator.language自动切换简体中文或英文 - 🚫 Zero runtime dependencies — only peer-depends on Cesium
零运行时依赖 — 仅依赖 Cesium
Installation / 安装
NPM
npm install @bimangle/cesium-scene-treeCDN
<!-- Cesium must be loaded first / 必须先加载 Cesium -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<!-- Then include cesium-scene-tree -->
<script src="https://unpkg.com/@bimangle/cesium-scene-tree/dist/cesium-scene-tree.js"></script>Quick Start / 快速开始
Browser (CDN)
<!DOCTYPE html>
<html>
<head>
<script src="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.120/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<script src="https://unpkg.com/@bimangle/cesium-info-accessor/dist/cesium-info-accessor.js"></script>
<script src="https://unpkg.com/@bimangle/cesium-scene-tree/dist/cesium-scene-tree.js"></script>
<style>
html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script type="module">
const viewer = new Cesium.Viewer('cesiumContainer');
// Step 1: Load cesium-info-accessor FIRST.
// SceneTreeMixin will auto-detect viewer.infoAccessor at init time
// and subscribe to its selectionChanged event — no extra wiring needed.
viewer.extend(InfoAccessorMixin, { autoAttach: true });
// Step 2: Load the scene tree plugin.
// onNodeSelect is optional; bidirectional sync with infoAccessor is automatic.
viewer.extend(CesiumSceneTree.SceneTreeMixin, {
onNodeSelect: (tileset, dbId, name) => {
console.log('Node selected:', name, 'dbId:', dbId);
}
});
// Step 3: Add a BimAngle 3D Tiles dataset — auto-detected by both plugins.
const tileset = await Cesium.Cesium3DTileset.fromUrl('./tileset.json');
viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset);
</script>
</body>
</html>NPM / ES Modules
import * as Cesium from 'cesium';
import { SceneTreeMixin } from '@bimangle/cesium-scene-tree';
const viewer = new Cesium.Viewer('cesiumContainer');
viewer.extend(SceneTreeMixin, {
onNodeSelect: (tileset, dbId, name) => {
console.log('Selected:', name, dbId);
},
// showInfoNodes: true // show nodes that have no geometry (property-only nodes)
});API Reference
SceneTreeMixin(viewer, options?)
Mixin function to be called via viewer.extend(SceneTreeMixin, options).
After calling, viewer.sceneTree exposes the SceneTree instance.
Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| onNodeSelect | function | — | Callback fired when a tree node is clicked: (tileset, dbId, name) => void |
| showInfoNodes | boolean | false | Show nodes whose boundingBoxes[dbId] is null (pure property/info nodes with no geometry) |
viewer.sceneTree — SceneTree
Methods
destroy() → void
Destroy the plugin: removes the DOM panel, unregisters all event listeners, and clears internal state.
viewer.sceneTree.destroy();Behavior Details
Auto-detection
A tileset is recognized as a BimAngle dataset when:
tileset.asset.extras.engine.info === trueinfo/index.jsonis present under the tileset root directory
Reverse Sync (Cesium → Scene Tree)
When a component is picked in the Cesium viewport via cesium-info-accessor:
- If the scene tree panel is collapsed → the sync event is ignored entirely (no panel auto-expansion).
- If the picked component belongs to a different dataset → the plugin switches datasets first and shows a status message ("Switching dataset..." / "正在切换数据集...") with a 60-second timeout.
- Once the target dataset is ready, the tree expands the path to the node, scrolls it into view, and highlights it.
Visibility Toggle
Checking/unchecking a node's checkbox cascades the visibility change to all descendant nodes. The actual feature.show property on each Cesium3DTileFeature is updated as tiles load/unload.
Zoom to Node
Double-clicking a tree node flies the camera to the node's bounding sphere. The bounding box stored in index.json is automatically transformed to ECEF using tileset.root.computedTransform, so both ECEF and ENU export modes are handled correctly.
Bounding Box Coordinate System
db.boundingBoxes[dbId] coordinates depend on the export mode chosen at BimAngle export time:
- ECEF mode: coordinates are world-space ECEF (metres)
- ENU local mode: coordinates are model-local; the plugin applies
tileset.root.computedTransformautomatically
No extra configuration is needed — the plugin handles both cases transparently.
Info Nodes
When db.boundingBoxes[dbId] === null, the node is an info node:
- It and all its descendants have no 3D geometry
- Hidden by default; enable with
showInfoNodes: true - Displayed with a distinct icon (◈) when visible
Integration with cesium-info-accessor
cesium-scene-tree is designed to work alongside cesium-info-accessor v2.0+.
No extra wiring is required — the scene tree subscribes to infoAccessor.selectionChanged automatically when both plugins are mounted on the same viewer.
// Mount both plugins — order matters: info-accessor first
viewer.extend(InfoAccessorMixin, { autoAttach: true });
viewer.extend(SceneTreeMixin, { showInfoNodes: false });
// Bidirectional sync works out of the box:
// • Click tree node → property panel opens
// • Pick in viewport → tree node highlighted (panel must be expanded)Dataset Requirements / 数据集要求
The loaded 3D Tiles must include a valid info/index.json file in BimAngle format:
<tileset root>/
├── tileset.json ← must have asset.extras.engine.info = true
├── info/
│ ├── index.json ← scene tree descriptor
│ └── 0.json, 1.json … ← property chunk files
└── 0/
└── … ← tile geometryindex.json schema (v1.4):
{
"version": "1.4",
"schema": "3D Tiles",
"db": {
"rootDbId": 1,
"parentIds": [-1, -1, 1, 1, 3],
"names": [null, "Project", "SubSet", "LayerA", "Column-1"],
"types": [-1, 5, 4, 2, 0],
"boundingBoxes": [null, [x1,y1,z1,x2,y2,z2], null, "..."]
}
}| db.types value | Meaning |
|-----------------|---------|
| 5 | Model (root) |
| 4 | Composite / assembly |
| 3 | Collection |
| 2 | Layer |
| 1 / 0 | Leaf component (has geometry) |
Compatibility / 兼容性
- Cesium ≥ 1.110.0
- Chrome 90+, Firefox 88+, Edge 90+
CSS Class Reference / CSS 命名规范
All CSS classes use the ba-cst- prefix (ba = BimAngle, cst = cesium-scene-tree).
所有 CSS 类名采用 ba-cst- 前缀(ba = BimAngle,cst = cesium-scene-tree)。
⚠️ v2.0.0 Breaking Change: All class names were renamed from the
cst-prefix toba-cst-. If your project overrides anycst-*styles with external CSS, those rules must be updated.
v2.0.0 破坏性变更:所有类名由cst-前缀统一更名为ba-cst-。如有外部 CSS 引用cst-*类名,需同步更新。
| Class / 类名 | Purpose / 用途 |
|-------------|---------------|
| .ba-cst-panel | Scene tree floating panel / 场景树浮动面板 |
| .ba-cst-panel--hidden | Panel hidden state / 面板隐藏态 |
| .ba-cst-panel-header | Panel title bar (draggable) / 面板标题栏(可拖拽) |
| .ba-cst-panel-title | Title text / 标题文字 |
| .ba-cst-panel-close | Panel close button / 面板关闭按钮 |
| .ba-cst-panel-toolbar | Panel toolbar area (dataset selector) / 面板工具栏(数据集选择器) |
| .ba-cst-dataset-select | Dataset dropdown selector / 数据集下拉选择框 |
| .ba-cst-panel-body | Panel content area / 面板内容区 |
| .ba-cst-status-msg | Status message (loading, empty, etc.) / 状态提示(加载中、无数据等) |
| .ba-cst-error-msg | Error message / 错误提示 |
| .ba-cst-retry-btn | Retry button / 重试按钮 |
| .ba-cst-resize-handle | Resize drag handle (bottom-right) / 调整大小句柄(右下角) |
| .ba-cst-scroller | Virtual-scroll container / 虚拟滚动容器 |
| .ba-cst-row-container | Absolute-positioned row wrapper / 绝对定位行容器 |
| .ba-cst-row | Single tree row / 单条树行 |
| .ba-cst-row--selected | Selected row state / 选中行 |
| .ba-cst-row--info | Info node row (dimmed) / Info 节点行(半透明) |
| .ba-cst-indent | Indentation spacer / 缩进占位 |
| .ba-cst-expand-icon | Expand/collapse icon / 展开收起图标 |
| .ba-cst-expand-icon--leaf | Leaf node icon (invisible) / 叶节点图标(不可见) |
| .ba-cst-checkbox | Visibility checkbox / 可见性复选框 |
| .ba-cst-node-icon | Node type icon / 节点类型图标 |
| .ba-cst-node-name | Node name label / 节点名称 |
| .ba-cst-node-name--info | Info node name style / Info 节点名称样式 |
| .ba-cst-zoom-btn | Zoom-to-node button (hover visible) / 缩放定位按钮(悬停显示) |
| .ba-cst-zoom-btn--disabled | Disabled zoom button / 禁用的缩放按钮 |
Build / 构建
npm install
npm run build
# Output: dist/cesium-scene-tree.jsChangelog
v1.0.0
- Initial release
- Virtual-scrolling scene tree panel with drag/resize support
- Multi-dataset dropdown switching
- Node visibility toggle (cascading)
- Double-click zoom to node bounding sphere (ECEF + ENU)
- Bidirectional sync with
cesium-info-accessorv2.0+ viaselectionChangedevent - Panel-collapsed reverse-sync ignore rule
- Dataset switching with 60-second timeout and status message
- Bilingual UI (Simplified Chinese / English)
License
MIT © BimAngle
