ARKit基本使用流程

1.准备工作,创建对象

@property (nonatomic, strong) ARSession *session;

//ARSessionConfigutation AR会话跟踪配置
@property (nonatomic, strong) ARSessionConfiguration *configuration;

//ARSCNView AR视图
@property (nonatomic, strong) ARSCNView *scnView;

//SCNNode 一个节点(模型)
@property (nonatomic, strong) SCNNode *planeNode;

这里通过懒加载分别创建前三个对象,节点在需要的时候再创建。

- (ARSession *)session {
    if (!_session) {
        _session = [[ARSession alloc] init];
        _session.delegate = self;
    }
    return _session;
}

//创建会话追踪配置
- (ARSessionConfiguration *)configuration {
    if (!_configuration) {

        ARWorldTrackingSessionConfiguration *worldConfiguration = [[ARWorldTrackingSessionConfiguration alloc] init];
        //设置检测平面,不需要检测的话不用设置
        worldConfiguration.planeDetection = ARPlaneDetectionHorizontal;

        _configuration = worldConfiguration;
        //设置自适应灯光
        _configuration.lightEstimationEnabled = YES;
    }
    return _configuration;
}
//创建AR视图
- (ARSCNView *)scnView {
    if (!_scnView) {
        _scnView = [[ARSCNView alloc] initWithFrame:self.view.bounds];

        _scnView.delegate = self;
        //指定会话
        _scnView.session = self.session;
        //自动调节灯光
        _scnView.automaticallyUpdatesLighting = YES;
        //显示状态信息
        _scnView.showsStatistics = YES;
        //设置debug选项,
        //ARSCNDebugOptionShowFeaturePoints 显示捕捉到的特征点(小黄点)
        //ARSCNDebugOptionShowWorldOrigin 显示世界坐标原点(相机位置,3D坐标系)
        _scnView.debugOptions = ARSCNDebugOptionShowFeaturePoints;
    }
    return _scnView;
}

2.显示视图,开启AR会话

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    //把AR视图添加到当前视图上
    [self.view addSubview:self.scnView];
    //运行AR会话,摄像头开始追踪现实场景
    [self.session runWithConfiguration:self.configuration];
}

3.添加节点

- (void)addNode {

    //通过场景来加载3D模型文件
    SCNScene *scene = [SCNScene sceneNamed:@"Models.scnassets/ship.scn"];

    //获取场景中的飞机节点
    SCNNode *node = scene.rootNode.childNodes[0];

    //设置节点的位置,单位是米 长宽高
    node.position = SCNVector3Make(0.1, 0.1, 0.1);
    //缩放
    node.scale = SCNVector3Make(0.5, 0.5, 0.5);
    self.planeNode = node;

    //添加到当前场景中
    [self.scnView.scene.rootNode addChildNode:node];

}

ARKit基本使用流程_第1张图片

4.检测平面

AR会话追踪配置中的设置:worldConfiguration.planeDetection = ARPlaneDetectionHorizontal;就是用来开启检测平面的功能的,目前只支持水平面的检测,不支持垂直平面。平面检测是根据摄像头采集到的特征点来判断的,当采集到足够多的特征点并且在同一水平面上,ARSession就会获取到一个ARPlaneAnchor(水平锚点,ARAnchor的子类,保存着水平面的位置信息),然后在这个锚点处添加一个节点,但这个节点是看不到的。通过ARSCNViewDelegate代理可以捕获这一事件。

//添加节点时候调用(当开启平地捕捉模式之后,如果捕捉到平地,ARKit会自动添加一个平地节点)
- (void)renderer:(id )renderer didAddNode:(SCNNode *)node forAnchor:(ARAnchor *)anchor
{

    if ([anchor isMemberOfClass:[ARPlaneAnchor class]]) {
        NSLog(@"捕捉到平地");

        //添加一个3D平面模型,ARKit只有捕捉能力,锚点只是一个空间位置,要想更加清楚看到这个空间,我们需要给空间添加一个平地的3D模型来渲染他

        //1.获取捕捉到的平地锚点
        ARPlaneAnchor *planeAnchor = (ARPlaneAnchor *)anchor;
        //2.创建一个3D物体模型 (系统捕捉到的平地是一个不规则大小的长方形,这里笔者将其变成一个长方形,并且是否对平地做了一个缩放效果)
        //参数分别是长宽高和圆角
        SCNBox *plane = [SCNBox boxWithWidth:planeAnchor.extent.x*0.3 height:0 length:planeAnchor.extent.x*0.3 chamferRadius:0];
        //3.使用Material渲染3D模型(默认模型是白色的,这里笔者改成红色)
        plane.firstMaterial.diffuse.contents = [UIColor redColor];

        //4.创建一个基于3D物体模型的节点
        SCNNode *planeNode = [SCNNode nodeWithGeometry:plane];
        //5.设置节点的位置为捕捉到的平地的锚点的中心位置 SceneKit框架中节点的位置position是一个基于3D坐标系的矢量坐标SCNVector3Make
        planeNode.position =SCNVector3Make(planeAnchor.center.x, 0, planeAnchor.center.z);

        //self.planeNode = planeNode;
        [node addChildNode:planeNode];


        //2.当捕捉到平地时,2s之后开始在平地上添加一个3D模型
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //1.创建一个花瓶场景
            SCNScene *scene = [SCNScene sceneNamed:@"Models.scnassets/vase/vase.scn"];
            //2.获取花瓶节点(一个场景会有多个节点,此处我们只写,花瓶节点则默认是场景子节点的第一个)
            //所有的场景有且只有一个根节点,其他所有节点都是根节点的子节点
            SCNNode *vaseNode = scene.rootNode.childNodes[0];

            //4.设置花瓶节点的位置为捕捉到的平地的位置,如果不设置,则默认为原点位置,也就是相机位置
            vaseNode.position = SCNVector3Make(planeAnchor.center.x, 0, planeAnchor.center.z);
            vaseNode.scale = SCNVector3Make(0.02, 0.02, 0.02);


            //5.将花瓶节点添加到当前屏幕中
            //!!!此处一定要注意:花瓶节点是添加到代理捕捉到的节点中,而不是AR试图的根节点。因为捕捉到的平地锚点是一个本地坐标系,而不是世界坐标系
            [node addChildNode:vaseNode];
        });
    }
}

ARKit基本使用流程_第2张图片

参考链接:http://www.chinaar.com/ARKit/5218.html

你可能感兴趣的:(ARKit)