ARKit基础(三)——ARKit平面识别

2018-08-16  本文已影响0人  梁间

这个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
上一篇下一篇

猜你喜欢

热点阅读