Helper class to set up a basic 3D demo with a Scene, Data, Viewer, WebGLRenderer, and View.

See @xeokit/sdk/demo for usage.

Constructors

Properties

data: Data

The Data created by the Studio. Holds all data models.

events: StudioEvents = ...

Per-Studio event hub — currently just onError / onWarning. Mirrors the *.events shape on Scene, Data, Viewer, and WebGLRenderer; the !issuesPanel.IssuesPanel | IssuesPanel subscribes here alongside those four to surface Studio-side failures in the same list.

Registry of model-format loaders consulted by loadModel. Populated from StudioConfig.loaders or createDefaultLoaderRegistry.

locator: ModelLocator

Resolves the default URL for a (modelId, format) pair when loadModel is called without an explicit src. Populated from StudioConfig.locator or DefaultModelLocator.

modelsDir: string = "../../models"

Base directory for loading models, relative to the HTML page.

Single dispatch point for opening, hiding, and toggling every built-in panel and tool — studio.panels.open("modelsPanel"), studio.panels.toggle("navCube", {view}), etc. Replaces the 40 dedicated openX/hideX/toggleX methods that used to live directly on Studio.

Register custom panels with studio.panels.register("myId", ...) and augment PanelMap from your own module so the call sites stay typed.

Owns the unified pick strategy and the BVH-backed SceneCollisionIndex. Lazy-built — demos that never pick pay for neither. Direct picks: studio.picking.picker.pick({...}). AABB queries: studio.picking.collisionIndex.getSceneAABB(). ViewController adapter: studio.picking.pickForViewController(view, params).

renderer: WebGLRenderer

The WebGLRenderer created by the Studio.

scene: Scene

The Scene created by the Studio. Holds all 3D objects.

stats: {
    aabb: number[];
    data: DataModelStats;
    elapsedTime: number;
    endTime: number;
    memory: MemoryUsage;
    renderer: RenderStats;
    scene: SceneModelStats;
    startTime: number;
}

Statistics about the demo, available after calling finished().

viewer: Viewer

The Viewer created by the Studio.

viewManager: studio.ViewManager

Owns the lifecycle of every View created through Studio — the views map (records of view, cameraFlight, viewController), auto-canvas layout, and floating ViewPanels for floating: true. Read access: studio.viewManager.views[id].cameraFlight. Create / destroy: studio.viewManager.createView(...) / studio.viewManager.destroyView(view).

