# Objects and shapes

> Reference for the built-in shapes (Box, Sphere, Cylinder, Cone, Plane, Torus, Capsule), Mesh, Group and Primitive: every prop, default and orientation, the shared shape props, transform props, SceneObject refs and the Vec3 type.

```ts
import { Box, Capsule, Cone, Cylinder, Group, Mesh, Plane, Primitive, Sphere, Torus } from "@apricot/react";
import type { SceneObject, Vec3 } from "@apricot/react";
```

## Transform props

Every object (shapes, `Mesh`, `Group`, `Primitive`, `Instances`, `Model`) takes:

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `position` | `Vec3` or shared value | `[0, 0, 0]` | Relative to the parent, in units (metres) |
| `rotation` | `Vec3` or shared value | `[0, 0, 0]` | Euler angles in **radians**, XYZ order |
| `scale` | `number \| Vec3` or shared value | `1` | One number for all axes, or per axis |

`type Vec3 = readonly [number, number, number]`. Shared values are read every frame without React renders; type them with `useDerivedValue<readonly [number, number, number]>(…)`.

## Shared shape props

Every shape and `Mesh` takes:

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `material` | `MaterialInput` | `"standard"` | A preset name, `{ preset, ...options }`, or a three.js material (yours: not disposed). See [Materials](https://matthiasbrandolin.dev/apricot/reference/materials) |
| `color` | colour | the preset's | Overrides the preset's colour. Changes animate |
| `onPress` | `(hit: PressHit) => void` | | Called when the object is tapped |
| `name` | `string` | `""` | The three.js object's name |
| `visible` | `boolean` | `true` | Hides the object (and its children) |
| `castShadow`, `receiveShadow` | `boolean` | decided by the scene | Overrides with `<Scene shadows>` |
| `ref` | `Ref<SceneObject>` | | The three.js mesh |
| `children` | `ReactNode` | | Nested objects, placed relative to this one |

`PressHit`: `{ mesh, material, materialIndex, point, distance, instanceId }`. `point` is the world-space `Vector3` hit; `distance` is from the camera.

## Shapes

All shapes are centred on their position.

| Component | Props (default) | Orientation |
| --- | --- | --- |
| `Box` | `size` number or `[w, h, d]` (`1`), `radius` edge rounding (`0`) | Axis-aligned |
| `Sphere` | `radius` (`0.5`), `segments` (`32`) | |
| `Cylinder` | `radius` (`0.5`), `radiusTop` (= `radius`), `height` (`1`), `segments` (`32`) | Stands along y |
| `Cone` | `radius` (`0.5`), `height` (`1`), `segments` (`32`) | Points up (+y) |
| `Plane` | `size` number or `[w, h]` (`1`) | Faces **+z**. For a floor: `rotation={[-Math.PI / 2, 0, 0]}` |
| `Torus` | `radius` centre to tube middle (`0.5`), `tube` thickness (`0.15`), `segments` (`48`) | Ring in the xy plane (faces +z) |
| `Capsule` | `radius` (`0.3`), `length` straight middle (`0.6`), `segments` (`16`) | Along y. Total height = `length + 2 * radius` |

Changing a size prop rebuilds the geometry; shapes free their geometry on unmount. To animate size, animate `scale` instead.

## `Mesh`

| Prop | Type | Description |
| --- | --- | --- |
| `geometry` | `THREE.BufferGeometry` (required) | The shape. Yours: not disposed by the mesh |

Plus the shared shape props and transform props. See [Custom geometry](https://matthiasbrandolin.dev/apricot/guides/custom#your-own-geometry-mesh).

## `Group`

An empty node that transforms its children together.

| Prop | Type | Description |
| --- | --- | --- |
| `name` | `string` | |
| `ref` | `Ref<SceneObject>` | The three.js group, for `<FollowCamera target>`, `<Label attach>`, `<CameraRig follow>` |
| `children` | `ReactNode` | |

Plus transform props.

## `Primitive`

Adds an existing three.js object as it is.

| Prop | Type | Description |
| --- | --- | --- |
| `object` | `THREE.Object3D` (required) | Any three.js object. Yours: dispose it yourself (`disposeObject`) |
| `ref` | `Ref<SceneObject>` | The same object |
| `children` | `ReactNode` | Nested under the object |

Plus transform props. Transform props overwrite the object's own position, rotation and scale only when given.

## `SceneObject`

`type SceneObject = THREE.Object3D`: what a `ref` on `Box`, `Group`, `Model`, `Vehicle`, `FollowPath` or a light holds. Read or change its `position`, `rotation`, `scale` and `visible` directly, then call `useScene().invalidate()` if you changed it outside `useFrame`.

```tsx
const box = useRef<SceneObject>(null);
<Box ref={box} />
```

## Related

- [Objects and lifetime](https://matthiasbrandolin.dev/apricot/concepts/objects).
- [Shapes and materials](https://matthiasbrandolin.dev/apricot/guides/shapes-and-materials).
- [Coordinates and units](https://matthiasbrandolin.dev/apricot/concepts/coordinates).
