User Guide

Using SpatialWork on the Web

Build and view 3D digital twins in the browser, drive them from live data, lay out and simulate spaces with an agent, and publish read-only links people can open without an account. No install.

Where to go: spatialwork.hiverlab.com. There is also a staging copy at spatialwork-staging.hiverlab.com for trying things before they reach everyone. It shares the same data, so treat changes there as real.

What SpatialWork is

SpatialWork opens the 3D spaces your team builds (models, splats, whole buildings) in the browser and lets you hang live data on them: charts, gauges and status panels that read straight from your databases and APIs, objects that show their readings when clicked or change colour with their data, and copies that move with their data. On top of that, an agent can lay out a room from a sentence, and a simulator runs people through the space to show where it queues and crowds.

StepWhat happens
1. Build the sceneImport models into a new scene here, or publish one from Unity SpatialWork.
2. Open it on the webSign in with your Central Platform account; your projects are waiting on the dashboard.
3. Add live dataConnect a source, describe a chart in plain words, place it in the scene. It refreshes on its own.
4. Share itPublish a read-only link, or embed it in your own dashboard.

Who sees what

PersonWhat they get
The ownerEverything: edit, connect data, publish, share, rename, delete.
An editor you addedEdits the project like you, except publishing, renaming, deleting and re-sharing (§22).
Someone with the published linkRead-only, no account: looks around, switches viewpoints and shown versions, clicks objects. Chart data still updates live; they never see your data connections.
About your data. Database passwords and API keys are encrypted and stay on the server; the browser only ever holds a reference to a connection. Database queries are read-only and capped, so a chart can never change your data, and a published link runs only the queries its own charts already contain.
Contents

01 What you are working with

A project is a 3D scene plus everything layered on it: imported models, data charts, interactive objects, heatmaps, saved camera viewpoints, and the connections to wherever your data lives. Two kinds sit side by side on the dashboard:

KindWhat it is
SpatialWork sceneA 3D scene you build in the browser, or one published from Unity SpatialWork. Everything in this guide applies to it.
GeoSenseA map-based project, opened in the geo editor. Different tool, same dashboard and the same sign-in.

Work saves as you go, and the top bar shows when it last saved. Save there saves at once. Ctrl+Z takes back an edit you did not mean (§05).

The editor: the rail on the left opens each panel, the top bar holds the project, its version, undo, Save and Publish, and the scene fills the rest.
The editor: the rail on the left opens each panel, the top bar holds the project, its version, undo, Save and Publish, and the scene fills the rest.

02 Sign in, and your dashboard

Log in with your Central Platform account, the same email and password you use elsewhere in Hiverlab tooling. You land on the dashboard, which lists every project you own or that someone has shared with you.

The dashboard. Each card opens a project; ↗ opens its published link.
The dashboard. Each card opens a project; ↗ opens its published link.
Everyone can read a few shared folders without being added to anything: the Spatialwork Assets Library, SW_3D_Group and GeneralLibrary, including their icon sets. You will see them in the library and in every picker.

03 Moving around

ActionControl
Look aroundLeft-drag
Orbit a pointAlt + left-drag. Turns around whatever is under the cursor
PanRight-drag or middle-drag
ZoomScroll. Moves towards whatever is under the cursor, not blindly forwards
FlyWASD · up E/Space · down Q · Shift for 3× speed
Frame the selectionF
Straight-on viewsThe view pill at the top: Top, Front, Left and the rest
Jump to a viewpointClick it in Views
Move / Rotate / Scale the selection1 2 3
Undo / RedoCtrl+Z · Ctrl+Shift+Z or Ctrl+Y, or the arrows in the top bar
Find an object by nameCtrl+F jumps to the Scene panel's search box

Looking and flying are deliberately separate from orbiting, the same way Blender and Unity separate them, so a fly never fights an orbit mid-drag. Any movement cancels a viewpoint fly-to. Move speed and look sensitivity are in Settings → Controls, and every key is listed under Settings → Key bindings.

04 The Scene panel

The rail on the left holds Scene, Data, Agent, Simulate, Views and Assets, with Settings at the foot. Scene opens first: a tree of everything in the scene, sorted by kind. Each row carries three switches, always in the same columns:

