Import models
Show glTF, FBX, OBJ, STL, PLY, Collada, 3DS, 3MF and USDZ files as Scene Objects, placed, scaled, turned and replaced.
A Scene Object can be drawn by a model file. Its geometry names the file by uri, and the
scene gives it a place, a heading and a scale like any other object. The three.js renderer
reads ten formats with the loaders three.js ships, and loads each loader only when a scene
first uses that format, so a page of glTF never downloads the FBX reader.
import { createScene, MODEL_FORMATS, modelFormatOf } from "@klorad/api/world";
import { createThreeRenderer } from "@klorad/engine-three";
const scene = createScene({ coordinateSystem: { origin: { lat: 40.62, lon: 22.95 } } });
// The extension of the address says the format; `format` says it when the address has none.
scene.add({ id: "pump", name: "Pump P1", position: { east: 0, north: 0 }, scale: 0.001, geometry: { kind: "model", uri: "/models/pump.stl" } });
scene.add({ id: "tank", name: "Tank T1", position: { east: 7, north: 5 }, orientation: { heading: 90 }, geometry: { kind: "model", uri: "/files/4f2a", format: "fbx" } });
// One named node of a file, standing at its own origin: one element of a building as its own object.
scene.add({ id: "wall-1", name: "Wall", position: { east: -10, north: 0 }, geometry: { kind: "model", uri: "asset:9c1e", format: "glb", part: "2O2Fr$t4X7Zf8NOew3FLOH" } });
// Replace the file an object shows; it keeps its place, heading and bindings.
scene.update("pump", { geometry: { kind: "model", uri: "/models/pump-v2.glb" }, scale: 1 });
// The formats the renderer reads, and the format a file name says it is.
export const formats = MODEL_FORMATS; // ["gltf", "glb", "fbx", "obj", "stl", "ply", "dae", "3ds", "3mf", "usdz"]
export const pumpFormat = modelFormatOf("Pump.STL"); // "stl"
createThreeRenderer({
container: document.getElementById("view")!,
scene,
// `asset:<id>` names a file your app stores; say where it is fetched from.
assetUrl: (assetId) => `/api/assets/${assetId}`,
});Formats
| Format | Extension | Notes |
|---|---|---|
| glTF | .gltf, .glb | Materials, hierarchy and named nodes. The format to prefer. |
| FBX | .fbx | Materials and hierarchy. |
| OBJ | .obj | Geometry and groups; materials in a separate .mtl are not read. |
| STL | .stl | Geometry only, drawn in a plain material. Stands on Z, turned to stand up. |
| PLY | .ply | Geometry, with colours by vertex when the file has them. Stands on Z. |
| Collada | .dae | Materials and hierarchy. |
| 3D Studio | .3ds | Materials. Stands on Z. |
| 3MF | .3mf | Materials. Stands on Z. |
| USDZ | .usdz | Geometry and simple materials. |
MODEL_FORMATS lists them and modelFormatOf(fileName) names the format of a file by its
extension, or null. A model with no format is read by the extension of its address, and
as glTF when the address has none. A model stands on its own origin, in metres: give scale
when the file was drawn in millimetres (0.001) or centimetres (0.01).
What the renderer does
- It fetches a file once per page and gives each object its own copy with its own materials, so the glow of one never lights another.
parttakes one named node of a file and stands it at its own origin, so one file can draw many objects: each element of a building, say.asset:<id>names a file your application stores; theassetUrloption says where it is fetched from. Without it, such a model cannot load and the error goes toonError.- Replacing the geometry of an object loads the new file and keeps everything else the object is: its place, its bindings, its readings.
BIM
An IFC file is not read in the browser. Klorad One reads it on the platform's worker, keeps its
elements as Scene Objects with their properties and stores their meshes as one glTF binary,
each element a named node; each element then draws its own part of that file.
Something wrong or unclear? Tell us.