The scene tree#
Components inside <Scene> form a tree, like views. Each object is attached to its closest parent object, and its position, rotation and scale are relative to that parent.
import { Box, Group, Scene, Sphere } from "@apricot/react";
export function Tree() {
return (
<Scene style={{ flex: 1 }}>
{/* Moving or turning the group moves both children together. */}
<Group position={[0, -0.5, 0]} rotation={[0, Math.PI / 6, 0]}>
<Box size={[2, 0.2, 1]} />
<Sphere radius={0.3} position={[0, 0.45, 0]} material="chrome" />
</Group>
</Scene>
);
}These components are objects and accept children: Group, Mesh and every shape, Model, Primitive, Vehicle, FollowPath, and behaviors such as Spin (which wrap their children in a group).
Ordinary React components can sit anywhere in the tree: an object inside them still attaches to the closest object above it.
Refs: SceneObject#
A ref on an object holds a SceneObject, the underlying three.js Object3D. Use it to read or change the object directly, or to hand it to a component that follows it.
import { Box, FollowCamera, Group, Scene, type SceneObject, useFrame } from "@apricot/react";
import { useRef } from "react";
function Runner() {
const runner = useRef<SceneObject>(null);
useFrame(({ time }) => {
if (!runner.current) return true;
runner.current.position.z = -time * 2; // runs away from the camera
return true;
});
return (
<>
<Group ref={runner}>
<Box size={[0.5, 1, 0.5]} position={[0, 0.5, 0]} />
</Group>
{/* After the target, so it reads this frame's position. */}
<FollowCamera target={runner} />
</>
);
}
export function Refs() {
return (
<Scene style={{ flex: 1 }}>
<Runner />
</Scene>
);
}What you can do with a SceneObject:
| Use | How |
|---|---|
| Move, turn, scale | ref.current.position.set(x, y, z), .rotation.y = a, .scale.setScalar(s) |
| Hide | ref.current.visible = false |
| Read where it is in the world | ref.current.getWorldPosition(vector) |
| Follow it with the camera | <FollowCamera target={ref}>, <CameraRig follow={ref}> |
| Pin a label to it | <Label attach={ref}> |
<Instances> refs are different: they hold an InstancesHandle with group and set(index, item). <CameraRig> refs hold a CameraRigHandle with flyTo and jumpTo.
Groups#
<Group> is an empty object that transforms its children together. Use it to:
- place several shapes as one object;
- apply a second motion on top of another (a swipe
rotationinside a<Spin>); - set a pivot point: put the child off-centre inside a group, then rotate the group.
import { Box, Group, Scene, Spin } from "@apricot/react";
export function Pivot() {
return (
<Scene style={{ flex: 1 }}>
<Spin speed={1} axis={[0, 0, 1]}>
{/* The arm turns around its left end, not its centre. */}
<Group>
<Box size={[2, 0.2, 0.2]} position={[1, 0, 0]} />
</Group>
</Spin>
</Scene>
);
}Visibility, names and order#
visible={false}on a shape hides it without unmounting it, and keeps its material and shader.namesets the object's name: useful in model selectors and debugging.- Unmounting a component removes its object and frees what it created.
- Draw order does not depend on the order in JSX: depth decides what is in front.
Who frees what#
| Thing | Created by | Freed when |
|---|---|---|
Shape geometry (<Box size>…) |
Apricot | The shape unmounts or its size changes |
Preset materials (material="chrome") |
Apricot, shared between identical uses | The last component using it unmounts |
A geometry you pass to <Mesh> or <Instances> |
You | Never by Apricot: dispose it yourself (geometry.dispose() in an effect cleanup) |
A three.js material you pass |
You | Never by Apricot |
Models (<Model src>) and textures (useTexture) |
Apricot, cached per app | The last user unmounts |
Objects you create with @apricot/assets factories (createPeach()…) |
You | Call disposeObject(object) from @apricot/core |
Escape hatch: three.js objects#
<Primitive object={…}> adds any existing three.js Object3D to the scene, with the usual position, rotation, scale and children. Use it for objects built by @apricot/assets factories or your own three.js code. Most apps never need it: see Custom geometry and behaviors.
Related#
- Objects reference:
Group,Primitive,Meshand shapes. - Coordinates and units.