Select a row to get the gizmo; 1, 2 and 3 switch it between Move, Rotate and Scale. Clicking an object in the 3D view opens its row in the tree. Double-click a name to rename. Drag a row onto a group to put it inside. New group and Collapse all are in the panel header. Groups start collapsed, and they are the main way to keep a scene legible. They matter later when you publish (§21).

The Scene panel on an office scene, organised in groups. Each row has its eye, X-ray and lock switches.
The Scene panel on an office scene, organised in groups. Each row has its eye, X-ray and lock switches.

Search

Type in Search objects and the tree shows only the matches, plus the groups leading to them. Every word you type must appear in the name, in any order. Enter selects the first match, Shift+Enter selects all of them, F then frames them, and Esc clears the search.

A selected object: the gizmo in the scene (Move, Rotate, Scale at the bottom) and its exact position, rotation and scale on the right.
A selected object: the gizmo in the scene (Move, Rotate, Scale at the bottom) and its exact position, rotation and scale on the right.

05 Undo and redo

Every edit to the scene can be undone, up to 50 steps per tab and version: moves, deletes, renames, new charts, a layout the agent applied. A whole drag counts as one step. Deleting asks you to confirm, and the confirmation reminds you that Ctrl+Z brings it back.

Undo covers the scene itself. Files you uploaded and data sources you connected live outside it and are not undone. Inside a text box, Ctrl+Z undoes your typing, as usual. For going further back than a session, use a restore point (§19).

06 Adding 3D content

Open Assets in the rail to browse the Central Platform library: your own uploads, folders you are a member of, and the shared libraries. Pick a model or splat and it drops into the scene. Compressed GLBs (Draco or Meshopt) load as they are; there is no need to export an uncompressed copy.

The picker also shows In this project: everything the open scene already uses. That is the only listing that works on a project shared with you, since the folders belong to whoever uploaded into them.

The asset picker, open on In this project. Shared folders are listed below it.
The asset picker, open on In this project. Shared folders are listed below it.

07 Connecting data

Data → Data source. A source is a connection, defined once and reused by every chart, interactive object and dynamic set in the project. Credentials are stored encrypted on the server and never sent back to the browser.

A database

Host, port, database, user, password. Queries are read-only SELECTs.

A REST / JSON API

The URL, then as much of the rest as the API needs:

FieldUse it for
MethodGET, or POST for a read endpoint that takes its filter in the body.
Request bodyAppears for POST. Must be valid JSON; it is checked before saving.
AuthNone, an API key in a header, a bearer token, a username and password, or Sign in for a token.
Extra headersName: value, one per line. For a tenant id, an API version pin, anything that is not itself a credential.
Read byOur server, or each viewer's browser. Left on the first choice, it is decided when you save: a source with a login or key is always read by our server; one with none is read by viewers' browsers if this browser can reach it.

Read by viewers' browsers

An API on a client's own network (an intranet) cannot be reached from our server, but it can be reached by the browsers of people on that network. A source read by each viewer's browser works that way: every viewer's browser asks the API itself, in the editor, the published link and an embedded dashboard alike. Every window shows the same data, and nothing passes through our server.

Sign in for a token is for APIs that issue short-lived tokens instead of permanent keys. Give it the sign-in URL, a username and password, and its own headers. The server fetches a token, keeps it in memory only, and renews it before it expires, so charts keep updating without anyone pasting a new token every few hours.

Press ⚡ on a source to test it. A failure says which half broke: bad credentials, a token that is not where expected, or the data call itself being refused.

The Data menu: everything that brings data into the scene starts here.
The Data menu: everything that brings data into the scene starts here.

08 Charts

Data → Chart adds a card into the scene. Open its ✎ for the style editor.

Charts standing in the scene, on live data: a status panel, a bar chart, a stacked area chart and a gauge.
Charts standing in the scene, on live data: a status panel, a bar chart, a stacked area chart and a gauge.

Describe it, and let the assistant write the query

Pick the source, say what you want in plain language, for example "chiller flow rate for device 100001". Choose a type or leave it on Auto, and press Generate with AI. It fills in the query, and you press Test query to see what actually comes back before anything reaches the scene. Nothing is applied behind your back.

