UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

164 lines (161 loc) 5.69 kB
import { EventHandler } from '../../core/event-handler.js'; import { Quat } from '../../core/math/quat.js'; import { Vec3 } from '../../core/math/vec3.js'; /** * @import { XrPlaneDetection } from './xr-plane-detection.js' */ var ids = 0; /** * 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 * {@link XrPlaneDetection} system. * * @category XR */ class XrPlane extends EventHandler { /** @ignore */ destroy() { if (!this._xrPlane) return; this._xrPlane = null; this.fire('remove'); } /** * @param {XRFrame} frame - XRFrame from requestAnimationFrame callback. * @ignore */ update(frame) { var manager = this._planeDetection._manager; var pose = frame.getPose(this._xrPlane.planeSpace, manager._referenceSpace); if (pose) { this._position.copy(pose.transform.position); this._rotation.copy(pose.transform.orientation); } // has not changed if (this._lastChangedTime !== this._xrPlane.lastChangedTime) { this._lastChangedTime = this._xrPlane.lastChangedTime; // attributes have been changed this.fire('change'); } } /** * Get the world space position of a plane. * * @returns {Vec3} The world space position of a plane. */ getPosition() { return this._position; } /** * Get the world space rotation of a plane. * * @returns {Quat} The world space rotation of a plane. */ getRotation() { return this._rotation; } /** * Unique identifier of a plane. * * @type {number} */ get id() { return this._id; } /** * 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. * * @type {"horizontal"|"vertical"|null} * @example * 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.'); * } */ get orientation() { return this._orientation; } /** * 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. * * @type {DOMPointReadOnly[]} * @example * // prepare reusable objects * const transform = new pc.Mat4(); * const vecA = new pc.Vec3(); * const vecB = new pc.Vec3(); * * // update Mat4 to plane position and rotation * transform.setTRS(plane.getPosition(), plane.getRotation(), pc.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, pc.Color.WHITE); * } */ get points() { return this._xrPlane.polygon; } /** * 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). * * @type {string} * @example * if (plane.label === 'floor') { * console.log('This plane represents the floor.'); * } else if (plane.label === 'wall') { * console.log('This plane represents a wall.'); * } */ get label() { return this._xrPlane.semanticLabel || ''; } /** * Create a new XrPlane instance. * * @param {XrPlaneDetection} planeDetection - Plane detection system. * @param {*} xrPlane - XRPlane that is instantiated by WebXR system. * @ignore */ constructor(planeDetection, xrPlane){ super(), /** * @type {Vec3} * @private */ this._position = new Vec3(), /** * @type {Quat} * @private */ this._rotation = new Quat(); this._id = ++ids; this._planeDetection = planeDetection; this._xrPlane = xrPlane; this._lastChangedTime = xrPlane.lastChangedTime; this._orientation = xrPlane.orientation; } } /** * Fired when an {@link XrPlane} is removed. * * @event * @example * plane.once('remove', () => { * // plane is not available anymore * }); */ XrPlane.EVENT_REMOVE = 'remove'; /** * Fired when {@link XrPlane} attributes such as: orientation and/or points have been changed. * Position and rotation can change at any time without triggering a `change` event. * * @event * @example * plane.on('change', () -> { * // plane has been changed * }); */ XrPlane.EVENT_CHANGE = 'change'; export { XrPlane };