or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

2d-controls.md2d-layout.md3d-controls.md3d-materials.mdindex.mdinput-controls.mdutilities.md
tile.json

3d-controls.mddocs/

3D Controls

Immersive 3D interface elements that exist within the 3D scene space, including holographic buttons, 3D panels, and spatial menus.

Capabilities

GUI3D Manager

Main manager class for 3D GUI elements and interactions.

class GUI3DManager implements IDisposable {
  constructor(scene?: Scene);
  
  rootContainer: Container3D;
  utilityLayer: Nullable<UtilityLayerRenderer>;
  controlScaling: number;
  
  addControl(control: Control3D): GUI3DManager;
  removeControl(control: Control3D): GUI3DManager;
  containsControl(control: Control3D): boolean;
  dispose(): void;
  
  onPickedPointChangedObservable: Observable<Nullable<Vector3>>;
  onPickingObservable: Observable<Nullable<AbstractMesh>>;
}

Usage Examples:

import { GUI3DManager, HolographicButton } from "@babylonjs/gui";

// Create 3D GUI manager
const gui3DManager = new GUI3DManager(scene);

// Create and add 3D control
const button3D = new HolographicButton("btn3d");
button3D.text = "Hello 3D";
button3D.position.x = 2;

gui3DManager.addControl(button3D);

// Handle picking events
gui3DManager.onPickingObservable.add((mesh) => {
    if (mesh) {
        console.log("Picked mesh:", mesh.name);
    }
});

Base 3D Controls

Foundation classes for all 3D GUI controls.

abstract class Control3D implements IDisposable {
  name: string;
  position: Vector3;
  scaling: Vector3;
  node: Nullable<TransformNode>;
  mesh: Nullable<AbstractMesh>;
  parent: Nullable<Container3D>;
  isVisible: boolean;
  
  linkToTransformNode(transform: TransformNode): Control3D;
  dispose(): void;
  
  onPointerEnterObservable: Observable<Control3D>;
  onPointerOutObservable: Observable<Control3D>;
  onPointerDownObservable: Observable<Vector3WithInfo>;
  onPointerUpObservable: Observable<Vector3WithInfo>;
}

class ContentDisplay3D extends Control3D {
  content: Control;
  contentResolution: number | { width: number; height: number };
  contentScaleRatio: number;
}

class Container3D extends Control3D {
  addControl(control: Control3D): Container3D;
  removeControl(control: Control3D): Container3D;
  getChildByName(name: string): Nullable<Control3D>;
  containsControl(control: Control3D): boolean;
  children: Control3D[];
}

3D Buttons

Interactive button controls for 3D environments.

abstract class AbstractButton3D extends Control3D {
  onPointerClickObservable: Observable<Vector3WithInfo>;
  onPointerEnterObservable: Observable<Control3D>;
  onPointerOutObservable: Observable<Control3D>;
  onPointerDownObservable: Observable<Vector3WithInfo>;
  onPointerUpObservable: Observable<Vector3WithInfo>;
}

class Button3D extends AbstractButton3D {
  content: Control;
  contentResolution: number;
  contentScaleRatio: number;
}

class HolographicButton extends Button3D {
  imageUrl: string;
  text: string;
  tooltipText: string;
  tooltipTextBlock: TextBlock;
  backMaterial: FluentBackplateMaterial;
  frontMaterial: FluentMaterial;
  plateMaterial: StandardMaterial;
  renderingGroupId: number;
  
  shareMaterials(sourceMesh: AbstractMesh): void;
}

class TouchHolographicButton extends HolographicButton {
  collideMeshes: AbstractMesh[];
  collisionGroup: number;
  collisionMask: number;
  
  onToggleObservable: Observable<boolean>;
}

class MeshButton3D extends Button3D {
  mesh: AbstractMesh;
}

class TouchMeshButton3D extends MeshButton3D {
  collideMeshes: AbstractMesh[];
  collisionGroup: number;
  collisionMask: number;
  
  onToggleObservable: Observable<boolean>;
}

Usage Examples:

import { HolographicButton, TouchHolographicButton, MeshButton3D } from "@babylonjs/gui";

// Create holographic button
const holoButton = new HolographicButton("holoBtn");
holoButton.text = "Click Me";
holoButton.position = new Vector3(0, 1.5, 2);
holoButton.tooltipText = "This button does something";

// Handle button events
holoButton.onPointerClickObservable.add(() => {
    console.log("Holographic button clicked!");
});

// Create touch-enabled button
const touchButton = new TouchHolographicButton("touchBtn");
touchButton.text = "Touch Button";
touchButton.position = new Vector3(2, 1.5, 2);

// Set collision objects
touchButton.collideMeshes = [handMesh, controllerMesh];

touchButton.onToggleObservable.add((isPressed) => {
    console.log("Button is", isPressed ? "pressed" : "released");
});

// Create mesh button with custom geometry
const customMesh = MeshBuilder.CreateBox("buttonMesh", {size: 0.5}, scene);
const meshButton = new MeshButton3D(customMesh, "meshBtn");
meshButton.position = new Vector3(-2, 1.5, 2);

