Skip to content

3D Models

EcoCtrl supports interactive 3D building visualization through Babylon.js. Administrators upload glTF/glB models via the admin dashboard; the public web portal renders them with configurable camera angles, lighting and annotated hotspots.

Upload pipeline

Admin UI

The Models page in the admin dashboard provides:

  • ModelFileZone.tsx — drag-and-drop upload area with format validation.
  • ModelViewer.tsx — preview the model before publishing using Google Model Viewer.
  • Scene configuration panel for camera preset, ambient light and hotspot placement.

Supported formats

  • glTF 2.0 (.gltf + .bin + textures)
  • glB (binary glTF, .glb) — preferred for single-file uploads

Other formats (FBX, OBJ, STL) are not supported directly. Convert to glB using Blender or online converters before upload.

Data model

models

Uploaded 3D model metadata.

ColumnTypeNotes
iduuid PK
namevarcharOriginal filename.
fileUrlvarcharPublic URL: /static/models/<filename>.
fileSizebigintBytes.
mimeTypevarcharmodel/gltf+json or model/gltf-binary.
descriptiontextOptional.
createdAttimestamptz

dashboard_models

Single-row scene configuration.

ColumnTypeNotes
idserial PK
modelFileUrlvarcharActive model file URL.
cameraPresetvarcharNamed camera angle (Default_View_01, Top_View, etc.).
ambientLightIntensityreal0–1, default 0.85.
hotspotsjsonbArray of {x, y, z, label, targetId}.
labelsjsonbArray of {position: {x,y,z}, text, color}.
updatedAttimestamptz

Web portal rendering

apps/web/app/components/dashboard/building-view.tsx loads the active model into a Babylon.js scene:

ts
// Simplified flow
const config = await fetch("/api/public/model").then((r) => r.json());
const engine = new Engine(canvas, true);
const scene = new Scene(engine);
await SceneLoader.ImportMeshAsync("", config.modelFileUrl, "", scene);
// Apply camera preset, ambient light, hotspots and labels from config

Camera presets

Camera presets are named views stored in the model's glTF data or overridden in dashboard_models.cameraPreset. Common presets:

PresetDescription
Default_View_01Front-facing overview.
Top_ViewBird's eye view.
Side_ViewLeft-side elevation.

Hotspots

Hotspots are clickable markers placed at 3D coordinates. When clicked, they can:

  • Display a tooltip with the label text.
  • Navigate to a specific floor or system page.
  • Show real-time IoT data for the associated targetId.

Labels

Labels are persistent text annotations floating at fixed 3D positions. They are useful for marking building sections, equipment rooms or energy zones.

API

MethodPathDescription
GET/api/public/modelPublic scene config (no auth).
GET/api/modelsList uploaded models.
POST/api/modelsUpload a new model.
GET/api/models/:idGet model metadata.
DELETE/api/models/:idDelete model and file.
GET/api/dashboard-modelGet full scene config.
PUT/api/dashboard-modelUpdate scene config.

File serving

Models are served as static files at /static/models/<filename>. Fastify's fastify-static plugin handles this:

ts
await fastify.register(fastifyStatic, {
  root: "uploads/models",
  prefix: "/static/models/",
});

No authentication is required for /static/models/* — the web portal needs to load them directly in the browser.

Released under the MIT License.