初識ARKit

lijingpei2016發表於2018-05-17

首先介紹幾個經常出現的類

#ARSCNView

#ARSession

#ARWorldTrackingConfiguration

#SCNScene

#SCNNode


ARSCNView

用於顯示虛擬(3D模型)與現實(相機採集回來的資料)結合起來的view,傳統的UIView並不能直接顯示3D模型。

3D模型常常是.scn .dae .fbx格式

如果你建立了AR的工程 那麼工程裡會有一個小飛機的3D模型 在art.scnassets資料夾,名為ship.scn


#ARSession

是用於管理相機類和會話類的

裡面有不少代理方法 比如檢測平面的代理回撥


#ARWorldTrackingConfiguration 繼承ARConfiguration,但其更加專業

他可以設定一些場景的燈光效果、撲抓平面功能等

現在水平平面和豎直平面都可以檢測了


#SCNScene

它相當於一個容器,容器裡有很多的節點,其實每個節點可以存放一個3D模型。


#SCNNode 節點,它可以是在美工拿過來的模型(不規則),也可以是你自己用程式碼建立的模型(常常是規則的)


#ARKit

這個框架主要是管理相機和相機鋪抓到的畫面 給SceneKit提供座標和角度


#SceneKit

這個框架才是管理3D模型

如果你想用純程式碼建立一個AR工程,那麼你應該把系統自動在Main.storyboard建立的ARSCNView給去掉

具體程式碼如下

//
//  ViewController.m
//  第三次敲這個程式碼
//
//  Created by jp on 4/12/17.
//  Copyright © 2017年 poco. All rights reserved.
//

#import "ViewController.h"

//匯入框架
#import <ARKit/ARKit.h>
#import <SceneKit/SceneKit.h>

@interface ViewController () <ARSCNViewDelegate>

//檢視
@property(nonatomic, strong) ARSCNView * jpARSCNView;

//會話
@property(nonatomic, strong) ARSession * jpARSession;

//跟蹤會話
@property(nonatomic, strong) ARWorldTrackingConfiguration * jpARWTkConfiguration;

@end

    
@implementation ViewController


#pragma mark - 生命週期

- (void)viewDidLoad {
    [super viewDidLoad];

}

- (void)viewWillAppear:(BOOL)animated {
    
    [super viewWillAppear:animated];
    
    [self.view addSubview:self.jpARSCNView];
    
    //場景執行並且設定跟蹤會話
    [self.jpARSession runWithConfiguration:self.jpARWTkConfiguration];
    
    [self addNode];
    
}

- (void)viewWillDisappear:(BOOL)animated {
    
    [super viewWillDisappear:animated];
    
    self.jpARWTkConfiguration = nil;
    self.jpARSession = nil;
    self.jpARWTkConfiguration = nil;
    
}

#pragma mark - 私有方法

- (void)addNode{
    
    SCNScene * jpSCNScene1 = [SCNScene sceneNamed:@"cup.scnassets/candle/candle.scn"];
    SCNScene * jpSCNScene2 = [SCNScene sceneNamed:@"art.scnassets/ship.scn"];
    SCNScene * jpSCNScene3 = [SCNScene sceneNamed:@"AAA.scnassets/chair/chair.scn"];
    
    //建立容器的時候 自動建立了根節點
    SCNNode * planeNode1 = jpSCNScene1.rootNode.childNodes[0];
    SCNNode * planeNode2 = jpSCNScene2.rootNode.childNodes[0];
    SCNNode * planeNode3 = jpSCNScene3.rootNode.childNodes[0];

    //設定位置
    planeNode1.position = SCNVector3Make(-0.5, -1, -1);
    planeNode2.position = SCNVector3Make(0, -1, -1);
    planeNode3.position = SCNVector3Make(1, -1, -1);

    //設定節點
    [self.jpARSCNView.scene.rootNode addChildNode:planeNode1];
    [self.jpARSCNView.scene.rootNode addChildNode:planeNode2];
    [self.jpARSCNView.scene.rootNode addChildNode:planeNode3];
}


#pragma mark - 訪問器方法

- (ARSCNView *)jpARSCNView {
    
    if (_jpARSCNView == nil) {
        _jpARSCNView = [[ARSCNView alloc]init];
        _jpARSCNView.frame = self.view.frame;
        _jpARSCNView.session = self.jpARSession;
        _jpARSCNView.automaticallyUpdatesLighting = YES;
        
    }
    
    return _jpARSCNView;
}

- (ARSession *)jpARSession {
    
    if (_jpARSession == nil) {
        _jpARSession = [[ARSession alloc]init];
    }
    
    return _jpARSession;
    
}

- (ARWorldTrackingConfiguration *)jpARWTkConfiguration {
    
    if (_jpARWTkConfiguration == nil) {
        _jpARWTkConfiguration = [[ARWorldTrackingConfiguration alloc]init];
        _jpARWTkConfiguration.planeDetection = ARPlaneDetectionHorizontal;
        _jpARWTkConfiguration.lightEstimationEnabled = YES;
    
    }
    
    return _jpARWTkConfiguration;
    
}

@end

複製程式碼

程式碼