ARkit 收藏本版 已有4人收藏 +发表新主题
查看: 26870|回复: 3
打印 上一主题 下一主题

关于Xcode的ARKit开发

[复制链接]

关于Xcode的ARKit开发

xieyoulong 发表于 2017-8-8 19:30:40 浏览:  26870 回复:  3 只看该作者 复制链接
本帖最后由 xieyoulong 于 2017-8-8 19:33 编辑

ARKit 最近在开发圈实在是火,ios 开发者可以快速的进行增强现实的开发,简化了许多步骤,接下来我们实现一个简单的AR功能
打开Xcode,新建一个AR项目

  这次我们用SceneKit 来渲染3D内容。

  进入项目之后会有个smaple project,我们可以尝试着运行:

  我们使用SceneKit绘制一个3D立方体。SceneKit有几个基本类,SCNScene是所有3D模型的容器。要向场景添加内容,你首先创建几何,几何可以是复杂的形状,或简单的像球体,多维数据集,平面等。然后,将几何模型放在在场景节点中,并将其添加到场景中。然后,SceneKit将遍历场景图并呈现内容。
  1.   - (void)viewDidLoad {

  2.   [super viewDidLoad];

  3.   SCNScene *scene = [SCNScene new];

  4.   SCNBox *boxGeometry = [SCNBox

  5.   boxWithWidth:0.1

  6.   height:0.1

  7.   length:0.1

  8.   chamferRadius:0.0];

  9.   SCNNode *boxNode = [SCNNode nodeWithGeometry:boxGeometry];

  10.   boxNode.position = SCNVector3Make(0, 0, -0.5);

  11.   [scene.rootNode addChildNode: boxNode];

  12.   self.sceneView.scene = scene;

  13.   }
复制代码
  ARKit和SceneKit的坐标系如下所示:

  当ARSession启动时,计算出的相机位置最初设置为X = 0,Y = 0,Z = 0。
  们可以看到立方体的两面,我们可以稍后添加一些更高级的照明,但现在我们可以在SCNScene实例上设置autoenablesDefaultLighting :
  self.sceneView.autoenablesDefaultLighting = YES;
  进阶:平面检测+可视化
  效果演示:

  在我们开始之前,将一些调试信息添加到程序中,即渲染ARKit检测到的功能点,我们可以打开我们的ARSCNView:
  1.   self.sceneView.debugOptions =

  2.   ARSCNDebugOptionShowWorldOrigin |

  3.   ARSCNDebugOptionShowFeaturePoints;
复制代码
  我们来检测平面几何,在ARKit中,可以通过设置planeDetection属性来检测水平平面。此值可以设置为ARPlaneDetectionHorizontal或ARPlaneDetectionNone。

  1.   - (void)renderer:(id )renderer

  2.   didAddNode:(SCNNode *)node

  3.   forAnchor:(ARAnchor *)anchor {

  4.   }
复制代码
  SCNNode实例是ARKit创建的一个SceneKit节点,它具有一些类似于方向和位置的属性,然后我们获得一个锚实例,这将告诉我们使用已找到的特定锚点的更多信息,如大小和中心位置的plane。锚实例实际上是一个ARPlaneAnchor类型,比如我们可以得到plane的范围和中心信息。
  我们进行渲染plane,可以在虚拟世界中绘制一个SceneKit 3D平面。为此,我们创建一个继承自SCNNode的Plane类。在构造方法中,我们创建平面并相应地调整它的大小:
  1.  self.planeGeometry = [SCNPlane planeWithWidth:anchor.extent.x height:anchor.extent.z];

  2.   SCNNode *planeNode = [SCNNode nodeWithGeometry:self.planeGeometry];

  3.   planeNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);

  4.   planeNode.transform = SCNMatrix4MakeRotation(-M_PI / 2.0, 1.0, 0.0, 0.0);

  5.   [self addChildNode:planeNode];
复制代码
  现在我们有我们的Plane类,回到ARSCNViewDelegate回调方法中,当ARKit找到一个新的锚点时,我们可以创建我们的新plane:
  1.   - (void)renderer:(id )renderer

  2.   didAddNode:(SCNNode *)node

  3.   forAnchor:(ARAnchor *)anchor {

  4.   if (![anchor isKindOfClass:[ARPlaneAnchor class]]) {

  5.   return;

  6.   }

  7.   Plane *plane = [[Plane alloc] initWithAnchor: (ARPlaneAnchor *)anchor];

  8.   [node addChildNode:plane];

  9.   }

  10.   更新Plane SceneKit,使得我们在移动时有更稳定的效果。

  11.   - (void)renderer:(id )renderer

  12.   didUpdateNode:(SCNNode *)node

  13.   forAnchor:(ARAnchor *)anchor {

  14.   // See if this is a plane we are currently rendering

  15.   Plane *plane = [self.planes objectForKey:anchor.identifier];

  16.   if (plane == nil) {

  17.   return;

  18.   }

  19.   [plane update:(ARPlaneAnchor *)anchor];

  20.   }

  21.   更新plane的宽度和高度。

  22.   - (void)update:(ARPlaneAnchor *)anchor {

  23.   self.planeGeometry.width = anchor.extent.x;

  24.   self.planeGeometry.height = anchor.extent.z;

  25.   self.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z);

  26.   }