Methods

  • Lazily creates a ScenePhysics system, attaches every SceneObject of sceneModel (or every SceneObject of every SceneModel if no model is passed) as a dynamic Rapier body, and applies a downward gravity so the parts drop and "demolish" themselves.

    "Downward" is derived from Scene.coordinateSystem.worldUp — gravity points in -worldUp, which makes the demolition look the same regardless of whether the scene is Y-up, Z-up, or any other orientation. SceneModels with their own coordinate-system basis still fall the right way because Rapier bodies live in world space and the SceneModel's coordinateSystemMatrix has already mapped them there.

    The physics system, Rapier WASM module, and per-frame step() loop are only created on the first call — demos that never demolish anything pay nothing. Gravity is locked in at that first call from the Scene's worldUp; later calls don't re-derive it.

    Each object gets a small randomised initial angular + lateral velocity so the disassembly looks chaotic instead of monolithic.

    Parameters

    • OptionalsceneModel: SceneModel

      SceneModel whose objects should be turned into dynamic bodies. When omitted, every SceneModel currently in the Scene is demolished.

    Returns Promise<SDKResult<void>>

    SDKResult — ok: false if Rapier failed to load.

  • Destroys both the SceneModel and the DataModel that share modelId (when each exists). Either side may be absent — a model loaded via loadModel with no dataModel argument leaves the data side empty, and a model loaded with datamodel only leaves the scene side empty — and the call succeeds whichever combination is found.

    Pairs with how loadDataset mints SceneModel + DataModel under the same id so a "delete this model" action in the UI is the natural inverse: one call wipes both halves without the caller having to know which loader path produced them.

    Parameters

    • modelId: string

      The ID shared by the SceneModel / DataModel to destroy (typically SceneModel.id from the active selection).

    Returns { dataModelDestroyed: boolean; sceneModelDestroyed: boolean }

    A small report of what was actually destroyed — useful when the caller wants to log/announce only the sides that existed.

  • Initializes the Studio by creating the Scene, Data, Viewer, WebGLRenderer, and optional initial View.

    Parameters

    • cfg: StudioConfig = {}

      Configuration options for initialization.

    Returns Promise<any>

    A promise that resolves when initialization is complete.

  • Replace the helper's Scene + Data contents with a single named dataset from the demo model catalog (models/index.json). Loads formats sequentially into a fresh SceneModel + DataModel pair and frames the camera on the result.

    Parameters

    • params: {
          clear?: boolean;
          formats: string[];
          modelId: string;
          yieldIntervalMs?: number;
      }
      • Optionalclear?: boolean

        When true (default), every existing SceneModel + DataModel in the helper's Scene / Data is destroyed before the new one is created. Pass false to load alongside whatever's already there.

      • formats: string[]
      • modelId: string
      • OptionalyieldIntervalMs?: number

        Optional override for the cooperative-yield throttle, in milliseconds. See yieldIntervalMs — passed through to every per-format loadModel call so a single override applies across the whole dataset load. Raise above the 16ms default for noticeably faster large loads at the cost of less-frequent progress updates.

    Returns Promise<SDKResult<{ dataModel: DataModel; sceneModel: SceneModel }>>

    The newly-created SceneModel + DataModel on success, or an SDK error result if any phase fails.

  • Loads a model into the Scene and/or Data layers using a format-specific loader.

    This method:

    • Resolves or creates SceneModel and DataModel instances when not provided
    • Fetches model data from params.src or a default path derived from modelId
    • Selects the appropriate loader based on params.format
    • Delegates parsing and population to the corresponding loader implementation

    Supported formats:

    • "xgf" → XGFLoader (binary)
    • "ifc" → IFCLoader (binary)
    • "gltf" → GLTFLoader (binary, .glb)
    • "metamodel" → MetaModelLoader (JSON, data-only)
    • "datamodel" → DataModelParamsLoader (JSON, data-only)
    • "scenemodel" → SceneModelParamsLoader (JSON, scene-only)

    Default source resolution: If params.src is not provided, the source path is inferred as: ../../models/{modelId}/{format}/model.{ext}

    Model creation behavior:

    • If sceneModel is not provided, a new one is created via this.scene.createModel()
    • If dataModel is not provided, a new one is created via this.data.createModel()
    • Created model IDs are derived from modelId when available

    Parameters

    • params: {
          dataModel?: DataModel;
          format: string;
          modelId?: string;
          sceneModel?: SceneModel;
          src?: string;
      }

      Configuration for loading the model

      • OptionaldataModel?: DataModel

        Optional existing DataModel to populate

      • format: string

        Model format determining which loader to use

      • OptionalmodelId?: string

        Optional identifier used for default paths and generated model IDs

      • OptionalsceneModel?: SceneModel

        Optional existing SceneModel to populate

      • Optionalsrc?: string

        Optional explicit source URL/path for the model file

    • options: any

      Loader-specific options passed through to the underlying loader

    Returns Promise<SDKResult<any>>

    A promise resolving to an SDKResult containing the loader result

    Error

    • If model creation fails
    • If the format is unsupported
    • If fetching or parsing the model data fails
  • Open the floating per-example info panel. Single-instance: a second call destroys the previously-opened panel before constructing a fresh one, so an example always has at most one info card on screen. The caller gets the panel handle back and uses its imperative builders to populate it:

    const info = studio.openInfoPanel({
    id: "viewing_sectionPlane_duplex",
    title: "Section Caps — Duplex",
    description: "<p>Drag the slider to move the cut plane.</p>",
    });
    info.addToggle({ label: "Section plane", value: true,
    onChange: v => sp.active = v });
    info.addSlider({ label: "Cut Z (m)", min: 0, max: 5,
    value: 2.6, onChange: rebuildCaps });
    info.addStat ({ id: "caps", label: "Cap meshes" });
    // …later:
    info.setStat("caps", String(result.numCapMeshes));

    Layout / chrome notes:

    • Default position is top-left so the panel doesn't compete with the built-in panels that cluster top-right.
    • Non-modal: scene interaction passes through the body.
    • Per-example localStorage slot via InfoPanelParams.id.

    Parameters

    Returns InfoPanel

  • Open an InfoPanel pre-populated from the example's own index.json metadata. Single line for every example:

    const info = await studio.openInfoPanelFromMeta();
    info.addToggle({...}); // optional — chain controls if needed

    Fetches ./index.json (relative to the current page URL) and uses its id, title, and description fields to build the panel. If the fetch fails or the JSON is malformed, the promise still resolves with a generic panel rather than rejecting — examples never break because of a missing metadata file.

    Callers that need richer descriptions or want to override the metadata can pass override props that win over the fetched fields.

    Parameters

    Returns Promise<InfoPanel>

  • Dispatch an error through this Studio's StudioEvents.onError channel. The !issuesPanel.IssuesPanel | IssuesPanel is the canonical subscriber — every dispatch lands as a row in its log, with severity = "error". Panels and host code use this in place of throw / console.error so the IssuesPanel is the single place to surface Studio-side failures.

    Accepts either an SDKResult<any> (an ok: false outcome coming back from a downstream call) or a plain message string. For the string form, the dispatched payload synthesises an SDKResult<void> shape with the supplied type (defaulting to SDKErrorType.InvalidOperation).

    Parameters

    Returns void