swift设置启动图不现实

by Ranadhir Dey

由Ranadhir Dey

如何通过装饰房屋来开始在Swift中使用增强现实 (How to get started with augmented reality in Swift by decorating your home)

If you’ve read my previous post, you already have a beautiful AR floor in your dining room. That was the first thing we built while learning the basics of AR. And now, it’s time to decorate the room with some cool virtual furniture. At the end of this tutorial, you will have a dining room just like this:

如果您读过我以前的文章,则您的饭厅已经有一个漂亮的AR地板。 这是我们学习AR基础知识时首先构建的东西。 现在,该用一些凉爽的虚拟家具装饰房间了。 在本教程的最后,您将拥有一个饭厅,如下所示:

命名SCNNode (Naming SCNNodes)

Let’s get our hands dirty. Fire up Xcode, and open the last project where we decorated our floor. Before viewDidLoad, create a constant floorNodeName.

让我们弄脏双手。 启动Xcode,并打开最后一个装饰地板的项目 。 在viewDidLoad之前,创建一个常量floorNodeName。

let floorNodeName = "FloorNode"

We are now going to set the name of the floor node to this constant so that we don’t mix up this node with other furniture nodes. Go to the createFloorNode method and name the floor node.

现在,我们将楼层节点的名称设置为此常数,以免我们将此节点与其他家具节点混淆。 转到createFloorNode方法并命名地板节点。

In line 7 we have just named the floor node — everything else remains the same.

在第7行中,我们刚刚命名了地板节点-其他所有内容都保持不变。

The plan is that, once launched, the app would recognise the floor first and then the user would see through the screen to determine where they want to place the furniture. They would tap on the location and a piece of furniture would sit just there. To achieve this, we need a correlation between the points on screen and the real-world locations. Thankfully, Apple has made this process quite simple.

计划是,一旦启动,应用程序将首先识别地板,然后用户将通过屏幕查看以确定他们要放置家具的位置。 他们将点击该位置,然后将一件家具坐在那里。 为此,我们需要在屏幕上的点与实际位置之间建立关联。 值得庆幸的是,Apple使此过程非常简单。

手势和HitTests (Gestures and HitTests)

An active AR session keeps on finding nearby objects/planes. Once a new object/plane is found, it places AR anchors on top of it. To find exactly on which anchors user has tapped, we need the help of HitTest. HitTest works like this:

活跃的AR会话不断寻找附近的物体/平面。 一旦找到新的对象/平面,它将在其顶部放置AR锚点。 为了准确找到用户点击了哪个锚,我们需要HitTest的帮助。 HitTest的工作方式如下:

  • a logical ray is shot from the point of touch to the anchors on the plane从接触点到平面上的锚点发出逻辑射线
  • all the anchors the ray passes through are stored in an array in the format of HitTestResult.

    射线穿过的所有锚点都以HitTestResult的格式存储在数组中。

Each HitTestResult contains the information of the real-world surface of an AR anchor. We will use this HitTestResult information to place our furniture.

每个HitTestResult都包含AR锚点的真实表面信息。 我们将使用此HitTestResult信息放置家具。

Let’s create a method that adds the tap gesture to our sceneView to interact with the user. We’ll call this method from viewDidLoad.

让我们创建一个将轻击手势添加到我们的sceneView以便与用户交互的方法。 我们将从viewDidLoad调用此方法。

Now define the “tapped” method to get the location of the tap and place a furniture there. For now, we print to test if the HitTest is working fine.

现在定义“轻敲”方法以获取水龙头的位置并将家具摆放在那里。 现在,我们打印以测试HitTest是否工作正常。

In the first line, we are casting tap gesture’s view to ARSCNView. As we know that the tap will come from our sceneView itself, we force-unwrap it. Then we get the location on sceneView where user has tapped. Then a HitTest is performed to get all the HitTestResults from the tapped location to the real-world anchors. “.existingPlaneUsingExtent” gives the estimated size of the detected planes. Now, we check if the user actually has tapped on a detected plane or somewhere else, and we print accordingly.