复制代码
  运行,会发现如下一些效果。

  添加物理效果
  效果预览:

  在这个演示中,当用户在屏幕上单击时,我们执行一段代码,这个代码很简单,ARSCNView包含一个hitTest方法,可以通过获得的屏幕坐标点,从相机中心通过该点投射一条射线,并返回结果:
  1.  - (void)handleTapFrom: (UITapGestureRecognizer *)recognizer {

  2.   CGPoint tapPoint = [recognizer locationInView:self.sceneView];

  3.   NSArray *result = [self.sceneView hitTest:tapPoint types:ARHitTestResultTypeExistingPlaneUsingExtent];

  4.   if (result.count == 0) {

  5.   return;

  6.   }

  7.   ARHitTestResult * hitResult = [result firstObject];

  8.   [self insertGeometry:hitResult];

  9.   }
复制代码
  通过上述代码,我们可以得到射线与平面交叉点的世界坐标,并在该位置放置一些3D模型等等。
  1.  - (void)insertGeometry:(ARHitTestResult *)hitResult {

  2.   float dimension = 0.1;

  3.   SCNBox *cube = [SCNBox boxWithWidth:dimension

  4.   height:dimension

  5.   length:dimension

  6.   chamferRadius:0];

  7.   SCNNode *node = [SCNNode nodeWithGeometry:cube];

  8.   node.physicsBody = [SCNPhysicsBody

  9.   bodyWithType:SCNPhysicsBodyTypeDynamic

  10.   shape:nil];

  11.   node.physicsBody.mass = 2.0;

  12.   node.physicsBody.categoryBitMask = CollisionCategoryCube;

  13.   float insertionYOffset = 0.5;

  14.   node.position = SCNVector3Make(

  15.   hitResult.worldTransform.columns[3].x,

  16.   hitResult.worldTransform.columns[3].y + insertionYOffset,

  17.   hitResult.worldTransform.columns[3].z

  18.   );

  19.   [self.sceneView.scene.rootNode addChildNode:node];

  20.   [self.boxes addObject:node];

  21.   }
复制代码
  我们给每个立方体一个physicsBody,它是SceneKit的物理引擎。
  接下来,我们实现停止平面检测的功能。用户用两个手指按住屏幕1秒钟,那么我们会隐藏所有的平面并关闭平面检测。
  1.  ARWorldTrackingSessionConfiguration *configuration = (ARWorldTrackingSessionConfiguration *)self.sceneView.session.configuration;

  2.   configuration.planeDetection = ARPlaneDetectionNone;

  3.   [self.sceneView.session runWithConfiguration:configuration];
复制代码


ARKit技术交流qq群482631386
ARVR训练营www.arvrthink.com

文章转自AR酱:https://335284.kuaizhan.com/15/63/p4416344644c71d


分享至:
| 人收藏
回复

使用道具 举报

该用户从未签到

沙发
重庆生活网l 发表于 2017-10-25 19:39:46 只看该作者
能发这么好的帖子,太谢谢了













第五代QQ机器人QQ群机器人论坛QQ机器人智能客服机器人QQplus机器人QQ群互联机器人..联系QQ4000017854
回复 支持 反对

使用道具 举报

该用户从未签到

板凳
重庆生活网l 发表于 2017-10-26 22:07:54 只看该作者
真不错,赞一个,继续努力啊













第五代QQ机器人QQ群机器人论坛QQ机器人智能客服机器人QQplus机器人QQ群互联机器人..联系QQ800829129 QQ群28352615
回复 支持 反对

使用道具 举报

  • TA的每日心情

    2019-3-25 21:42
  • 签到天数: 2 天

    [LV.1]初来乍到

    地板
    wj7636 发表于 2019-4-10 15:01:55 只看该作者
    【句句十五个字有哪个高手能超越呢】!电动门 http://www.ssmdd.com
    回复 支持 反对

    使用道具 举报

    *滑动验证:
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    Copyright © 2013-2017 ARinChina-增强现实中国技术论坛   All Rights Reserved.