当前位置:主页 > 资料 >

开源一个 AR 线上项目
栏目分类:资料   发布日期:2018-08-02   浏览次数:

导读:本文为去找网小编(www.7zhao.net)为您推荐的开源一个 AR 线上项目,希望对您有所帮助,谢谢! WeAre.gif 技术点 AR初始化 在新建项目时可以直接创建 AR 项目, xcode 会创造一个 AR 项目的模板

本文为去找网小编(www.7zhao.net)为您推荐的开源一个 AR 线上项目,希望对您有所帮助,谢谢!

www.7zhao.net



内容来自www.7zhao.net

WeAre.gif www.7zhao.net

技术点

copyright www.7zhao.net

AR初始化

在新建项目时可以直接创建 AR 项目, xcode 会创造一个 AR 项目的模板. 内容来自www.7zhao.net

也可以创建普通的项目,在需要实现 AR 功能的控制器中实现如下代码进行初始化.

本文来自去找www.7zhao.net

import ARKit
let sceneView = ARSCNView()

override func viewDidLoad() {
    super.viewDidLoad()
    sceneView.frame = view.bounds
    view.addSubview(sceneView)

    sceneView.delegate = self
    sceneView.showsStatistics = true

    // 创建一个场景,系统默认是没有的
    let scene = SCNScene()
    sceneView.scene = scene

      //不允许用户操作摄像机
     sceneView.allowsCameraControl = false
      //抗锯齿
     sceneView.antialiasingMode = .multisampling4X

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let configuration = ARWorldTrackingConfiguration()
    sceneView.session.run(configuration)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    sceneView.session.pause()
}
 本文来自去找www.7zhao.net 

添加节点

    //我使用的是 SCNPlane 来充当相框,也可以使用"厚度"很小的 SCNBox
    let photo = SCNPlane(width: 1, height: 1)
    //photo.cornerRadius = 0.01
    let image = UIImage(named: "0")
    //纹路可以使图片,也可以是颜色
    photo.firstMaterial?.diffuse.contents = image
    //photo.firstMaterial?.diffuse.contents = UIColor.red
    let photoNode = SCNNode(geometry: photo)
    //节点的位置
    let vector3 = SCNVector3Make(-1, -1, -1) 
    photoNode.position = vector3
    sceneView.scene.rootNode.addChildNode(photoNode) 

欢迎访问www.7zhao.net

     let text = SCNText(string: "文字", extrusionDepth: 0.1)