在第一行中,我们将轻击手势的视图投射到ARSCNView。 我们知道水龙头将来自我们的sceneView本身,因此我们将其强行打开。 然后,我们在SceneView上获得了用户点击的位置。 然后执行HitTest,以从点击的位置获取所有HitTestResults到现实世界的锚点。 “ .existingPlaneUsingExtent”给出检测到的平面的估计大小。 现在,我们检查用户是否确实在检测到的平面或其他位置上轻击,然后进行相应打印。

Now run the app, wait until the world origin loads and the floor is detected. Then tap on the screen to check if we are hitting the planes correctly.

现在运行该应用,等待世界原点加载并检测到地面。 然后在屏幕上点击以检查我们是否正确击中了飞机。

If you tap on the places where the tiles are located, it will print “Touched on the plane.” Touch anywhere else, and it will be “Not a plane.” If there’s no output in the console, you haven’t called the addTapGesture method from viewDidLoad (this happed to me!). Now that we have successfully detected the clicked position, it’s time to bring home some furniture.

如果您点击瓷砖所在的位置,它将打印“ Touched on the plane”。 触摸其他任何地方,它将变为“不是飞机”。 如果控制台中没有输出,则您尚未从viewDidLoad调用addTapGesture方法(这对我来说很麻烦!)。 现在我们已经成功检测到点击位置,是时候将一些家具带回家了。

将3D模型导入项目 (Importing 3D models to the project)

We need some 3D furniture models. I use turbosquid, which is a great repository of 3D models. You need to create a free account there to access their free models. I’ve downloaded a 3D table for now (in the GitHub repo — I’ll add some more furniture as well).

我们需要一些3D家具模型。 我使用了turbosquid ,它是一个很棒的3D模型库。 您需要在此处创建一个免费帐户以访问其免费模型。 我现在已经下载了一个3D 表格 (在GitHub存储库中-我还将添加更多家具)。

Apple advises you to use collada-formatted(.dae) models in SceneKit. I have used other kinds of models as well in the past, and I have faced problems in many cases. Mostly, if there is a glass, SceneKit tends to make it solid. So, let’s find 3D models with a .dae extension.

Apple建议您在SceneKit中使用collada格式的(.dae)模型。 过去我也使用过其他类型的模型,并且在许多情况下都遇到了问题。 通常,如果有玻璃,SceneKit倾向于使其坚固。 因此,让我们找到扩展名为.dae的3D模型。

Now add an asset folder under the “Home Decor” group.

现在,在“ Home Decor”组下添加一个资产文件夹。

Press next, and in the save dialog, save it as furnitures.scnassets and not xcassets.

按下一步,然后在保存对话框中将其另存为家具。 scnassets,而不是xcassets。

使用Xcode SceneKit编辑器 (Working with Xcode SceneKit Editor)

All scene files or models that will be used by SceneKit should reside in a scnassets folder. Now drag and drop the table we just downloaded to the scnassets folder and rename it as “Table”. Click on the Table.dae file (if not already opened) to open it in SceneKit Editor. On the bottom left corner there is a button (marked with a red ellipse below) to open Scene Graph View. Click on it and the editor should appear like below.

SceneKit将使用的所有场景文件或模型都应位于scnassets文件夹中。 现在,将刚才下载的表拖放到scnassets文件夹中,并将其重命名为“ Table”。 单击Table.dae文件(如果尚未打开)在SceneKit Editor中将其打开。 在左下角有一个按钮(下面带有红色椭圆标记)以打开“场景图视图”。 单击它,编辑器应如下所示。

In the Scene Graph there are 3 nodes: a Camera, a light source (Lamp) and the table (Small_table). ARKit has its default camera, so we don’t need this camera anymore. As we will be using sceneView’s default lighting, we don’t need the Lamp either. Remove both of them.

在“场景图”中,有3个节点:“相机”,“光源”(“灯”)和表(“小表”)。 ARKit具有其默认摄像头,因此我们不再需要此摄像头。 因为我们将使用SceneView的默认照明,所以我们也不需要Lamp。 删除两个。

Let’s rename “Small_table” to “Table”, same as the file name. Now the scene graph will look like this:

让我们将“ Small_table”重命名为“ Table”,与文件名相同。 现在,场景图将如下所示:

There is something called point of view (marked with a red ellipse above) in the editor which determines how the object will look from a certain point of view. By default, it’s set to Perspective, but we will be seeing the table from the front. So change the point of view to Front.

编辑器中有一个称为“视点”(上面带有红色椭圆标记)的东西,它确定从特定视点看对象的外观。 默认情况下,它设置为Perspective,但是我们将从前面看到表格。 因此,将视角更改为“正面”。

Oops — it looks like we can see only the top view. Clearly, this isn’t how we would like to see it. We want to see the table as it was shown in the perspective view. Let’s fix this.

糟糕-看来我们只能看到顶视图。 显然,这不是我们希望看到的。 我们希望看到透视表中显示的表格。 让我们解决这个问题。

Select the Table node, open the Utilities tab (right-top corner button in Xcode) and click on the node inspector(the cube icon). You should see the below window.

选择“表”节点,打开“实用程序”选项卡(Xcode中的右上角按钮),然后单击节点检查器(多维数据集图标)。 您应该看到以下窗口。

I’ve numbered the steps for your reference. To view the complete table from the front, we need to rotate the table on its X axis. If you can recollect, we did same kind of thing in the first post where we rotated the capsule on its Z axis by changing its Euler angle.

我已编号步骤供您参考。 要从正面查看完整的表格,我们需要沿X轴旋转表格。 如果可以回忆的话,我们在第一篇文章中做了同样的事情,我们通过更改胶囊的欧拉角沿其Z轴旋转胶囊。

If you see the Transforms matrix, the Euler angle for X is already specified to 90 degree radians, which is causing the table to be rotated incorrectly. Make it zero and the rotation will be fixed. But the positioning has a vector of (-0.35,0.348,0). We will make it (0,0,0) to place the table exactly where the user will tap. Now the Transform will look like this:

如果您看到“变换”矩阵,则X的欧拉角已指定为90度弧度,这将导致表格旋转不正确。 使其为零,旋转将被固定。 但是定位的向量为(-0.35,0.348,0)。 我们将使其(0,0,0)恰好将桌子放置在用户点击的位置。 现在,Transform将如下所示:

Transform matrix editing is kind of a trial and error task. You might need to go through quite a number of iterations before you reach the exact position.

变换矩阵编辑是一种反复试验的任务。 您可能需要经过很多次迭代才能到达确切位置。

Now, we change the .dae model to a SceneKit scene file (.scn) which will made it much more efficient for SceneKit to handle. Go to Editor>Convert to SceneKit scene file(.scn).

现在,我们将.dae模型更改为SceneKit场景文件(.scn),这将使SceneKit的处理效率大大提高。 转到“编辑器”>“转换为SceneKit场景文件(.scn)”。

And…we are done with the 3D object editing. Head back to the ViewController file. First, since we have removed the light source of the table, we should turn on the default lighting of the scene view in viewDidLoad.

并且…我们完成了3D对象编辑。 回到ViewController文件。 首先,由于我们已经删除了桌子的光源,因此我们应该在viewDidLoad中打开场景视图的默认照明。

sceneView.autoenablesDefaultLighting = true

sceneView.autoenablesDefaultLighting = true

定位3D对象 (Positioning 3D objects)

Then we create a method to add the table to the scene. It will accept a HitResult as a parameter and place the table based on the position of the HitResult.

然后,我们创建一种将表添加到场景的方法。 它将接受HitResult作为参数,并根据HitResult的位置放置表格。

Bear with me — this is the last method which needs some explanation!

