Skip to content

Embed API: SET_CAMERA, RESET_COLORS and ENTITY_HOVERED are inert, and 8 URL params are never applied #2934

Description

@BIMvoice

Summary

Auditing the embed postMessage API surface, most of it is sound — all 23 InboundCommandType entries have a matching case in handler.ts with no mismatch in either direction, 20 of them reach a real actuator, and GET_SCREENSHOT returns an honest NOT_IMPLEMENTED rather than pretending.

Four things do not work, and each one signals success while doing nothing. Verified on main (b3a4d30), most by execution.

1. SET_CAMERA never moves the camera

apps/viewer-embed/src/bridge/handler.ts:401-406 extracts {azimuth, elevation} and calls setCameraRotation. apps/viewer/src/store/slices/cameraSlice.ts:44 does set({cameraRotation}) — and the chain ends there.

Proven by execution: driving setCameraRotation against a store built from the real slice, with a recording proxy over cameraCallbacks, invokes zero callbacks. The only absolute-orientation actuator, applyViewpoint (apps/viewer/src/store/types.ts:339-406), takes position/target vectors and is never called from the handler. Everything azimuth/elevation-shaped on CameraCallbacks is a relative stepper (rotateLeft/rotateRight/orbit). The payload's documented zoom? field (packages/embed-protocol/src/index.ts:96) is dropped silently too.

2. CAMERA_CHANGED never fires for real navigation

cameraRotation is written only by setCameraRotation, and real camera motion deliberately bypasses store state — cameraSlice.ts:57-64, "Don't update store state during real-time updates", with the live per-frame path going through updateCameraRotationRealtime to a separate callback.

So the outbound event at EmbedViewer.tsx:241-251 can only fire by echoing back values a host just sent. User navigation — mouse drag, keyboard, ViewCube — emits nothing.

Combined with #1, a host sending SET_CAMERA receives a requestId ack and a CAMERA_CHANGED echo of its own values — every success signal — while the view never moves.

3. RESET_COLORS cannot undo SET_COLORS

SET_COLORS reaches dataSlice.ts:279 updateMeshColors, which writes pendingMeshColorUpdates and bakes colour into geometryResult.meshes[].color. RESET_COLORS reaches dataSlice.ts:309 clearPendingColorUpdates, which clears pendingColorUpdates — a different channel, used by the lens/IDS/SDK overlays.

Proven by execution: calling the real updateMeshColors then the real clearPendingColorUpdates leaves both the baked mesh colour and pendingMeshColorUpdates untouched.

4. ENTITY_HOVERED is never emitted

Declared at packages/embed-protocol/src/index.ts:130,143, with listener plumbing and tests in packages/embed-sdk. There are zero emitEvent('ENTITY_HOVERED', ...) call sites in apps/viewer-embed.

The SDK tests pass because they call harness.emit('ENTITY_HOVERED', ...) directly — they prove the SDK dispatches an event the viewer never sends.

Also: eight URL parameters are parsed and never applied

apps/viewer-embed/src/bridge/urlParams.ts parses 14 parameters; 6 are applied. Dead: controls, autoLoad, hideAxis, hideScale, select, isolate, hideTypes, camera.

autoLoad is worse than inert — the autoload effect (EmbedViewer.tsx:134-159) has no gate at all, so ?autoLoad=false loads the model anyway. urlParams.test.ts:119-127 pins the parsing with four assertions, which is why this held: the parser is tested, the application of the parsed value is not.

camera is dead for the same root cause as #1 — nothing exists to hand it to.

Status

We have fixes on a branch for everything with unambiguous semantics — the colour reset (backing up pre-override colours so reset genuinely restores), the autoLoad gate, five of the URL params, and ENTITY_HOVERED (which turned out not to need new renderer plumbing; hoverSlice was already reachable). Each has a test that fails before and passes after.

controls is not implemented — there is no orbit/pan restriction mechanism in the camera controller to hang it on.

SET_CAMERA and ?camera= are deliberately untouched. Restoring them needs a real absolute-orientation actuator on CameraCallbacks, and whether the two should share one — or route through applyViewpoint — is a design call we did not want to make on your behalf.

Happy to open a PR once the review queue has drained, or to split it if you would rather take these separately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions