平面检测
与网格检测类似,平面检测提供现实表面的平面估计。
各平面可带 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
});