100 行代碼寫一個手機AR

本節學習目標

學習如何使用SceneKit框架高效開發AR項目

先來看兩個效果視頻

Scenekit_17.gif
Scenekit_16.gif

使用技術

蘋果親兒子 SceneKit 3D框架

話不多說直接上干活


實現思路

第一步 - 攝像頭捕捉生活場景
第二步 - 使用SceneKit 框架加載3D 模型文件
第三步 - 使用重力感應類獲取手機旋轉角度,模型中的視角位置


代碼實現部分

  • 第一步 - 通過照相機捕捉現實生活中的場景,這個想必iOS 開發者都很熟悉,我就簡單的說一下

使用的框架AVFoundation

Step-1.實現兩個協議
1.AVCaptureMetadataOutputObjectsDelegate
2.UINavigationControllerDelegate

Step-2.創建一個捕捉設備對象

let device =   AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

Step-3.創建一個輸入和輸出設備對象

  let input = try! AVCaptureDeviceInput(device: device)
  output = AVCaptureMetadataOutput()
  output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
  session = AVCaptureSession()

Step-4.創建一個會話場景 將輸入和輸出設備對象添加到會話場景中去

session.canSetSessionPreset(AVCaptureSessionPresetHigh)
if(session.canAddInput(input)){
      session.addInput(input)
}
if(session.canAddOutput(output)){
    session.addOutput(output)
}

Step-5.創建一個預覽視圖對象用于顯示攝像頭捕捉到的畫面

let preview = AVCaptureVideoPreviewLayer(session: session)
preview?.videoGravity = AVLayerVideoGravityResizeAspectFill
preview?.frame = self.bounds
self.layer.addSublayer(preview!)

Step-6.開始捕捉畫面

session.startRunning()

第一步操作完成了,接下來第二步操作

  • 第二步 創建渲染3D模型的場景

Step-1.創建渲染3D模型專用視圖

   var  scnView:SCNView = { // 游戲場景
   let view = SCNView()
   return view
  }()

Step-2.創建用于觀察3D場景的照相機節點對象

var  eyeNode:SCNNode = { // 眼睛節點
    let node = SCNNode()
    node.camera = SCNCamera()
    node.camera?.automaticallyAdjustsZRange = true;
    return node
}()

Step-3.配置3D視圖

self.scnView.frame = self.frame
self.addSubview(self.scnView)
self.scnView.scene = SCNScene()     
self.scnView.scene?.rootNode.addChildNode(self.eyeNode)

Step-4.創建一個給場景中添加3D模型的方法

 func addModelFile(file:URL,position:SCNVector3){
   let scene = try! SCNScene(url: file, options: nil)
   let node = scene.rootNode
   node.position = position
   self.scnView.scene?.rootNode.addChildNode(node)
}

第二步. 內容就完成了,繼續第三步

  • 第三步 創建重力感應對象,檢測手機角度的變化

Step-1.創建對象

var  motionManager = CMMotionManager() 

Step-2.設置刷新頻率

motionManager.deviceMotionUpdateInterval = 1/30.0

Step-3.開始檢測

 motionManager.startDeviceMotionUpdates(using: .xMagneticNorthZVertical, to: OperationQueue.main) { (motion, error) in
     if  let attitude = motion?.attitude,error == nil{
         var vector = SCNVector3Zero
         if (UIDevice.current.orientation.isPortrait) // home鍵靠右
          {
                vector.x = Float(attitude.pitch);
                vector.y = (Float)(attitude.roll);
            }else if(UIDevice.current.orientation.isLandscape ){
                vector.x = (Float)(attitude.pitch);
                vector.y = Float(attitude.roll);
           }else{
                vector.x = (Float)(attitude.pitch)
                vector.y = Float(attitude.roll);
           }
           vector.z = Float(attitude.yaw);
           self.eyeNode.eulerAngles = vector
       }
   }

以上就是全部內容了

A5556ACE-2593-4C8B-B946-E77BC2F0C070.png

上圖是demo的工程目錄

所有內容封裝在一個ARView的文件中,接下來看看如何使用

  // 創建AR場景
   self.arView = ARView(frame: UIScreen.main.bounds)
   self.view.addSubview(self.arView)
    // 添加3D 文件
   let url =  Bundle.main.url(forResource: "boss_attack", withExtension: "dae")
   self.arView.addModelFile(file: url!, position: SCNVector3Make(0, 0, -1000))

可能好多iOS 開發者從來沒有使用過SceneKit 3D框架,是因為國內這方面的資料太少。不過這個引擎特別強大,而且使用起來很簡單,appstore上有中文電子書,當你項目需要在你的應用中加入3D元素的時候,可以去下載看看,應用名字叫做<SceneKit>

來給大家看一張圖,你就知道它有多強大

混編

此demo的代碼,我已放在這里

Swift教程
SceneKit 中文教程
VR全景播放器

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容