If a result comes back wider than you meant, say the identifying value in your description. The assistant filters on what you name; with nothing to go on it can only guess, and it will say what it assumed.

Types

TypeShowsNeeds
ValueOne big numberA query returning a single value
GaugeA dial, with its threshold colours drawn on the dial's own arcA single value, plus min and max
TableRows and columnsA query returning rows
Status panelA place's state at a glance: its name in large type, a coloured headline, an explanation line, KPI tiles and a footerA query returning one row
Bar, LineA plotted seriesWritten by the assistant. These are the two the dropdown cannot offer, because their shape lives in a generated spec

Status panels

A status panel is written as plain lines in the style editor, one per item:

Styling and placement

09 Interactive objects

Data → Interactive asset. Clicking an object in the scene opens a small panel of readings beside it. Describe what a click should show and press Ask to have the query written for you, or write it yourself.

Choose what is clickable: a whole group (everything beneath it, nested groups included), or individual objects you select and Add selected. The difference decides how the query has to look:

Bound toThe query should returnObject id column
One objectIts row, or every row about itNot needed: the binding already says which object
Several, or a groupOne row per objectThe column whose values match the object names

Names are matched with the file extension dropped, so an object imported as pressure.glb matches a row keyed pressure. You do not need to rename anything, and your data does not need to know about .glb.

Fields to show chooses which columns the panel shows, in order. A feed that sends one row per measurement (supply temperature, return temperature, humidity for the same unit) is shown as a Measurement | Value table with units and the last update time, instead of only the last row.

Colour objects by their data

Colour objects by takes a column and a list of rules: a number range or an exact text value, each with a colour. Each object takes the colour of the first rule its own value meets, and the colours are reapplied on every refresh. An object whose row stops matching goes back to its own look. Dark models show the rule's colour too, since the tint mixes with the model's own colour instead of darkening it.

10 Dynamic objects

Data → Dynamic objects spawns and moves copies of library models from a data API: pallets in racks, AMRs on a floor, people and equipment in a hospital. Every item in the data (a person, a pallet, a wheelchair) becomes a copy of one of the models. On each refresh the copies glide to their new places, new items appear and items that are gone disappear. The panel is laid out in the order you answer it: Data, Models, Position & motion, Colour and On click.

Ask AI

The quickest way: choose the data API, describe what to show, for example "staff as people, a model per role, coloured by state with SOS pulsing red", and press Ask AI. It reads a sample of the data, the scene's place names and your library's model names, and fills in the whole panel: the list, the ID, where each item goes, a model per value, status colours, the label and the click fields. Check what it chose (the preview and the line under Refresh help) and press Apply; nothing is applied on its own. Anything it got wrong is just a field to change.

Data

Choose the data API. With a REST source every list in its data is offered with how many items it holds and their columns; choose the one that holds the things to show (the JSONPath behind it is under Edit as JSON). A database source takes a SQL query instead. The data is read straight away: a preview shows the first few items, every column question below is a list of the real columns, and the line under Refresh says how many items there are and how many would actually be placed in this scene. Nested values read as dotted columns, so pos: {x, y, z} gives pos.x, pos.y, pos.z. For a source read by viewers' browsers, keep to the lists the picker offers; filters need our server.

Models

Models come from the asset library: shared folders and your own uploads. Nothing has to be placed in the scene to be copied. Leave Model by on one model for every item and choose that model; or choose a column (such as role) and add + Model for a value for each value that needs its own (a nurse figure for nurse, a wheelchair for wheelchair); the value box offers the values in the data. + Any other value covers the rest; without it, items with an unlisted value are not shown. Each model has a size (1 is its own size) and a turn in degrees about the vertical, which every copy of it takes.

A set made by the older editor used objects in the scene as models. It opens with those turned into the same library models at the same size and turn; Apply saves it, and can delete the scene objects that were only there to be copied.

Position & motion

Colour and On click

Tracking people and equipment

