首先,配置文件设置成水平平地,目前暂时只支持水平的,垂直的貌似还不支持,期待正式版。
configuration.planeDetection = .horizontal
捕到平地后,通过代理拿到当前平地的信息,代码如下:
//添加节点时候调用(当开启平地捕捉模式之后,如果捕捉到平地,ARKit会自动添加一个平地节点)
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
if anchor.isMember(of: ARPlaneAnchor.self){
//通过anchor建一个SCNPlane向量
myPlane = plane(anchor: anchor as! ARPlaneAnchor)
//加入到平地node里
node.addChildNode(myPlane)
}
}
在这里,捕获到平地后,返回2个数据:
SCNNode:当前平地的node.
ARAnchor:平地的向量坐标,该向量虽然是vector_float3类型,其实只是(X,Z)的二维平面,Y轴一直为0,需要注意的是平地探测会不断变化,所以下面这几个值会一直变化,有几个很重要的属性:
center:平地向量的中心点。
extent:vector_float3向量,其中Y为0.
在平地被探测的时候,添加一个SCNPlane。
//根据平地向量的长度,宽度,初始化一个平面形状
self.planeGeometry = SCNPlane.init(width: CGFloat(self.anchor.extent.x), height: CGFloat(self.anchor.extent.z))
//通过平面形状初始化一个SCNNode
let planeNode:SCNNode = SCNNode.init(geometry: self.planeGeometry)
//把中心点设置在平面的中心
planeNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z)
//SCNPlane是位于(X,Y)轴的,需要旋转到(X,Z) 轴
planeNode.transform = SCNMatrix4MakeRotation(-.pi/2, 1.0, 0, 0)
//添加到平地的Node上
self.addChildNode(planeNode)
需要注意的是,平地探测会一直变化,所以我们需要持续监听,更改平面的宽高和中心点:
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
//更改宽
self.planeGeometry.width = CGFloat(anchor.extent.x);
//更改高
self.planeGeometry.height = CGFloat(anchor.extent.z);
//更改中心点
self.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);
//由于渲染了纹理,需要拉伸纹理。
self.setTextureScale();
}
水平有限,欢迎大家提出意见:
demo地址
网友评论