3D Panels and Layouts

Spatial layout containers for organizing 3D controls.

class StackPanel3D extends Container3D {
  isVertical: boolean;
  margin: number;
}

abstract class VolumeBasedPanel extends Container3D {
  orientation: Vector3;
  columnCount: number;
  rowCount: number;
  
  blockLayout(): void;
  unblockLayout(): void;
}

class PlanePanel extends Container3D {
  columns: number;
  rows: number;
}

class SpherePanel extends VolumeBasedPanel {
  radius: number;
}

class CylinderPanel extends VolumeBasedPanel {
  radius: number;
}

class ScatterPanel extends Container3D {
  iteration: number;
  size: Vector3;
}

Usage Examples:

import { StackPanel3D, SpherePanel, PlanePanel } from "@babylonjs/gui";

// Create vertical stack of 3D buttons
const stack3D = new StackPanel3D("stack");
stack3D.isVertical = true;
stack3D.margin = 0.1;

const buttons = ["Menu", "Options", "Exit"];
buttons.forEach((text, index) => {
    const btn = new HolographicButton(`btn${index}`);
    btn.text = text;
    stack3D.addControl(btn);
});

// Create spherical menu layout
const sphereMenu = new SpherePanel("sphereMenu");
sphereMenu.radius = 1.5;
sphereMenu.columns = 6;
sphereMenu.rows = 3;

// Add controls to sphere
for (let i = 0; i < 12; i++) {
    const btn = new HolographicButton(`sphereBtn${i}`);
    btn.text = `Item ${i + 1}`;
    sphereMenu.addControl(btn);
}

// Create planar grid layout
const planePanel = new PlanePanel("plane");
planePanel.columns = 3;
planePanel.rows = 2;
planePanel.position = new Vector3(0, 2, 3);

3D Sliders and Input

Value input controls for 3D environments.

class Slider3D extends Control3D {
  minimum: number;
  maximum: number;
  value: number;
  step: number;
  
  onValueChangedObservable: Observable<number>;
}

Usage Examples:

import { Slider3D } from "@babylonjs/gui";

// Create 3D slider
const slider3D = new Slider3D("volumeSlider");
slider3D.minimum = 0;
slider3D.maximum = 100;
slider3D.value = 50;
slider3D.step = 1;
slider3D.position = new Vector3(0, 1, 3);

// Handle value changes
slider3D.onValueChangedObservable.add((value) => {
    console.log("Slider value:", value);
    // Update volume or other property
});

Specialized 3D Controls

Advanced 3D interface elements for mixed reality and spatial computing.

class HolographicBackplate extends Control3D {
  renderingGroupId: number;
  shareMaterials(sourceMesh: AbstractMesh): void;
}

class HolographicSlate extends ContentDisplay3D {
  title: string;
  titleBarText: string;
  titleBarHeight: number;
  backplateMaterial: MRDLBackplateMaterial;
  frontplateMaterial: MRDLFrontplateMaterial;
  
  imageUrl: string;
  titleBarMargin: number;
}

class HandMenu extends VolumeBasedPanel {
  palmUpStrictness: number;
  followTiltAngle: number;
  
  onHandMenuVisibilityChangedObservable: Observable<boolean>;
}

class NearMenu extends VolumeBasedPanel {
  isPinned: boolean;
  dragTolerance: number;
  
  onMenuStateChangedObservable: Observable<string>;
}

Usage Examples:

import { HolographicSlate, HandMenu, NearMenu } from "@babylonjs/gui";

// Create holographic slate
const slate = new HolographicSlate("infoSlate");
slate.title = "Information Panel";
slate.imageUrl = "./info-content.png";
slate.position = new Vector3(0, 2, 2);

// Create hand menu
const handMenu = new HandMenu("handMenu");
handMenu.palmUpStrictness = 0.8;
handMenu.columns = 2;
handMenu.rows = 2;

// Add buttons to hand menu
const menuItems = ["Home", "Settings", "Help", "Exit"];
menuItems.forEach((text, index) => {
    const btn = new HolographicButton(`menu${index}`);
    btn.text = text;
    handMenu.addControl(btn);
});

// Handle hand menu visibility
handMenu.onHandMenuVisibilityChangedObservable.add((visible) => {
    console.log("Hand menu is", visible ? "visible" : "hidden");
});

// Create near menu
const nearMenu = new NearMenu("nearMenu");
nearMenu.isPinned = false;
nearMenu.dragTolerance = 0.1;

nearMenu.onMenuStateChangedObservable.add((state) => {
    console.log("Near menu state:", state);
});

Types and Interfaces

class Vector3WithInfo extends Vector3 {
  buttonIndex: number;
  pickedMesh: Nullable<AbstractMesh>;
}

interface IDisposable {
  dispose(): void;
}

interface IButton3DCreationOptions {
  width?: number;
  height?: number;
  depth?: number;
}

// 3D control events
interface IPointer3DEvent {
  position: Vector3;
  buttonIndex: number;
  pickedMesh: Nullable<AbstractMesh>;
}