跳到主要内容

平面检测

与网格检测类似,平面检测提供现实表面的平面估计。

各平面可带 wall、floor、table 等可选标签。

可使用预先捕获数据或实时重建,取决于系统实现。

支持​

if (app.xr.planeDetection.supported) {
// plane detection is supported
}

app.xr.on('start', () => {
if (app.xr.planeDetection.available) {
// plane detection is available
}
});

访问​

启动会话时添加功能标志:

app.xr.start(camera, pc.XRTYPE_AR, pc.XRSPACE_LOCALFLOOR, {
planeDetection: true
});

平面异步添加和移除:

app.xr.planeDetection.on('add', (xrPlane) => {
// a new XrPlane has been added

xrPlane.once('remove', () => {
// an XrPlane has been removed
});
});

也可读取 XrPlane 列表:

const xrPlanes = app.xr.planeDetection.meshes;
for (let i = 0; i < xrPlanes.length; i++) {
const xrPlane = xrPlanes[i];
}

网格​

平面由 XrPlane 表示,会话期间可增删,数据也可变化。

读取世界空间位置和旋转:

entity.setPosition(xrPlane.getPosition());
entity.setRotation(xrPlane.getRotation());

局部点和朝向可构建可视网格,点列表表示多边形轮廓顶点。

xrPlane.orientation 表示垂直、水平或其他方向。

以下为每个平面构建网格并添加到场景根:

app.xr.planeDetection.on('add', (xrPlane) => {
// geometry data
const mesh = new pc.Mesh(app.graphicsDevice);
mesh.clear(true, true); // ensure that mesh is created with dynamic buffers

// create a list of vertices
const vertices = new Float32Array((xrPlane.points.length + 1) * 3);

// first point is always in the origin
vertices[0] = 0;
vertices[1] = 0;
vertices[2] = 0;

// create a list of indices
const indices = new Uint32Array(xrPlane.points.length * 3);

// construct a polygon where each edge is connected to the origin of a mesh
for (let i = 0; i < xrPlane.points.length; i++) {
vertices[i * 3 + 3 + 0] = xrPlane.points[i].x;
vertices[i * 3 + 3 + 1] = xrPlane.points[i].y;
vertices[i * 3 + 3 + 2] = xrPlane.points[i].z;
indices[i * 3 + 0] = 0;
indices[i * 3 + 1] = i + 1;
indices[i * 3 + 2] = ((i + 1) % xrPlane.points.length) + 1;
}

mesh.setPositions(vertices); // set vertices
mesh.setNormals(pc.calculateNormals(vertices, indices)); // calculate normals
mesh.setIndices(indices); // set indices
mesh.update(pc.PRIMITIVE_TRIANGLES); // update buffers

const material = new pc.StandardMaterial();
const meshInstance = new pc.MeshInstance(mesh, material);

const entity = new pc.Entity(xrPlane.label);

// add render component
entity.addComponent('render', {
meshInstances: [ meshInstance ]
});

// add entity to the scene root
app.root.addChild(entity);

// clean up after XrPlane is removed
xrPlane.once('remove', () => {
material.destroy();
mesh.destroy();
entity.destroy();
});
});

语义标签​

XrPlane.label 有助于识别现实对象类型。

例如 floor、wall、door、window、table、screen、global mesh、other 等。标签列表并非最终限制,平台可以返回其他标签。

变化​

底层支持时,属性会在会话期间更新,可监听并同步网格:

xrPlane.on('change', () => {
// points and/or label have been changed
});