@pixi/3d
    Preparing search index...

    Class AmbientLight

    Light that reaches every surface equally, whatever its position or direction

    It lifts shadowed areas off pure black for almost no cost. Several ambient lights add up. It casts no shadows; castShadow is ignored. On a Material3D it lights only the non-metal part, so a fully metallic surface gets nothing from it.

    import { AmbientLight } from '@pixi/3d';

    view.root.addChild(new AmbientLight({ color: 0xffffff, intensity: 0.3 }));

    Hemisphere For sky and ground colours that vary with the way a surface faces.

    Hierarchy (View Summary)

    Index
    boundsVolume: Box | null = null

    A fixed local-space box measured in place of this container and its subtree, or null to measure the geometry

    Set one on a large subtree whose extent you already know, such as a level chunk, to skip walking it. getLocalBounds and the size members read it. It's pixi's boundsArea; it doesn't change culling.

    swarm.boundsVolume = new Box(new Vector3(-10, 0, -10), new Vector3(10, 5, 10));
    
    castShadow: boolean = false

    Whether this light casts shadows; only directional and spot lights can

    The first light in a view to cast a shadow makes the view recompile its lit materials, once; later toggles recompile nothing.

    false
    
    torch.castShadow = settings.shadows;
    
    children: Container3D[] = []

    Child nodes

    Their order doesn't decide what draws first. Read the array, but change it through addChild and removeChild. To visit the whole subtree, use traverse.

    for (const child of group.children) child.visible = false;
    
    cursor: string & {} | Cursor | null

    CSS cursor shown while this node is the pointer's target

    Only the target's own cursor counts, as in 2D: a hit on a 'passive' child shows its interactive ancestor's cursor, so set it on the node with the listeners. null shows the View3D's own cursor. Any CSS cursor value works, url(...) included.

    null
    
    button.cursor = 'pointer';
    handle.cursor = 'grab';
    blade.cursor = 'url("crosshair.png") 8 8, crosshair'; // custom, with a hotspot
    destroyed: boolean = false

    Whether destroy has run, as in pixi's Container

    eventMode: EventMode

    How this node takes part in pointer events, as on a pixi.js Container

    • 'none': never picked, and neither is anything below it. The subtree costs nothing per pointer event.
    • 'passive' (default): fires no listeners and is never the target. Under an interactive ancestor it is still picked, and the hit goes to that ancestor with this node's surface data. So one 'static' group makes its whole subtree clickable, with the group as target.
    • 'auto': as 'passive', but ray-tested even with no interactive ancestor, which costs time and finds no target. Prefer 'passive'.
    • 'static': picked against its hitVolume, and fires listeners.
    • 'dynamic': as 'static', and the View3D also picks again while a mouse or pen is still, so a node that moves under it gets its enter and leave events.

    The renderer's eventMode option only sets the default for 2D containers, and the View warns once when it isn't 'passive'. Picking costs time for each node that takes part, so set the mode on the nodes and groups that need it.

    'passive'
    
    button.eventMode = 'static';   // a clickable mesh
    spinner.eventMode = 'dynamic'; // it moves under a still pointer
    panel.eventMode = 'none'; // decoration; skip it and its children

    // A whole model that answers as one target; its meshes need no setup
    robot.eventMode = 'static';
    hitVolume: HitVolume3DInput

    Shape the pointer ray is tested against when picking this node, like hitArea in 2D

    Setting it doesn't make the node interactive; eventMode does that. Left null, a Mesh3D uses its geometry's bounding box and a plain Container3D has no shape, so it only hears events from its children.

    A shape you set also clips the node's descendants, as hitArea does in 2D: a descendant only hits where the hit point is inside every such shape above it, whatever those nodes' eventMode. A clipped hit doesn't block what is behind it. A Geometry3D clips by its bounding box, an IHitVolume3D only through its optional containsPoint, and the default bounding box never clips. A ray that misses a Box or Sphere shape, or a Geometry3D's bounding box, skips the exact test of every descendant under it.

    null
    
    mesh.interactive = true;                  // picked by its bounding box
    mesh.hitVolume = 'geometry'; // picked per triangle
    mesh.hitVolume = new Sphere(center, 0.4); // a cheaper or tighter shape
    mesh.hitVolume = null; // back to the bounding box

    // Children of the porthole only pick inside its sphere
    porthole.hitVolume = new Sphere(new Vector3(), 1);

    HitVolume3DInput For what each accepted value resolves to.

    intensity: number = 0

    Brightness, multiplied into Light.color

    Values above 1 are fine. A point or spot light dims with the square of the distance, so it needs a higher intensity than a directional light to look as bright. Lit colour brighter than 1 clips under the default toneMapping; a filmic curve such as 'aces' rolls it off instead.

    1, or 0.5 on an AmbientLight

    lamp.intensity = flicker ? 6 : 8;
    
    interactive: boolean

    Shorthand for eventMode, as on a pixi.js Container

    true sets 'static' and false sets 'passive'. It reads true for 'static' and 'dynamic'. false doesn't stop picking: under an interactive ancestor, a 'passive' node is still picked on that ancestor's behalf. Set eventMode = 'none' to take a node and its subtree out of picking.

    mesh.interactive = true;  // eventMode = 'static'
    mesh.interactive = false; // eventMode = 'passive'
    interactiveChildren: boolean

    Whether this node's descendants can be picked, as on a pixi.js Container

    false takes the whole subtree out of picking: descendants neither hit nor block what is behind them, and cost nothing per pointer event. The node itself still picks by its own eventMode and volume, so it can answer for the subtree.

    true
    
    menu.interactiveChildren = false; // nothing in the menu can be picked
    menu.interactiveChildren = true; // every button picks again, eventMode intact

    // One sphere answers for the whole robot: one ray test instead of one per mesh
    robot.eventMode = 'static';
    robot.hitVolume = new Sphere(new Vector3(), 2);
    robot.interactiveChildren = false;
    label: string | null = null

    Name to find the node by, with getChildByLabel

    Animation tracks find their target by it too. A plain Container3D starts with null; built-in subclasses such as Mesh3D start with their class name.

    turret.label = 'turret';
    tank.getChildByLabel('turret', true)?.lookAt(target);
    localTransform: Matrix4 = ...

    Local transform matrix, built from the position, rotation, scale and origin

    It catches up with changes in the view's transform pass, or when you call updateLocalTransform. Read it, but change the components instead: the next rebuild overwrites it.

    onclick: Pointer3DEventHandler | null

    Property-based handler for the click event

    Fired when a mouse click on this node completes, with any button but the right one.

    null
    
    mesh.eventMode = 'static';
    mesh.onclick = (e) => {
    if (e.hit3D) marker.position.copyFrom(e.hit3D.point);
    };

    IFederatedContainer3D#onpointertap For the equivalent for every pointer type.

    oncontextmenu: Pointer3DEventHandler | null

    Property-based handler for the contextmenu event

    Fired when the browser is about to open its context menu over this node; call preventDefault() to keep it closed.

    null
    
    mesh.oncontextmenu = (e) => {
    e.preventDefault();
    openMenuFor(mesh, e.global);
    };
    onglobalmousemove: Pointer3DEventHandler | null

    Property-based handler for the globalmousemove event

    Fired on every mouse move, wherever the pointer is on the page.

    null
    
    mesh.onglobalmousemove = (e) => {
    if (dragging) dragTo(e.global);
    };

    IFederatedContainer3D#onglobalpointermove For the equivalent for every pointer type.

    onglobalpointermove: Pointer3DEventHandler | null

    Property-based handler for the globalpointermove event

    Fired on every pointer move on the page, whether or not the pointer is over this node. The node still needs eventMode 'static' or 'dynamic' to hear it.

    null
    
    // Keep a drag going once the pointer runs off the dragged mesh
    mesh.onglobalpointermove = (e) => {
    const hit = dragging && view3d.screenToWorld(e.global, ground);
    if (hit) mesh.position.copyFrom(hit);
    };
    onglobaltouchmove: Pointer3DEventHandler | null

    Property-based handler for the globaltouchmove event

    Fired on every touch move, wherever the touch is on the page.

    null
    
    mesh.onglobaltouchmove = (e) => {
    if (dragging) dragTo(e.global);
    };

    IFederatedContainer3D#onglobalpointermove For the equivalent for every pointer type.

    onmousedown: Pointer3DEventHandler | null

    Property-based handler for the mousedown event

    Fired when a mouse button other than the right one goes down over this node.

    null
    
    mesh.onmousedown = (e) => {
    if (e.button === 1) startPan(e.global); // middle button
    };

    IFederatedContainer3D#onpointerdown For the equivalent for every pointer type.

    onmouseenter: Pointer3DEventHandler | null

    Property-based handler for the mouseenter event

    Fired when the mouse enters this node. Doesn't bubble.

    null
    
    mesh.onmouseenter = () => (tooltip.visible = true);
    

    IFederatedContainer3D#onpointerenter For the equivalent for every pointer type.

    onmouseleave: Pointer3DEventHandler | null

    Property-based handler for the mouseleave event

    Fired when the mouse leaves this node. Doesn't bubble.

    null
    
    mesh.onmouseleave = () => (tooltip.visible = false);
    

    IFederatedContainer3D#onpointerleave For the equivalent for every pointer type.

    onmousemove: Pointer3DEventHandler | null

    Property-based handler for the mousemove event

    Fired while the mouse moves across this node.

    null
    
    mesh.onmousemove = (e) => tooltip.position.copyFrom(e.global);
    

    IFederatedContainer3D#onpointermove For the equivalent for every pointer type.

    onmouseout: Pointer3DEventHandler | null

    Property-based handler for the mouseout event

    Fired when the mouse moves off this node. Bubbles, unlike mouseleave.

    null
    
    shelf.onmouseout = (e) => unhighlight(e.target3D);
    

    IFederatedContainer3D#onpointerout For the equivalent for every pointer type.

    onmouseover: Pointer3DEventHandler | null

    Property-based handler for the mouseover event

    Fired when the mouse moves onto this node. Bubbles, unlike mouseenter.

    null
    
    // One handler on the shelf hears every item on it
    shelf.onmouseover = (e) => highlight(e.target3D);

    IFederatedContainer3D#onpointerover For the equivalent for every pointer type.

    onmouseup: Pointer3DEventHandler | null

    Property-based handler for the mouseup event

    Fired when a mouse button other than the right one is released over this node.

    null
    
    mesh.onmouseup = (e) => {
    if (e.button === 1) endPan();
    };

    IFederatedContainer3D#onpointerup For the equivalent for every pointer type.

    onmouseupoutside: Pointer3DEventHandler | null

    Property-based handler for the mouseupoutside event

    Fired when a mouse button that went down on this node is released anywhere else.

    null
    
    mesh.onmouseupoutside = () => endPan();
    

    IFederatedContainer3D#onpointerupoutside For the equivalent for every pointer type.

    onpointercancel: Pointer3DEventHandler | null

    Property-based handler for the pointercancel event

    Never called: pixi delivers no pointer cancellation, in 2D either.

    null
    
    // End a drag on these two instead
    handle.onpointerup = endDrag;
    handle.onpointerupoutside = endDrag;
    onpointerdown: Pointer3DEventHandler | null

    Property-based handler for the pointerdown event

    Fired when a pointer goes down on this node: mouse, touch or pen alike.

    null
    
    handle.eventMode = 'static';
    handle.onpointerdown = (e) => {
    if (!e.hit3D) return;
    dragOffset.copyFrom(e.hit3D.localPoint); // where on the handle it was grabbed
    dragging = true;
    };
    onpointerenter: Pointer3DEventHandler | null

    Property-based handler for the pointerenter event

    Fired when a pointer enters this node. Doesn't bubble, so an ancestor hears it only when the pointer enters the ancestor itself.

    null
    
    button.eventMode = 'static';
    button.onpointerenter = () => button.scale.set(1.1);
    onpointerleave: Pointer3DEventHandler | null

    Property-based handler for the pointerleave event

    Fired when a pointer leaves this node. Doesn't bubble.

    null
    
    button.onpointerleave = () => button.scale.set(1);
    
    onpointermove: Pointer3DEventHandler | null

    Property-based handler for the pointermove event

    Fired while a pointer moves across this node.

    null
    
    // Trail the cursor across the surface it is over
    table.eventMode = 'static';
    table.onpointermove = (e) => {
    if (e.hit3D) cursorMarker.position.copyFrom(e.hit3D.point);
    };
    onpointerout: Pointer3DEventHandler | null

    Property-based handler for the pointerout event

    Fired when a pointer moves off this node. Bubbles, unlike pointerleave.

    null
    
    shelf.onpointerout = (e) => unhighlight(e.target3D);
    
    onpointerover: Pointer3DEventHandler | null

    Property-based handler for the pointerover event

    Fired when a pointer moves onto this node. Bubbles, unlike pointerenter.

    null
    
    // One handler on the shelf hears every item on it
    shelf.onpointerover = (e) => highlight(e.target3D);
    onpointertap: Pointer3DEventHandler | null

    Property-based handler for the pointertap event

    Fired when a pointer completes a tap on this node, for any pointer type and any button, right clicks included.

    null
    
    // Works for mouse, touch and pen alike
    mesh.eventMode = 'static';
    mesh.onpointertap = (e) => select(e.target3D);
    onpointerup: Pointer3DEventHandler | null

    Property-based handler for the pointerup event

    Fired when a pointer is released over this node.

    null
    
    handle.onpointerup = () => {
    dragging = false;
    };
    onpointerupoutside: Pointer3DEventHandler | null

    Property-based handler for the pointerupoutside event

    Fired when a pointer that went down on this node is released anywhere else. The event's target3D is the node that was pressed, and hit3D is what the pointer was released over.

    null
    
    // The release that ends a drag usually happens off the mesh
    handle.onpointerupoutside = () => {
    dragging = false;
    };
    onrightclick: Pointer3DEventHandler | null

    Property-based handler for the rightclick event

    Fired when a right click completes on this node.

    null
    
    mesh.onrightclick = () => openMenuFor(mesh);
    
    onrightdown: Pointer3DEventHandler | null

    Property-based handler for the rightdown event

    Fired when the right mouse button goes down over this node.

    null
    
    mesh.onrightdown = (e) => startRotate(e.global);
    
    onrightup: Pointer3DEventHandler | null

    Property-based handler for the rightup event

    Fired when the right mouse button is released over this node.

    null
    
    mesh.onrightup = endRotate;
    
    onrightupoutside: Pointer3DEventHandler | null

    Property-based handler for the rightupoutside event

    Fired when the right mouse button that went down on this node is released anywhere else.

    null
    
    mesh.onrightupoutside = endRotate;
    
    ontap: Pointer3DEventHandler | null

    Property-based handler for the tap event

    Fired when a touch completes a tap on this node. Chrome gives each touch a new pointerId, and detail only counts repeat taps by the same one, so it stays 1 there; time a double tap yourself.

    null
    
    let lastTap = 0;
    mesh.ontap = (e) => {
    if (e.timeStamp - lastTap < 300) focusOn(mesh); // double tap
    lastTap = e.timeStamp;
    };

    IFederatedContainer3D#onpointertap For the equivalent for every pointer type.

    ontouchcancel: Pointer3DEventHandler | null

    Property-based handler for the touchcancel event

    Never called: pixi delivers no touch cancellation, in 2D either.

    null
    
    // End a drag on these two instead
    handle.ontouchend = endDrag;
    handle.ontouchendoutside = endDrag;
    ontouchend: Pointer3DEventHandler | null

    Property-based handler for the touchend event

    Fired when a touch lifts off this node.

    null
    
    handle.ontouchend = endDrag;
    

    IFederatedContainer3D#onpointerup For the equivalent for every pointer type.

    ontouchendoutside: Pointer3DEventHandler | null

    Property-based handler for the touchendoutside event

    Fired when a touch that started on this node lifts off anywhere else.

    null
    
    handle.ontouchendoutside = endDrag;
    

    IFederatedContainer3D#onpointerupoutside For the equivalent for every pointer type.

    ontouchmove: Pointer3DEventHandler | null

    Property-based handler for the touchmove event

    Fired while a touch moves across this node.

    null
    
    canvasMesh.hitVolume = 'geometry'; // per triangle, so hits carry a uv
    canvasMesh.ontouchmove = (e) => {
    if (e.hit3D) paintAt(e.hit3D.uv);
    };

    IFederatedContainer3D#onpointermove For the equivalent for every pointer type.

    ontouchstart: Pointer3DEventHandler | null

    Property-based handler for the touchstart event

    Fired when a touch lands on this node.

    null
    
    handle.ontouchstart = (e) => startDrag(e.pointerId);
    

    IFederatedContainer3D#onpointerdown For the equivalent for every pointer type.

    onwheel: Wheel3DEventHandler | null

    Property-based handler for the wheel event

    Fired when the wheel turns while the pointer is over this node.

    null
    
    // Scroll to push the panel away from the camera
    panel.eventMode = 'static';
    panel.onwheel = (e) => {
    panel.position.z += e.deltaY * 0.01;
    };
    parent: Container3D | null = null

    Parent node, or null for a node with none, such as a view's root

    shadow: LightShadow

    This light's shadow settings; see LightShadow

    Change a field at any time and the shadow's next redraw uses it.

    sun.shadow.bias = 0.002;
    
    type: "ambient" = 'ambient'

    Always 'ambient'

    uid: number = ...

    Unique id, assigned at construction

    worldTransform: Matrix4 = ...

    World transform: the parent's world transform times this node's localTransform

    The view updates it once per frame, before drawing, for visible nodes only, and not at all while the view holds no mesh. So it can be out of date after a change this frame or while the node or an ancestor is hidden, and a node outside any view keeps the identity matrix. getGlobalTransform always works out a current one.

    defaultOptions: AmbientLightOptions = ...

    Defaults for every new AmbientLight; an option passed as undefined keeps its default

    AmbientLight.defaultOptions.intensity = 0.2;
    
    • get angle(): PointLike3D

      rotation in degrees, as in pixi.js

      It reads and writes rotation, so the two always agree. Reading converts back from radians, so a value can come back a hair off, such as 30 as 29.999999999999996; compare with a tolerance.

      Returns PointLike3D

      node.angle.y = 90; // same as node.rotation.y = Math.PI / 2
      node.angle = { x: 0, y: 45, z: 0 };
    • set angle(value: PointData3D): void

      Sets the Euler rotation and makes it the rotation in use, even when the values are unchanged

      Parameters

      Returns void

    • get canCastShadow(): boolean
      Advanced

      Always false: ambient light has no direction to cast along

      Returns boolean

    • get color(): Color

      Colour of the light, multiplied by Light.intensity

      Assign any ColorSource, in display (sRGB) space as everywhere in pixi, or change the returned Color in place.

      Returns Color

      0xffffff
      
      sun.color = 0xff9a4d;
      sun.color.setValue('#ffd8a8');
    • set color(value: ColorSource): void

      Sets the colour, copying the value into the light's own Color

      Parameters

      Returns void

    • get depth(): number

      Depth along local z: |scale.z| × local bounds depth

      Assigning writes scale.z only; see width.

      Returns number

      bench.depth = 0.5;
      
    • set depth(value: number): void

      Scales along z so the depth becomes value

      Parameters

      • value: number

        Target depth along z

      Returns void

    • get height(): number

      Height along local y: |scale.y| × local bounds height

      Assigning writes scale.y only; see width.

      Returns number

      tree.height = 6;
      
    • set height(value: number): void

      Scales along y so the height becomes value

      Parameters

      • value: number

        Target height along y

      Returns void

    • get origin(): ObservableVector3

      Point in local space that rotation and scale happen around, as in pixi.js

      Unlike a pivot, it leaves an unrotated, unscaled node where it is: the origin sits at position + origin in the parent. Assigning copies the values in, and a single number sets all three axes.

      Returns ObservableVector3

      // Tip a crate over its bottom-right edge without moving it first.
      crate.origin = { x: 0.5, y: -0.5, z: 0 };
      crate.angle.z = -90;
    • set origin(value: number | PointData3D): void

      Sets the origin; a number sets all three axes

      Parameters

      • value: number | PointData3D

        The new origin, in local space

      Returns void

    • get position(): ObservableVector3

      Local position

      Assigning copies the values in; the object itself never changes.

      Returns ObservableVector3

      node.position.set(0, 1, 0);
      node.position = { x: 0, y: 1, z: 0 };
    • set position(value: PointData3D): void

      Sets the local position

      Parameters

      Returns void

    • get quaternion(): ObservableQuaternion

      Local rotation as a unit quaternion; see rotation for which of the two is in use

      Assigning copies the values in, so node.quaternion = other.quaternion doesn't link the two.

      Returns ObservableQuaternion

      node.quaternion = other.quaternion;
      node.quaternion = { x: 0, y: Math.SQRT1_2, z: 0, w: Math.SQRT1_2 };
    • set quaternion(value: QuaternionData): void

      Sets the quaternion and makes it the rotation in use, even when the values are unchanged

      Parameters

      Returns void

    • get rotation(): ObservableVector3

      Local rotation as Euler angles in radians: turns around Z, then Y, then X, each about the parent's axes

      The node keeps both this and quaternion, and whichever you set last is the rotation in use. Assigning copies the values in. Writing unchanged values to either through a component, set or copyFrom doesn't switch which one is in use; assign it whole.

      Returns ObservableVector3

      node.rotation.y = Math.PI / 2;
      node.rotation = { x: 0, y: Math.PI / 2, z: 0 };
    • set rotation(value: PointData3D): void

      Sets the Euler rotation and makes it the rotation in use, even when the values are unchanged

      Parameters

      Returns void

    • get scale(): ObservableVector3

      Local scale

      Assigning copies the values in, and a single number scales all three axes; the object itself never changes.

      Returns ObservableVector3

      node.scale.set(2, 1, 1);
      node.scale = 2; // uniform
    • set scale(value: number | PointData3D): void

      Sets the local scale; a number sets all three axes

      Parameters

      Returns void

    • get visible(): boolean

      Whether this container and its descendants draw

      Hiding is cheap, and a hidden node stays in the scene; to take it out, remove it with removeChild. Emits visibleChanged when the value changes.

      Returns boolean

      door.visible = false;
      
    • set visible(value: boolean): void

      Shows or hides this container and its descendants

      Parameters

      • value: boolean

        Whether they draw

      Returns void

    • get width(): number

      Width along local x: |scale.x| × local bounds width

      Assigning writes scale.x only. To set several axes, setSize measures the bounds once instead of once per axis.

      Returns number

      crate.width = 2;
      
    • set width(value: number): void

      Scales along x so the width becomes value

      Parameters

      • value: number

        Target width along x

      Returns void

    • get worldVisible(): number

      1 when this node and every ancestor are visible, otherwise 0

      The view works it out once per frame, so it lags a visible change until the next render.

      Returns number

    • get x(): number

      Local position on the x axis; the same as position.x

      Returns number

      player.x += speed * dt;
      
    • set x(value: number): void

      Sets position.x

      Parameters

      • value: number

        The new x position

      Returns void

    • get y(): number

      Local position on the y axis; the same as position.y

      Returns number

      ball.y = Math.abs(Math.sin(time)) * 2;
      
    • set y(value: number): void

      Sets position.y

      Parameters

      • value: number

        The new y position

      Returns void

    • get z(): number

      Local position on the z axis; the same as position.z

      Returns number

      if (car.z > finishLine) finish();
      
    • set z(value: number): void

      Sets position.z

      Parameters

      • value: number

        The new z position

      Returns void

    • Adds one or more children to the end of this container's child list

      A child with another parent leaves it first. A child that is already here moves to the end, without events.

      Type Parameters

      Parameters

      • ...children: U

        The children to add

      Returns U[0]

      The first added child

      view.root.addChild(crate, lamp);
      
    • Adds child at index, or moves it there when it is already a child of this container

      A move within this container emits no events.

      Type Parameters

      Parameters

      • child: U

        The child to add or move

      • index: number

        The destination index

      Returns U

      The added child

      rack.addChildAt(sword, 0);
      

      When index is out of bounds.

    • Measures the scene again for the fitted shadow box on the next frame, then redraws the shadow

      A view with 256 shadow casters or fewer never needs this: the box is measured each time the shadow redraws. Past 256 it is measured once and kept, so call this after moving or spawning casters outside the box. Instances of a BatchedMesh3D count one each. For a cascaded light, a spot light, or a light with its own bounds, it only redraws the shadow, like Light.refreshShadows.

      Returns void

      spawnCity(); // 50k instanced casters: the fitted box was measured once and kept
      sun.fitShadowBounds(); // measure again so the new content is inside the box
    • Gets the child at index

      Type Parameters

      Parameters

      • index: number

        Index of the child to fetch

      Returns U

      The child at index

      const first = group.getChildAt(0);
      

      When index is out of bounds.

    • Returns the first child whose label matches, or null

      Each container checks its direct children before searching inside them. An unlabelled node never matches, even a pattern.

      Parameters

      • label: string | RegExp

        Exact label, or a pattern to test labels against

      • deep: boolean = false

        Whether to search the whole subtree, not only direct children

      Returns Container3D | null

      The first match, or null when nothing matches

      const wheel = car.getChildByLabel('wheel_front_left', true);
      const anyWheel = car.getChildByLabel(/^wheel_/, true);
    • Gets the index of child within this container

      Parameters

      Returns number

      The child's index

      const slot = rack.getChildIndex(sword);
      

      When child is not a child of this container.

    • Collects every child whose label matches, in the order Container3D.getChildByLabel visits them

      Parameters

      • label: string | RegExp

        Exact label, or a pattern to test labels against

      • deep: boolean = false

        Whether to search the whole subtree, not only direct children

      • out: Container3D[] = []

        Array the matches are appended to; a new one when omitted

      Returns Container3D[]

      out

      const wheels = car.getChildrenByLabel(/^wheel_/, true);
      
    • Returns this container's position in world space: parent.toGlobal(this.position), or a copy of position with no parent

      Parameters

      • out: Vector3 = ...

        Point the result is written into. Defaults to a new Vector3.

      • skipUpdate: boolean = false

        true to use the parent's cached world transform (see Container3D.getGlobalTransform); this node's own position is always read as it stands.

      Returns Vector3

      const screenPos = view3d.worldToScreen(mesh.getGlobalPosition());
      
    • Works out this container's current world transform into out

      It walks up the parent chain, so the result is right even before the view's transform pass has run this frame. With skipUpdate it copies the cached worldTransform instead, which is cheaper but can be stale.

      Parameters

      • out: Matrix4 = ...

        Matrix the result is written into. Defaults to a new Matrix4.

      • skipUpdate: boolean = false

        true to copy the cached world transform instead of recomputing.

      Returns Matrix4

      const world = mesh.getGlobalTransform();
      const localRay = ray.applyMatrix4(world.getInverse(world), new Ray());
    • Measures the bounding box of this container and its descendants, in this container's local space

      A subtree with a boundsVolume counts as that box. Hidden descendants are left out; this container counts whether or not it is visible. An empty subtree measures as a zero box at the origin. Each call walks the subtree, so cache the result if you need it every frame.

      Parameters

      • out: Box = ...

        Box to write into; a new one when omitted

      Returns Box

      out

      const bounds = model.getLocalBounds();
      const center = bounds.getCenter();
    • Returns the scaled size of this container, measuring the local bounds once

      Parameters

      • out: Size3D = ...

        Object to write into; a new one when omitted

      Returns Size3D

      The size, written into out

      const { width, height, depth } = model.getSize();
      
    • Whether this node fires listeners and can be an event target

      True for eventMode 'static' and 'dynamic', as in 2D.

      Returns boolean

      mesh.eventMode = 'dynamic';
      mesh.isInteractive(); // true

      mesh.eventMode = 'auto';
      mesh.isInteractive(); // false: hit-tested, but never the target
    • Advanced

      Prints this container's subtree to the console as an indented tree of ConstructorName "label" lines, for debugging

      Parameters

      • depth: number = 0

        Indentation level to start at; used by the recursion

      Returns void

      model.logHierarchy();
      
    • Turns this node so its forward axis, local +Z, points at a world-space target

      Cameras and lights aim local -Z instead. The node aims from position + origin, and uses the parent's current world transform, so a move earlier in the frame counts.

      Parameters

      • target: PointData3D

        World-space point to face

      • up: PointData3D = _lookAtDefaultUp

        World-space up reference; defaults to (0, 1, 0)

      Returns void

      turret.lookAt(enemy.getGlobalPosition());
      
    • Redraws this light's shadow on the next frame, whatever its LightShadow.update rate

      With update: 'manual', call it after each change the shadow should show. With a slower rate, call it after a change that shouldn't wait for the next scheduled redraw.

      Returns void

      sun.shadow.update = 'manual';
      // ...later, after the scene changes:
      sun.refreshShadows();
    • Removes one or more children from this container; a node that isn't a child is ignored

      Type Parameters

      Parameters

      • ...children: U

        The children to remove

      Returns U[0]

      The first child passed in

      view.root.removeChild(crate);
      
    • Removes the child at index

      Type Parameters

      Parameters

      • index: number

        Index of the child to remove

      Returns U

      The removed child

      const newest = queue.removeChildAt(queue.children.length - 1);
      

      When index is out of bounds.

    • Removes the children from beginIndex up to, but not including, endIndex

      Parameters

      • beginIndex: number = 0

        First index to remove

      • OptionalendIndex: number

        End of the range, exclusive; defaults to the child count

      Returns Container3D[]

      The removed children, last child first

      const debris = level.removeChildren();
      

      When beginIndex is negative or past endIndex, or equal to it while this container has children.

    • Removes this container from its parent, if it has one

      Returns void

      pickup.removeFromParent();
      
    • Moves one or more nodes under this container without moving them in the world; see reparentChildAt

      Type Parameters

      Parameters

      • ...child: U

        The children to reparent

      Returns U[0]

      The first reparented child

      hand.reparentChild(sword);
      
    • Moves child under this container at index without moving it in the world

      Its local position, rotation and scale change so that it renders where it did, and it keeps its origin. Unlike pixi, it uses current world transforms, so a move earlier in the frame counts. A child that is already here only changes index.

      Type Parameters

      Parameters

      • child: U

        The child to reparent

      • index: number

        The destination index

      Returns U

      The reparented child

      rack.reparentChildAt(sword, 0);
      
    • Replaces oldChild with newChild at the same index, copying oldChild's local position, rotation and scale onto newChild

      newChild keeps its own origin, and its position is solved so it sits exactly where oldChild did.

      Type Parameters

      Parameters

      • oldChild: U

        The child to replace

      • newChild: T

        The child that takes its place

      Returns void

      car.replaceChild(flatTyre, spareWheel);
      

      When oldChild is not a child of this container.

    • Moves an existing child to index within this container

      Parameters

      • child: Container3D

        The child to move

      • index: number

        The destination index

      Returns void

      rack.setChildIndex(sword, 0);
      

      When index is out of bounds or child is not a child of this container.

    • Rescales this container so its size matches the given width, height and depth

      A missing height or depth takes the width. An axis whose local extent is zero, such as a flat plane's depth, keeps a unit scale. The sign of each scale axis is kept, so a mirrored node stays mirrored.

      Parameters

      • value: number | Pick<Size3D, "width"> & Partial<Size3D>

        Target width, or an object with width and optional height / depth

      • Optionalheight: number

        Target height; defaults to the width

      • Optionaldepth: number

        Target depth; defaults to the width

      Returns void

      model.setSize(2); // stretch each axis to 2
      model.setSize(4, 2, 1);
      model.setSize({ width: 4, height: 2 }); // depth follows width: 4
    • Swaps the places of two children in this container's list

      Type Parameters

      Parameters

      • child: U

        The first child

      • child2: U

        The second child

      Returns void

      rack.swapChildren(sword, shield);
      

      When either argument is not a child of this container.

    • Converts a point into this container's local space

      Type Parameters

      Parameters

      • position: PointData3D

        The point to convert.

      • Optionalfrom: Container3D

        Container whose local space position is in. Defaults to world space.

      • Optionalout: T

        Point the result is written into. Defaults to a new Vector3.

      • skipUpdate: boolean = false

        true to use cached world transforms (see Container3D.getGlobalTransform).

      Returns T

      const targetFromTurret = turret.toLocal({ x: 0, y: 0, z: 0 }, target);
      
    • Calls callback with this container, then with every container under it, depth first

      Each container comes before its children, and hidden ones are visited too. A Skeleton's bones and a BatchedMesh3D's items aren't containers, so the walk doesn't reach them. It can't stop early or skip a subtree.

      The callback may remove, destroy or replace the container it's given. A container it adds with addChild is visited only if its new parent hasn't been visited yet. Other changes to the tree during the walk can skip a container or visit one twice.

      Parameters

      • callback: (container: Container3D) => void

        Called once with each container, this one first

      Returns void

      const robot = new Model3D(source);

      robot.traverse((container) => {
      if (container instanceof Mesh3D) container.enablePass('outline');
      });
    • Unloads the geometry of every mesh in this subtree, for a part of the scene you'll show again later

      Each mesh keeps its vertex data, so the next render that draws it uploads it again; remove the subtree from the scene first. Geometry3D.unload says what GPU memory that frees. Materials are left alone, since they're usually shared, except under a Model3D, which unloads its own; unload any other material yourself.

      Returns void

      view.root.removeChild(level);
      level.unload();
    • Advanced

      Rebuilds localTransform from the position, rotation, scale and origin

      The view calls it for each node that changed, so you only need it to read a current localTransform before the next frame. When rotation is the rotation in use, it updates the quaternion to match.

      Returns void

      crate.rotation.y = Math.PI / 4;
      crate.updateLocalTransform();
      const local = crate.localTransform.clone();