Use one Dynamic object per kind of thing and put each in its own group, such as Staff, Patients and Assets: each then reads its own list and has its own models, status rules and label, and viewers can show or hide it. Kinds whose status values differ need no separate API for that reason. The data only says what is where; everything about the look stays here, so changing a colour or a model is a scene edit. Positions are x / y / z in scene metres, and the data supplies y where height matters, for example across floors; nothing is guessed. A tracking API on the client's own network is connected as a source read by each viewer's browser (§07).

Edit as JSON shows the whole set as configuration, to read, copy into another project or edit. The delete button is in the panel's header. The editor never puts the gizmo on a copy: the copies belong to the data, not to you.

In an embedded viewer

Clicking a copy sends the host page an object-click message whose instance is the item's ID (such as S-201) and whose row is its data, so the host can open its own record for that person or asset. The host page does not send positions; the viewer reads them from the data API itself.

Limitations

11 Spatial heatmaps

Data → Spatial heatmap interpolates one numeric reading across a floor, between sensors that are ordinary objects in a group. Move a sensor in the editor and its contribution moves with it.

Point it at the group, give it a query returning one row per sensor, and say which column is the name and which the value. Min and max should come from the quantity (RSSI is about −90 to −30 dBm, a percentage 0 to 100), not from whatever today's sample happens to span, or later readings fall off the scale. Viridis is the default colour scheme and the safest for colour blindness; the traffic-light scheme is the one to avoid if that matters to your audience.

12 Build with Agent: data objects

Agent in the rail opens Build with Agent, which works on the whole scene. It has two tabs: Data objects, covered here, and Space layout (§13).

Pick a data source and describe what you want, e.g. "A gauge of chiller load. A Wi-Fi signal heatmap on the Access points group. Make Pump A and Pump B clickable to show flow and status." Press Build. The agent reads the source and the scene's own names. It proposes charts (placed in front of the camera), status panels standing in each place, heatmaps on a named group, clickable objects, colour rules and dynamic sets. You see the list first and choose what goes in.

Build with Agent, Data objects: pick a source and describe what to build in the scene's own names.
Build with Agent, Data objects: pick a source and describe what to build in the scene's own names.

13 Space layout: plan a room with the agent

Agent → Space layout rearranges a place using the furniture the scene already has. It never generates a 3D model: every desk, chair or table it places is a copy of one already in the scene or in your library, with the same materials, so nothing new is uploaded.

“Make the workshop a standard office with desks and chairs”: the plan, its floor sketch (new, stays, free floor) and checks on the left, and the preview standing in the scene. Nothing is saved until you apply it.
“Make the workshop a standard office with desks and chairs”: the plan, its floor sketch (new, stays, free floor) and checks on the left, and the preview standing in the scene. Nothing is saved until you apply it.

What you can ask for

Kind of requestExample
Turn a place into something else"Make the workshop a standard office with desks and chairs"
A number, in rows"200 chairs facing the stage, 10 per row"
Several blocks"200 at the front, 200 at the back"
Fill a whole room"Fill the space with meeting tables". Sets go in rows, single pieces along the walls
Put things somewhere"Sofas in the corners", "a row of lockers along the north wall"
Grow what is there"Another 50 chairs with the existing ones"
Edit what is there"Remove the sofas", "rotate the desks to face the window", "move the reception desk 2 m to the left", "desks toward the window"
Name one object"Chairs facing the south entrance". The agent reads every object's name, group and position, so it can aim at one exact thing

How it works

  1. Say where and what. Name the place in What should change?. With no place named, it works on the place around your selection, or around the camera (shown as current). On an empty floor it starts with a 10 × 10 m square at that spot and grows it, up to 40 × 40 m, if it needs more room.
  2. Plan layout. The agent finds the furniture sets as they already stand: a desk with its chair, a pod of facing desks, a meeting table and its chairs. It also finds single pieces such as a sofa. They are listed under Furniture sets in this scene. Then it measures the room (walls, floor, what stays) and packs the sets in rows.
  3. Read the checks. The plan is checked against your request before you see it: each step's count and rows, no overlaps, inside the walls and on the floor, nothing removed that was meant to stay. Anything it could not do is listed, along with things your request named that the scene has but that are not furniture ("its name has 'vent' in it").
  4. Pick from the library if needed. When the scene has no model of something you asked for ("a plant", "a treadmill"), the agent searches this project's models and then the shared libraries, by all their names. You choose one with Use these, Skip it, or Search under another name. Very large models are flagged before they load.
  5. Preview, then decide. The result stands in the scene, with the place's old objects hidden, but nothing is saved yet. Apply here replaces the place in this version as one save and one undo step. Save as new version copies the version with the new layout and leaves this one untouched. Discard drops it.

