首先介紹幾個經常出現的類
#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
複製程式碼