忍受我-这是最后一个需要解释的方法!

  1. A constant is declared to know what furniture scene needs to be added. We will change it to a variable and declare it on top of the viewcontroller when we have more furniture.声明一个常数以知道需要添加什么家具场景。 当我们拥有更多家具时,我们将其更改为变量并在ViewController的顶部声明。
  2. Then we create a scene from the selected furniture file.然后,我们从选定的家具文件创建场景。
  3. A furniture node is created from the child node of the furniture scene’s root node with the name of the furniture. As we named the first node the same as the furniture name, it doesn’t need to traverse any further. Hence the recursive option is set to false.从家具场景的根节点的子节点创建带有家具名称的家具节点。 由于我们将第一个节点命名为与家具名称相同,因此不需要进一步遍历。 因此,递归选项设置为false。
  4. HitResult’s worldTransform property holds the co-relation transform matrix between the real-world position and the scene anchor/node position. And the 3rd column of the transform matrix holds the position information.

    HitResult的worldTransform属性保存现实位置和场景锚点/节点位置之间的互相关转换矩阵。 并且变换矩阵的第三列保存位置信息。

  5. Now that we have successfully extracted the world coordinate of the tapped location, our job is now just to place the furniture node on that exact same coordinate.现在我们已经成功提取了所点击位置的世界坐标,我们的工作就是将家具节点放置在该完全相同的坐标上。
  6. Then we add the node to the root node of the scene. And thats it!然后,将节点添加到场景的根节点。 就是这样!

Now we just need to call the method whenever the user taps on the screen. Let’s modify the tapped method to accommodate this change.

现在,我们只需要在用户点击屏幕时调用该方法。 让我们修改点按的方法以适应此更改。

Here, if we find a plane, we are just calling the method to add the furniture. As HitTest holds all the positions the ray passes through, we are considering the top most result. Let’s run the app, wait until the floor has tiles on it, and then tap on the screen to place a table. And voilà! You have a new table on your floor. Watch your step :)

在这里,如果找到飞机,我们只是在调用添加家具的方法。 由于HitTest保持了射线穿过的所有位置,因此我们正在考虑获得最高的结果。 让我们运行该应用程序,等到地板上铺有瓷砖,然后在屏幕上点击以放置桌子。 和瞧! 您的地板上有一张新桌子。 小心台阶 :)

I have downloaded some more furniture and have added it into the repo. I’ve also added pinch and rotate gestures to resize and rotate objects. The complete source code will give you an appearance like this:

我已经下载了更多家具并将其添加到存储库中。 我还添加了捏合和旋转手势以调整大小和旋转对象。 完整的源代码将为您提供如下外观:

You can download the full source code from GitHub.

您可以从GitHub下载完整的源代码。

Hope you have enjoyed reading the post as much as I did writing it :)

希望您像我写这篇文章一样喜欢阅读这篇文章:)

See you at the next post. Happy reading!!

下篇文章见。 阅读愉快!

翻译自: https://www.freecodecamp.org/news/how-to-get-started-with-augmented-reality-in-swift-by-decorating-your-home-85671482df3c/

swift设置启动图不现实