Good to know

14 The simulator

Simulate in the rail opens this scene's simulator in a tab of its own. It runs people through the real space: they walk the floor of your scene, queue, are served, sit, wander and leave, and you see where it gets crowded and how long people wait. Pressing Simulate again brings that tab forward without losing a run, and the simulator's Editor link goes back to the editor tab. It needs a saved project.

The page has a steps graph (what people do, in order), a floor plan with the places, a 3D view of the scene, and side tabs: Properties, People, Timing, Checks and Results. Drag the dividers to resize the panes.

A run in progress: the steps graph with a count on each step, people moving on the floor plan coloured by activity, and the clock, people inside and the registration line at the bottom right.
A run in progress: the steps graph with a count on each step, people moving on the floor plan coloured by activity, and the clock, people inside and the registration line at the bottom right.

1. Start

2. Steps

StepWhat people do
ArriveCome in at an entrance: how many, between which times, evenly, randomly or at a peak
ServiceQueue and are served: desks per place, seconds per person. Several places doing the same job share the load, and people take the quickest line
OccupyTake seats or stand in an area until a clock time or for a duration; when full they stand or skip it
VisitDrop by an area for a while (a share of people, a dwell time), optionally spread over several places
Free timeChoose where to go by what they need, until a clock time
SplitBranch the flow by share (70 % here, 30 % there) or by who (VIPs one way)
AlarmAn evacuation at a set time; everyone heads for the exits
ExitLeave by one of the exit points

3. Places

Each step happens at a place on the floor. Places from the scene makes them from the scene's objects by their names: a "Registration" desk becomes the registration place. You can also select objects in 3D and Add selected. On the plan, drag a place's arrows to Move it, its corner handles to Size it, and its ring to Turn it. Add another area copies a place so one job runs in several spots. Roof shows or hides the building above head height in 3D.

4. People and timing

5. Run, watch and read the results

Checks lists anything the setup is missing (a service with no desks, a step with two next steps and no Split) before you run. Run plays the run while it is worked out, as fast as possible or at a speed from 1× to 240×. People move on the plan and in 3D, each step shows how many people are at it, and quiet stretches are skipped. Colour people by activity or by who they are.

Results shows queues and waits per service (and per kind of person), who gave up, how long the evacuation took and whether anyone was still inside, and crowd density. Density uses Fruin's walkway levels of service: D crowded (over 0.72 people/m²), E very crowded (over 1.08), F crush risk (over 2.17). The plan can show Peak density or Time over band D for every spot on the floor. People seated or standing in a line are not counted, since those are dense by design. Afterwards, Play replays the run.

Simulator results with the peak density map
After the run: Peak density on the plan in Fruin bands D, E and F, and on the right the headline figures and each service's waits, with its line over time.

Save keeps the setup with the project (one simulation per project) and shows the revision it saved. Export downloads the setup as a file and Import loads one, to move a setup between projects.

15 Spatial analytics

Data → Spatial analytics slices a building model into walls and analyses the space. Wi-Fi coverage is the first analysis: point it at the floor model and the group of access points, slice the walls (or draw, select and fix them by hand), then press Run solver directly to compute coverage in the browser, or write an instruction and press Ask Copilot. The result is a coverage map scored only where there is building. It needs a saved project.

16 Look and settings

Settings, at the foot of the rail, has three tabs:

Settings → Controls.
Settings → Controls.

The scene's look (sun, tone mapping, exposure, bloom, background) is saved with the scene, so the published link looks the same as the editor. Shadows land on the grid, the ground you see, even under a model that hangs above it.

17 Viewpoints

Views in the rail saves camera positions. The first is the scene's opening view, what anyone sees when they open the project or the published link. Viewers can jump between them; they cannot change them.

