Install
$ agentstack add skill-impertio-studio-cesiumjs-claude-skill-package-cesium-impl-aec-georef ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
CesiumJS AEC Georeferencing
Overview
BIM, CAD, and city models use a LOCAL engineering coordinate system: meters from a project origin. CesiumJS renders in ECEF (Earth-Centered Earth-Fixed) WGS84 meters. A model loaded with no transform draws near the CENTER of the Earth, invisible from any normal camera. Georeferencing is building the Matrix4 that maps the model's local frame to its real position on the globe and assigning it to modelMatrix.
Core principle: the placement math (Transforms, Matrix4, HeadingPitchRoll, modelMatrix) is official CesiumJS API. Getting CityGML or IFC INTO a loadable format is an EXTERNAL workflow with no CesiumJS API. This skill keeps the two strictly separate.
This skill is technology-specific: CesiumJS 1.124+, WebGL2 only.
When to Use This Skill
- Placing a BIM, CAD, or city model at a real-world location.
- A loaded model is invisible, or appears at the center of the Earth.
- A model sits at the wrong place, or faces the wrong direction.
- A model floats above or sinks below terrain.
- Getting an IFC or CityGML model into CesiumJS.
- Rendering CAD-style edges on a model or tileset.
Official API vs External Workflow
This separation is CRITICAL. NEVER present a file-conversion pipeline as a CesiumJS API call.
| Concern | Official CesiumJS API | External workflow (NOT API) | |---------|-----------------------|------------------------------| | Place and orient an asset | Transforms, Matrix4, HeadingPitchRoll, modelMatrix | none | | Load a glb or glTF | Model.fromGltfAsync | none | | Load tiled 3D Tiles | Cesium3DTileset.fromUrl / fromIonAssetId | none | | CityGML to 3D Tiles | none | ion tiler, FME, external tooling | | IFC to glTF | none | ThatOpen Components, IfcOpenShell |
CesiumJS has NO native CityGML loader and NO native IFC loader. Those formats MUST be converted first, outside CesiumJS.
Quick Reference: Georeferencing API
| Call | Purpose | |------|---------| | Transforms.eastNorthUpToFixedFrame(origin) | local east-north-up frame at a position, mapped to ECEF | | Transforms.headingPitchRollToFixedFrame(origin, hpr) | the same, plus a heading-pitch-roll rotation | | Transforms.localFrameToFixedFrameGenerator(a, b) | a frame function for non-ENU axis conventions | | HeadingPitchRoll.fromDegrees(h, p, r) | a rotation from degree inputs | | model.modelMatrix / tileset.modelMatrix | the Matrix4 slot the result is assigned to |
The Placement Problem and modelMatrix
modelMatrix is a Matrix4 on both Model and Cesium3DTileset, default Matrix4.IDENTITY. With the identity matrix the asset is drawn in raw ECEF WGS84 coordinates, so a CAD model built around local (0, 0, 0) lands at the Earth's core.
ALWAYS assign a modelMatrix that maps the model's local origin to a real Cartesian3 position on the globe.
Placing a Model at a Location
Transforms.eastNorthUpToFixedFrame(origin) returns the Matrix4 that maps a local east-north-up frame (local +X east, +Y north, +Z up) at origin into ECEF. Assign it to modelMatrix.
const origin = Cesium.Cartesian3.fromDegrees(4.9041, 52.3676, 12.0);
const model = await Cesium.Model.fromGltfAsync({
url: "/models/building.glb",
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(origin),
});
viewer.scene.primitives.add(model);
Orienting a Model
When the model must be rotated (a building not aligned to north, a tilted element), use Transforms.headingPitchRollToFixedFrame(origin, hpr). The HeadingPitchRoll constructor takes RADIANS; ALWAYS use HeadingPitchRoll.fromDegrees when working in degrees.
const origin = Cesium.Cartesian3.fromDegrees(4.9041, 52.3676, 12.0);
const hpr = Cesium.HeadingPitchRoll.fromDegrees(135.0, 0.0, 0.0);
const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, hpr);
const model = await Cesium.Model.fromGltfAsync({
url: "/models/building.glb",
modelMatrix,
});
viewer.scene.primitives.add(model);
heading rotates about the local up axis from north, pitch about the east axis, roll about the north axis.
Placing a Tileset
Cesium3DTileset.modelMatrix works the same way and is mutable after the tileset loads.
ALWAYS check whether the tileset is ALREADY georeferenced before assigning a modelMatrix. A tileset produced by the ion tiler from georeferenced source data carries its real-world transform in its root tile; its modelMatrix must stay Matrix4.IDENTITY. Assign a modelMatrix ONLY to a tileset whose content sits in a local CAD frame.
// Non-georeferenced tileset: place it.
const tileset = await Cesium.Cesium3DTileset.fromUrl("/tiles/plant/tileset.json");
tileset.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(4.9041, 52.3676, 0.0)
);
viewer.scene.primitives.add(tileset);
Custom Local Frames
A glTF or BIM export whose axes do not match east-north-up needs either a local correction matrix composed onto the ENU frame, or a custom frame function from Transforms.localFrameToFixedFrameGenerator(firstAxis, secondAxis), where each axis is one of east, north, up, west, south, down.
// A model authored north-west-up instead of east-north-up.
const nwuToFixed = Cesium.Transforms.localFrameToFixedFrameGenerator("north", "west");
const modelMatrix = nwuToFixed(origin);
Compose a correction with Matrix4.multiply(enuFrame, localCorrection, result).
External Workflow: CityGML and IFC
These steps run OUTSIDE CesiumJS. They produce a file CesiumJS can load; they are NOT CesiumJS API.
- CityGML: convert to 3D Tiles with the Cesium ion tiler or external tooling,
then stream the result with Cesium3DTileset.fromUrl or fromIonAssetId.
- IFC: export to glTF with ThatOpen Components or IfcOpenShell, then load the
glTF with Model.fromGltfAsync and georeference it with a modelMatrix.
The georeference step (the modelMatrix) is the only CesiumJS-side work; the conversion is external workflow.
CAD-style Edges
EdgeDisplayMode (CesiumJS 1.142+) renders the crisp edges architects expect. The edgeDisplayMode property on Model and Cesium3DTileset takes EdgeDisplayMode.SURFACES_ONLY (default), SURFACES_AND_EDGES, or EDGES_ONLY (CAD wireframe).
// Requires CesiumJS 1.142 or newer.
model.edgeDisplayMode = Cesium.EdgeDisplayMode.SURFACES_AND_EDGES;
Edges are read from the EXT_mesh_primitive_edge_visibility glTF extension, so the glTF MUST carry edge data; an exporter that omits the extension shows no edges. The extension loads since 1.135; the EdgeDisplayMode control is 1.142+.
Cross-Tech Companion Notes
Georeferencing usually sits inside a larger AEC toolchain. Each tool below has its own skill package; this skill covers only the CesiumJS step.
- QGIS: prepares and inspects the geospatial source data (survey points,
imagery, terrain) that defines where a model belongs.
- ThatOpen Components and IfcOpenShell: the IFC-to-glTF bridge feeding
Model.fromGltfAsync.
- Speckle: federates multi-discipline BIM data; export to glTF or 3D Tiles for
streaming into CesiumJS.
Common Mistakes
| Mistake | Fix | |---------|-----| | Model invisible, at the Earth's core | Assign Transforms.eastNorthUpToFixedFrame(origin) to modelMatrix | | modelMatrix set on an ion-tiled tileset | Leave it Matrix4.IDENTITY; ion assets are pre-placed | | new HeadingPitchRoll(135, 0, 0) for degrees | Use HeadingPitchRoll.fromDegrees(135, 0, 0) | | Model sunk into terrain | Set the real height in the origin Cartesian3 | | Loading a .ifc or CityGML file directly | Convert first; CesiumJS has no native loader | | EdgeDisplayMode on CesiumJS below 1.142 | Upgrade; the enum does not exist earlier |
Full root-cause analysis is in references/anti-patterns.md.
Reference Files
references/methods.md: verified signatures forTransforms,Matrix4,
HeadingPitchRoll, TranslationRotationScale, modelMatrix, and EdgeDisplayMode.
references/examples.md: runnable placement, orientation, tileset, and
custom-frame snippets.
references/anti-patterns.md: georeferencing failure modes, each with
symptom, root cause, prevention, and recovery.
Related Skills
cesium-core-coordinates:Cartesian3,Cartographic, the ellipsoid, ENU frames.cesium-syntax-gltf-model:Model.fromGltfAsyncand model loading.cesium-syntax-3d-tiles:Cesium3DTilesetloading and tile formats.cesium-impl-cesium-ion: the ion tiler that converts source data to 3D Tiles.cesium-errors-coordinates: NaN positions and off-globe geometry.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/CesiumJS-Claude-Skill-Package
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.