swift设置启动图不现实_如何通过装饰房屋来开始在Swift中使用增强现实相关推荐

  1. Swift5.x使用纯代码创建NavigationTab控制器设置启动图Wb第1部分

    Swift5.x使用纯代码创建NavigationTab控制器设置启动图Wb第1部分 前言 1 使用纯代码创建NavigationTab控制器必须会,也可使用storyboard拖控件,没有代码创建灵 ...

  2. ios添加 启动画面_iOS 两种设置启动图方式的 bug 汇总

    楼主最近几天一直在纠结这个,忙到最后发现是 Apple 的锅,臣妾真搞不定呀 1.单独使用 LaunchImage 来设置启动图时: ①iOS9 系统的手机,在 APP 从后台通过 openURL 拉 ...

  3. iOS App 设置启动图(LaunchImage)

    基本上所有APP都有启动图,用来过渡APP启动时的一些耗时操作 (注意:启动图不是引导图,引导图得自定义VC) 下面简单说一下如何设置启动图. 1.点击 进入 Assets.xcassets ,右键新 ...

  4. AIR iOS 设置启动图,全屏

    问题 AirSDK打包时,没有对应的工程进行设置,无法全屏什么的,,, 打包过程中发现,设置不同启动图,Air的舞台大小会不一样(周围有黑边),特别是SDK更新后,新设备会有明显的问题. 最开始之前更 ...

  5. LaunchScreen.xib 设置启动图

    1.LaunchScreen.xib 中拖入UIImageView 约束都设置为0 2.新建一个Image Set 起名为LaunchScreen  Devices设置为:Device Speecif ...

  6. 微信小程序设置启动图时出现滚动条

    将image设置成块级元素可解决,即: display:block 转载于:https://blog.51cto.com/13550695/2369381

  7. python设置曲面图颜色范围_三维曲面p的matplotlib中的自定义颜色映射

    我有一个指定颜色图的曲面图.以下是我的理解:import numpy as np import matplotlib.pyplot as plt import math from mpl_toolki ...

  8. python 图 鼠标 显示_在matplotlib图形窗口(带imshow)中,如何删除、隐藏或重新定义鼠标的显示位置?...

    是的,你可以.但比你想象的要难. 您看到的鼠标跟踪标签是根据鼠标跟踪调用matplotlib.axes.axes.format_coord生成的.您必须创建自己的Axes类(重写format_coor ...

  9. storyboard 苹果启动图_使用Xcode storyboard 来提供 app 的启动屏幕

    一. 背景 6月30日前,苹果要求所有的app必须使用storyboard来提供app的启动屏幕. 其主要目的就是希望所有的开发者尽量不使用一张纯图片作为启动页面,而是希望APP的启动页面和其他页面一 ...

最新文章

  1. R语言deLong‘s test:通过统计学的角度来比较两个ROC曲线、检验两个ROC曲线的差异是否具有统计显著性
  2. vue 使用font-awesome
  3. php接收ajax转数组
  4. Python中的装饰器,迭代器,生成器
  5. 汇编语言——第2次上机实验
  6. 因为不想「被绿」,美国年轻人只想和 iPhone 聊天
  7. python中属于有序序列的有_Python中的有序序列有哪些
  8. map-based exploration of intrinsic shape differences and variability
  9. Java设计模式应用到数据库_Java设计模式在数据库编程中的应用研究
  10. M1 macbook安装jdk
  11. dijikstra 旅行商问题_车辆路径问题与算法
  12. 多屏信号服务器,多屏拼接控制器及多屏拼接方案【图文】
  13. 年薪50万的大数据分析师养成记
  14. 转:教人找电影的攻略
  15. Gym - 101606L Lizard Lounge 计算几何+LIS
  16. CocoaPods禁止显示警告inhibit_all_warnings
  17. 关于SpringMVC中使用LocalDateTime类型接收参数提示类型不匹配的问题
  18. Android开发-AMD平台如何使用Android studio自带模拟器
  19. linux磁盘阵列教程,RAID 磁盘阵列简述
  20. Java Scaner类详解_动力节点Java学院整理

热门文章

  1. 更轻量的 View Controllers
  2. php ile_get_contents无法请求https连接的解决方法
  3. 卡片右上角三角形效果,按钮点击变色
  4. iOS进阶之页面性能优化
  5. 白盒测试实践-任务完成
  6. JavaScript中几个重要的知识点(1) ---- 面向对象
  7. 2017.1.9版给信息源新增:max_len、max_db字段
  8. 自己动手,做一款抬头显示的「Todo Hud」
  9. QQ群功能设计与心理学
  10. 小鱼提问1 类中嵌套public修饰的枚举,外部访问的时候却只能Class.Enum这样访问,这是为何?...