Views: click a viewpoint to fly there; the first is the opening view.
Views: click a viewpoint to fly there; the first is the opening view.

18 Versions

A version is an authored variant ("ground floor", "night lighting", "client cut A"), not an undo history. Each has its own objects, charts and viewpoints, and each is independently shown or hidden to viewers.

One version opens first, in the editor and on the published link. Choose it with the home button beside a version. If that version is hidden, the link opens on the first shown version instead, and the panel says so.

The Publish panel: the read-only link at the top, then every version with its Shown switch, the home button that picks which opens first, and restore points at the foot.
The Publish panel: the read-only link at the top, then every version with its Shown switch, the home button that picks which opens first, and restore points at the foot.

19 Restore points

Save a restore point in the Versions panel keeps the whole project as it is now, every version included, under a name. Roll back returns the whole project to a restore point. Nothing is lost by doing so: save the state you are leaving as a restore point of its own first, and you can come back to it. The panel says when you have edited since the last restore point.

20 Publish a read-only link

Publish gives the project one link. Anyone with it can look around, jump between viewpoints, click interactive objects, and switch between the versions you marked shown. Nothing else. They cannot edit, and they do not need an account.

Hiding a version is real access control, not a display filter: a hidden version cannot be reached from the link at all. Unpublishing revokes the link.

21 Let viewers show and hide groups

A published scene can let whoever opens it switch whole groups off. A floor of sensors is one idea, not forty, and hiding them is easier than explaining them.

  1. Group the objects in the Scene panel.
  2. Open the group's ✎ and tick Let viewers show or hide this group.
  3. Publish. The viewer gets a Groups dropdown listing exactly those groups. It stays open while they switch several, and its ticks always match what is on screen.

What a viewer switches off is theirs for that visit only. It is never saved back, and it never affects anyone else opening the same link. A group inside a group gets its own switch.

22 Let someone else edit

People on a project card adds an editor by email address. They get the project on their own dashboard with a SHARED chip, and can do everything you can except publish, rename, delete or re-share it. Those stay with the owner.

An editor can open the project's assets even when the folders they came from belong to you, which is what makes a shared project actually workable.

23 Embedding in your own dashboard

A published scene can sit in an <iframe> and talk to the page around it: your dashboard can highlight an object when someone clicks a table row, and hear about clicks in the 3D view. Embed in the Versions panel copies a ready-made iframe snippet. A click reports the object, and the asset id and other fields its binding filters on, so the host can look it up in its own data. See the embedding guide for the full message list.

One behaviour worth knowing here: selecting an object from the host works even when the viewer has switched its group off. The host asked about an object, not a group, so the group is not revealed. Expect the readout, and the camera move, for something not currently on screen.

24 When something looks wrong

What you seeUsually means
A chart says no dataThe query returned nothing. Press Test query in the style editor to see the raw result.
A chart stopped updatingA short-lived token expired. Test the source; if it is a sign-in source, that renewal is automatic and the failure is elsewhere.
No reading matched "…" on a clickThe object id column is wrong, or the query is wider than the binding. The panel names the column it used and the values it saw.
A heatmap is blankNo row's name matched an object in the group. It reports how many rows it had and what the objects are called.
Dynamic objects do not appearRows came back but did not land in this scene. The line under Refresh counts how many would be placed; check that the place column names objects or rack slots this scene actually has, and that every value has a model (or add Any other value).
The layout agent left something outRead its Checks: it says which step it could not carry, or which named things it found that are not furniture. Nothing is saved until you Apply.
A table shows columns you did not wantSet Columns. A REST query cannot trim them itself.
Panels feel slowSettings → Visuals → Chart panels → Glass blur. The blur behind them is the most GPU-expensive part of how they look. Ambient occlusion is the next one to turn off.
An icon shows a dashed boxIts URL no longer resolves; the asset was probably removed from the library. Clear it and choose another.
You deleted the wrong thingCtrl+Z. Further back than this session, roll back to a restore point.

Updated 10 November 2026. Something here wrong or missing? It is maintained alongside the code. Tell the team and it gets corrected in the same place the behaviour lives.