text.font = UIFont.systemFont(ofSize: 0.4) 去找(www.7zhao.net欢迎您
let textNode = SCNNode(geometry: text)
textNode.position = SCNVector3Make(0,0, -1) 去找(www.7zhao.net欢迎您
//文字的图片/颜色
text.firstMaterial?.diffuse.contents = UIImage(named: color)
sceneView.scene.rootNode.addChildNode(textNode)

去找(www.7zhao.net欢迎您

可供选择的几何图形 内容来自www.7zhao.net

SCNText 文字   copyright www.7zhao.net

SCNPlane 平面  

欢迎访问www.7zhao.net

SCNBox 盒子  

内容来自www.7zhao.net

SCNPyramid 锥形  

欢迎访问www.7zhao.net

SCNSphere 球  

内容来自www.7zhao.net

SCNCylinder 圆柱  

copyright www.7zhao.net

SCNCone 圆锥  

去找(www.7zhao.net欢迎您

SCNTube 圆筒  

去找(www.7zhao.net欢迎您

SCNCapsule 胶囊  

www.7zhao.net

SCNTorus 圆环  

内容来自www.7zhao.net

SCNFloor 地板   内容来自www.7zhao.net

SCNShape 自定义

copyright www.7zhao.net

全景图实现

本文来自去找www.7zhao.net

想象自己站在一个球的球心处,球的内表面涂着壁画,那么是不是就实现了全景图. copyright www.7zhao.net

所以用一个Sphere 节点包裹着相机节点(也就是0位置节点),再设置Sphere节点的内表面纹理,就实现了功能. 欢迎访问www.7zhao.net

let sphere = SCNSphere(radius: 15) 去找(www.7zhao.net欢迎您

let sphereNode = SCNNode(geometry: sphere) 欢迎访问www.7zhao.net

sphere.firstMaterial?.isDoubleSided = true 去找(www.7zhao.net欢迎您

sphere.firstMaterial?.diffuse.contents = image 去找(www.7zhao.net欢迎您

sphereNode.position = SCNVector3Zero 本文来自去找www.7zhao.net

scene.rootNode.addChildNode(sphereNode)

内容来自www.7zhao.net

播放视频

www.7zhao.net

        let height:CGFloat = CGFloat(width) * videoSize.height/videoSize.width
        let box = SCNBox(width: width, height: height, length: 0.3, chamferRadius: 0)
        boxNode.geometry = box;
        boxNode.geometry?.firstMaterial?.isDoubleSided = true
        boxNode.position = SCNVector3Make(0, 0, -5);
        box.firstMaterial?.diffuse.contents = UIColor.red
        self.scene.rootNode.addChildNode(boxNode);


        let avplayer = AVPlayer(url: url)
        avplayer.volume = rescoucceConfiguration.video_isSilence ? 0.0 : 3.0
        videoPlayer = avplayer
        let videoNode = SKVideoNode(avPlayer: avplayer)
        NotificationCenter.default.addObserver(self, selector: #selector(playEnd(notify:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil)

        videoNode.size = CGSize(width: 1600, height: 900)
        videoNode.position = CGPoint(x: videoNode.size.width/2, y: videoNode.size.height/2)
        videoNode.zRotation = CGFloat(Float.pi)
        let skScene = SKScene()
        skScene.addChild(videoNode)
        skScene.size = videoNode.size
        box.firstMaterial?.diffuse.contents = skScene
        videoNode.play()
 

欢迎访问www.7zhao.net

粒子效果

        /*
          particleName = "bokeh.scnp"
          particleName = "rain.scnp"
          particleName = "confetti.scnp"
        **/
        particleSytem = SCNParticleSystem(named: particleName, inDirectory: nil){
        particleNode.addParticleSystem(particleSytem)
        particleNode.position = SCNVector3Make(0, Y, 0)
        self.scene.rootNode.addChildNode(particleNode)
 copyright www.7zhao.net 

节点点击事件

  //给 场景视图sceneView 添加点击事件
   let tap = UITapGestureRecognizer(target: self, action: #selector(tapHandle(gesture:)))
   sceneView.addGestureRecognizer(tap)
 copyright www.7zhao.net 
@objc func tapHandle(gesture:UITapGestureRecognizer){
       let results:[SCNHitTestResult] = (self.sceneView?.hitTest(gesture.location(ofTouch: 0, in: self.sceneView), options: nil))!
       guard let firstNode  = results.first else{
           return
       }
       // 这就是点击到的节点 可以对他做一些事情 或者根据这个节点的某些属性执行不同的方法
       let node = firstNode.node.copy() as! SCNNode
       if firstNode.node == self.selectNode {
           …推远照片…
       }else{
           …拉近照片…
           selectNode = node
       }
   }
 www.7zhao.net 

节点动画

我的另一篇文章中有详细记录 copyright www.7zhao.net

//拉近(推远)照片

本文来自去找www.7zhao.net

      //这只是其中一种方法
      let newPosition  = SCNVector3Make(firstNode.node.worldPosition.x*2, firstNode.node.worldPosition.y*2, firstNode.node.worldPosition.z*2)
      let comeOut = SCNAction.move(to: newPosition, duration: 1.2)
      firstNode.node.runAction(comeOut)
 去找(www.7zhao.net欢迎您 

自传/公转

        //自转
        let box = SCNBox(width: boxW, height: boxW, length: boxW, chamferRadius: 0)
        let boxNode = SCNNode(geometry: box)
        boxNode.position = vector3
        let emptyNode = SCNNode()
        emptyNode.position = SCNVector3Zero
        emptyNode.rotation = SCNVector4Make(0, 1, 0, Float.pi/Float(L/2) * Float(index))
        emptyNode.addChildNode(boxNode)
        photoRingNode.addChildNode(emptyNode)
        let ringAction = SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: right, z: 0, duration: 2))
        boxNode.runAction(ringAction)
        //公转 把节点加到一个正在自传的节点上就可以了
 

www.7zhao.net

录屏

录屏是使用ReplayKit完成的 内容来自www.7zhao.net

开始录屏 去找(www.7zhao.net欢迎您

协议      
RPScreenRecorderDelegate,RPPreviewViewControllerDelegate

 RPScreenRecorder.shared().startRecording(handler: nil)
 RPScreenRecorder.shared().delegate = self
 内容来自www.7zhao.net 

录制代理

func screenRecorder(_ screenRecorder: RPScreenRecorder, didStopRecordingWith previewViewController: RPPreviewViewController?, error: Error?) {
       print(error ?? "error")
       if error != nil{
           print("error:", error ?? "")
           DispatchQueue.main.async {
               let string = error?.localizedDescription
               ITTPromptView .showMessage(string, andFrameY: 0)
               print(string ?? "")
               //录制期间失败
               self.showFailReplay()
           }
       }else{
           print("else")
       }
       print("start recording handler")
   }
   //录制失败
   func showFailReplay(){
       let sb = UIStoryboard(name: "Main", bundle: nil)
       let vc = sb.instantiateViewController(withIdentifier: "HKExplainViewController")
       self.navigationController?.pushViewController(vc, animated: true)
       self.replayButtonRight.constant = 85;
       for button in self.smailButtons {
           button.alpha = 1
       }
       self.mainButton.alpha = 1
       UIView.animate(withDuration: 2.5) {
           self.stopReplayButton.alpha = 0
           self.view.layoutIfNeeded()
       }
   } 

内容来自www.7zhao.net

结束并弹出预览控制器

copyright www.7zhao.net

  RPScreenRecorder.shared().stopRecording { (vc, erroe) in
        vc?.previewControllerDelegate = self
        vc?.title = "We Are"
        self.present(vc!, animated: true, completion: nil)
    }
 欢迎访问www.7zhao.net 

预览控制器的代理

去找(www.7zhao.net欢迎您

func previewController(_ previewController: RPPreviewViewController, didFinishWithActivityTypes activityTypes: Set
  
    
     
   )
  
     {
print(activityTypes)
//取消

内容来自www.7zhao.net


if activityTypes.count == 0 {
previewController.dismiss(animated: true, completion: nil)
}
//保存
if activityTypes.contains("com.apple.UIKit.activity.SaveToCameraRoll"){ www.7zhao.net
ITTPromptView .showMessage("视频已保存在相册", andFrameY: 0)
previewController.dismiss(animated: true, completion: nil)
//检测到您刚刚保存了视频 是否想要分享
let delay = DispatchTime.now() + .seconds(2) 欢迎访问www.7zhao.net
DispatchQueue.main.asyncAfter(deadline: delay) {
self.outputVideo()
}
}
}

内容来自www.7zhao.net

目前所有代码已上传至 github

www.7zhao.net

欢迎(跪求)Star!

去找(www.7zhao.net欢迎您

作者:Heikki_
链接:https://www.jianshu.com/p/4a2ce71b44b2 本文来自去找www.7zhao.net

www.7zhao.net


本文原文地址:http://www.cocoachina.com/ios/20180802/24424.html

以上为开源一个 AR 线上项目文章的全部内容,若您也有好的文章,欢迎与我们分享!

copyright www.7zhao.net

Copyright ©2008-2017去找网版权所有   皖ICP备12002049号-2 皖公网安备 34088102000435号   关于我们|联系我们| 免责声明|友情链接|网站地图|手机版