iOS11出來(lái)也有一段時(shí)間了,其中ARKit框架還是比較有吸引力的荐操。就想用點(diǎn)時(shí)間學(xué)習(xí)一下芜抒,來(lái)做點(diǎn)好玩的東西。畢竟有難度必有所得嘛托启。
既然有方向了宅倒,那就給自己一個(gè)目標(biāo)吧,這樣學(xué)習(xí)起來(lái)才有動(dòng)力和目的屯耸。我的目標(biāo)就是使用ARKit框架實(shí)現(xiàn)類似于湯姆貓說(shuō)話拐迁,在我們公司移動(dòng)辦公平臺(tái)智能語(yǔ)音聊天的基礎(chǔ)上,實(shí)現(xiàn)虛擬現(xiàn)實(shí)中和一個(gè)小人進(jìn)行聊天疗绣。
這一章主要講基礎(chǔ)知識(shí)唠亚,來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的AR中添加一個(gè)正方形。
參考文章:
跨越屏幕的界限持痰,蘋果 ARKit 初探
良心教程:用戶交互的黑科技ARKit
設(shè)備要求
要運(yùn)行ARKit灶搜,在硬件上需要具備A9及以上的處理器,也就是iPhone6s以上的手機(jī)才可以支持AR。
我們?cè)谧龀绦驎r(shí)割卖,最好判斷是否支持ARKit前酿,如果你的項(xiàng)目就是基于ARKit的,可以在Required Device capabilities中添加如下UIRequiredDeviceCapabilities:
如果設(shè)備不支持的話就會(huì)顯示這個(gè):
如果ARKit只是程序的一部分鹏溯,就要使用isSupport來(lái)判斷加載罢维。
//在viewDidAppear中添加
guard ARWorldTrackingConfiguration.isSupported else {
fatalError("""
ARKit is not available on this device. For apps that require ARKit for core functionality, use the `arkit` key in the key in the `UIRequiredDeviceCapabilities` section of the Info.plist to prevent the app from installing. (If the app can't be installed, this error can't be triggered in a production scenario.) In apps where AR is an additive feature, use `isSupported` to determine whether to show UI for launching AR experiences. """) // For details, see https://developer.apple.com/documentation/arkit
}
軟件要求
需要運(yùn)行xcode 9.0 和 IOS 11 SDK
1. AR工作流程
其中藍(lán)色表示 ARKit 負(fù)責(zé)的部分,綠色表示 SceneKit 負(fù)責(zé)的部分丙挽。當(dāng)然肺孵,建立虛擬世界也可以使用其他的框架,比如 SpriteKit颜阐、Metal平窘,本文將以 SceneKit 為例子進(jìn)行講解。
- 首先凳怨,ARKit 利用攝像頭拍攝現(xiàn)實(shí)場(chǎng)景的畫面瑰艘,然后 SceneKit 用來(lái)建立虛擬世界。
- 建立好了以后肤舞,ARKit 負(fù)責(zé)將現(xiàn)實(shí)世界和虛擬世界的信息融合紫新,并渲染出一個(gè) AR 世界。
- 在渲染的同時(shí)李剖,ARKit 要負(fù)責(zé)以下三件事:
- 維持世界追蹤芒率。指的是當(dāng)你移動(dòng)攝像頭,要去獲取新的現(xiàn)實(shí)世界的信息篙顺。
- 進(jìn)行場(chǎng)景解析敲董。指的是解析現(xiàn)實(shí)世界中有無(wú)特征點(diǎn)、平面等關(guān)鍵信息慰安。
- 處理與虛擬世界的互動(dòng)腋寨。指的是當(dāng)用戶點(diǎn)擊或拖動(dòng)屏幕時(shí),處理有沒(méi)有點(diǎn)擊到虛擬物體或者要不要進(jìn)行添加/刪除物體的操作化焕。
2. ARKit 和 SceneKit 關(guān)系圖
這些類可以查看第一個(gè)參考文章萄窜,我也是記錄一下,方便以后查看
3 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的demo
- 創(chuàng)建一個(gè)ARDemo的project, 基于swift語(yǔ)言
- 在Info.plist中添加Camera Usage Description的相機(jī)權(quán)限撒桨。
- 點(diǎn)擊main.storyboard 中查刻,在Object Library中選擇ARKit SceneKit View,如下:
- 把ARKit SceneKit View拖到ViewController中,如下圖:
- 在ViewController.m中凤类,添加 import ARKit , 代碼如下:
class ViewController: UIViewController {
@IBOutlet weak var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
addBox() //添加一個(gè)立方體
addTapGestureToSceneView() //添加一個(gè)點(diǎn)擊手勢(shì)穗泵,可以根據(jù)手勢(shì)的坐標(biāo)來(lái)進(jìn)行立方體的拖動(dòng)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARWorldTrackingConfiguration() //初始化一個(gè)名為AR的配置,進(jìn)行世界跟蹤的配置,用來(lái)跟蹤設(shè)備的方向和位置谜疤。也可以通過(guò)設(shè)備的相機(jī)檢測(cè)現(xiàn)實(shí)世界的表面佃延。
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause() //停止跟蹤視圖內(nèi)容的運(yùn)動(dòng)和處理圖像
}
func addBox(x: Float = 0, y: Float = 0, z: Float = -0.2){ // 這里x,y,z中1就代表1米
let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
//1. 創(chuàng)建一個(gè)節(jié)點(diǎn)现诀,把box加入到geomety(幾何結(jié)構(gòu))中
let boxNode = SCNNode()
boxNode.geometry = box
boxNode.position = SCNVector3(x, y, z) //正x在右邊,負(fù)x在左邊履肃。正y是向上仔沿,負(fù)y是向下。正z是向后尺棋,負(fù)z是向前的封锉。我們是設(shè)置的向前0.2米
//2. 初始化SCNScene對(duì)象,把上面的節(jié)點(diǎn)加入到scene的根節(jié)點(diǎn)上
let scene = SCNScene()
scene.rootNode.addChildNode(boxNode)
//3. 把scene對(duì)象加入到我們的sceneView的scene上
sceneView.scene = scene
}
func addTapGestureToSceneView() {
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.didTap(withGestureRecognizer:)))
sceneView.addGestureRecognizer(tapGestureRecognizer)
}
@objc func didTap(withGestureRecognizer recognizer: UITapGestureRecognizer) {
let tapLocation = recognizer.location(in: sceneView)
let hitTestResults = sceneView.hitTest(tapLocation)
guard let node = hitTestResults.first?.node else {
let hitTestResultsWithFeaturePoints = sceneView.hitTest(tapLocation, types: .featurePoint)
if let hitTestResultWithFeaturePoints = hitTestResultsWithFeaturePoints.first {
let translation = hitTestResultWithFeaturePoints.worldTransform.translation
addBox(x: translation.x, y:translation.y, z:translation.z)
}
return
}
node.removeFromParentNode()
}
}
extension float4x4 {
var translation: float3 {
let translation = self.columns.3
return float3(translation.x, translation.y, translation.z)
}
}
就可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的VR程序膘螟。
知行辦公成福,專業(yè)移動(dòng)辦公平臺(tái)https://zx.naton.cn/
【總監(jiān)】十二春秋之,3483099@qq.com荆残;
【Master】zelo奴艾,616701261@qq.com;
【運(yùn)營(yíng)】運(yùn)維艄公脊阴,897221533@qq.com;****
【產(chǎn)品設(shè)計(jì)】流浪貓蚯瞧,364994559@qq.com嘿期;
【體驗(yàn)設(shè)計(jì)】兜兜,2435632247@qq.com埋合;
【iOS】淘碼小工备徐,492395860@qq.com;iMcG33K甚颂,imcg33k@gmail.com蜜猾;
【Android】人猿居士,1059604515@qq.com振诬;思路的頓悟蹭睡,1217022114@qq.com;
【java】首席工程師MR_W赶么,feixue300@qq.com肩豁;
【測(cè)試】土鏡問(wèn)道,847071279@qq.com辫呻;
【數(shù)據(jù)】fox009521清钥,42151960@qq.com;