这个view主要展示ARKit如何检测平面。
首先指定ARWorldTrackingConfiguration的planeDetection属性。
ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
configuration.planeDetection = ARPlaneDetectionHorizontal;
[sceneView.session runWithConfiguration:configuration];
ARPlaneDetectionHorizontal 检测水平面
ARPlaneDetectionVertical 检测垂直面
我们使用ARSCNViewDelegate来捕获的视频帧图像和跟踪状态。
当ARkit发现一个新的平面会调用这个方法:
- (void)renderer:(id <SCNSceneRenderer>)renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor
{
}
我们需要判断这个事件是否是发现新平面
[anchor isMemberOfClass:[ARPlaneAnchor class]]
如果发现了新的平面,我们添加一个节点来渲染这个平面
ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor;
SCNBox *plane = [SCNBox boxWithWidth:planeAnchor.extent.x height:0 length:planeAnchor.extent.z chamferRadius:0];
plane.firstMaterial.diffuse.contents = [UIColor colorWithWhite:0.4 alpha:0.6];
SCNNode *planeNode = [SCNNode nodeWithGeometry:plane];
planeNode.position =SCNVector3Make(planeAnchor.center.x, 0, planeAnchor.center.z);
[node addChildNode:planeNode];
ARKit会在运行中不断修正已经发现的平面,当ARkit修正平面时会调用这个方法。
- (void)renderer:(id<SCNSceneRenderer>)renderer didUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
}
我们需要在这个方法中同步修正我们用来渲染的节点.
ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor;
SCNNode *planeNode=node.childNodes[0];
SCNBox *plane = (SCNBox *)planeNode.geometry;
plane.width=planeAnchor.extent.x;
plane.length=planeAnchor.extent.z;
planeNode.position=SCNVector3Make(planeAnchor.center.x, 0, planeAnchor.center.z);
完整代码:
@interface ARPlaneAnchorViewController ()<ARSCNViewDelegate>{
IBOutlet ARSCNView *sceneView;
}
@end
@implementation ARPlaneAnchorViewController
- (void)viewDidLoad {
[super viewDidLoad];
sceneView.delegate = self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
configuration.planeDetection = ARPlaneDetectionHorizontal;
[sceneView.session runWithConfiguration:configuration];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[sceneView.session pause];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - ARSCNViewDelegate
- (void)renderer:(id <SCNSceneRenderer>)renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
if ([anchor isMemberOfClass:[ARPlaneAnchor class]]) {
ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor;
SCNBox *plane = [SCNBox boxWithWidth:planeAnchor.extent.x height:0 length:planeAnchor.extent.z chamferRadius:0];
plane.firstMaterial.diffuse.contents = [UIColor colorWithWhite:0.4 alpha:0.6];
SCNNode *planeNode = [SCNNode nodeWithGeometry:plane];
planeNode.position =SCNVector3Make(planeAnchor.center.x, 0, planeAnchor.center.z);
[node addChildNode:planeNode];
}
}
- (void)renderer:(id<SCNSceneRenderer>)renderer didUpdateNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor{
if ([anchor isMemberOfClass:[ARPlaneAnchor class]]) {
ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor;
SCNNode *planeNode=node.childNodes[0];
SCNBox *plane = (SCNBox *)planeNode.geometry;
plane.width=planeAnchor.extent.x;
plane.length=planeAnchor.extent.z;
planeNode.position=SCNVector3Make(planeAnchor.center.x, 0, planeAnchor.center.z);
}
}
@end
网友评论