# XrPlane

Class · extends [`EventHandler`](https://api.playcanvas.com/engine/classes/EventHandler.md) · category: XR

Source: https://github.com/playcanvas/engine/blob/f059dc005842f76e052cdf44d8370c8c7ec475ac/src/framework/xr/xr-plane.js#L19

Represents a detected plane in the real world, providing its position, rotation, polygon points,
and semantic label. The plane data may change over time as the system updates its understanding
of the environment. Instances of this class are created and managed by the
[XrPlaneDetection](https://api.playcanvas.com/engine/classes/XrPlaneDetection.md) system.

## Accessors

### id

```ts
get id(): number
```

Unique identifier of a plane.

### label

```ts
get label(): string
```

Gets the semantic label of the plane provided by the underlying system. The label describes
the type of surface the plane represents, such as "floor", "wall", "ceiling", etc. The list
of possible labels can be found in the [semantic labels repository](https://github.com/immersive-web/semantic-labels).

**Example**

```ts
if (plane.label === 'floor') {
    console.log('This plane represents the floor.');
} else if (plane.label === 'wall') {
    console.log('This plane represents a wall.');
}
```

### orientation

```ts
get orientation(): "horizontal" | "vertical" | null
```

Gets the plane's specific orientation. This can be "horizontal" for planes that are parallel
to the ground, "vertical" for planes that are perpendicular to the ground, or `null` if the
orientation is different or unknown.

**Example**

```ts
if (plane.orientation === 'horizontal') {
    console.log('This plane is horizontal.');
} else if (plane.orientation === 'vertical') {
    console.log('This plane is vertical.');
} else {
    console.log('Orientation of this plane is unknown or different.');
}
```

### points

```ts
get points(): DOMPointReadOnly[]
```

Gets the array of points that define the polygon of the plane in its local coordinate space.
Each point is represented as a `DOMPointReadOnly` object with `x`, `y`, and `z` properties.
These points can be transformed to world coordinates using the plane's position and
rotation.

**Example**

```ts
// prepare reusable objects
const transform = new Mat4();
const vecA = new Vec3();
const vecB = new Vec3();

// update Mat4 to plane position and rotation
transform.setTRS(plane.getPosition(), plane.getRotation(), Vec3.ONE);

// draw lines between points
for (let i = 0; i < plane.points.length; i++) {
    vecA.copy(plane.points[i]);
    vecB.copy(plane.points[(i + 1) % plane.points.length]);

    // transform points to world space
    transform.transformPoint(vecA, vecA);
    transform.transformPoint(vecB, vecB);

    // render line
    app.drawLine(vecA, vecB, Color.WHITE);
}
```

## Methods

### getPosition

```ts
getPosition(): Vec3
```

Get the world space position of a plane.

**Returns** [`Vec3`](https://api.playcanvas.com/engine/classes/Vec3.md): The world space position of a plane.

### getRotation

```ts
getRotation(): Quat
```

Get the world space rotation of a plane.

**Returns** [`Quat`](https://api.playcanvas.com/engine/classes/Quat.md): The world space rotation of a plane.

## Events

### EVENT_CHANGE

```ts
static EVENT_CHANGE: string = 'change'
```

Fired when [XrPlane](https://api.playcanvas.com/engine/classes/XrPlane.md) attributes such as: orientation and/or points have been changed.
Position and rotation can change at any time without triggering a `change` event.

**Example**

```ts
plane.on('change', () -> {
    // plane has been changed
});
```

### EVENT_REMOVE

```ts
static EVENT_REMOVE: string = 'remove'
```

Fired when an [XrPlane](https://api.playcanvas.com/engine/classes/XrPlane.md) is removed. Its attributes, such as its points and label, keep
their last values.

**Example**

```ts
plane.once('remove', () => {
    // plane is not available anymore
});
```

## Inherited from [EventHandler](https://api.playcanvas.com/engine/classes/EventHandler.md)

- `fire(name: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any, arg6?: any, arg7?: any, arg8?: any): EventHandler`
- `hasEvent(name: string): boolean`
- `off(name?: string, callback?: HandleEventCallback, scope?: any): EventHandler`
- `on(name: string, callback: HandleEventCallback, scope?: any): EventHandle`
- `once(name: string, callback: HandleEventCallback, scope?: any): EventHandle`
