RoomPlan

RoomPlanWWDC22上发布的一开非常酷的一个库,虽然,第一天的Keynote中都没有任何介绍和相关的技术展示。但是,从开发者网站中我们窥探到了这一新库出现。这个库主要是干嘛的呢?从目前来看,可以使用它扫描房间,它会帮我们创建好房间的3D模型。

来看下官方的这个演示视频,可以直观的感受下这个库的魅力。

嗯,看上去貌似对房地产行业和家装行业比较友好。

下面主要从技术角度介绍下RoomPlan

RoomPlan其实是ARKit的一个再封装,其主要利用的技术是借助LiDAR扫描周围的环境,捕获到场景的深度信息。然后,根据场景几何建立我们的Room网格。RoomPlan还利用影像数据结合AI的能力,对现实物体进行了更加细致的分类、检测和分割。主要可以识别这几大类:

1
2
3
4
5
6
7
8
9
10
// 墙体
public var walls: [CapturedRoom.Surface] { get }
// 门
public var doors: [CapturedRoom.Surface] { get }
// 窗户
public var windows: [CapturedRoom.Surface] { get }
// 开口
public var openings: [CapturedRoom.Surface] { get }
// 物体
public var objects: [CapturedRoom.Object] { get }

其中,Object 下面还有细分的类别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public enum Category : Codable, Sendable {
// 未知
case unknown
// 储物柜
case storage
// 冰箱
case refrigerator
// 厨灶
case stove
// 床
case bed
// 水槽
case sink
// 洗衣机
case washer
// 马桶
case toilet
// 浴缸
case bathtub
// 烤箱
case oven
// 洗碟机
case dishwasher
// 桌子
case table
// 沙发
case sofa
// 椅子
case chair
// 壁炉
case fireplace
// 屏幕
case screen
// 楼梯
case stairs
}

可以看到,识别的物品还是比较多的,未来苹果应该会增加更多的识别项。

如何使用?

主要有两种使用方式,一种是直接使用封装好的RoomCaptureView,另一种是通过API接口来自定义实现。下面主要介绍使用RoomCaptureView实现房间的模型创建。

RoomCaptureViewUIView的子类,我们可以轻松地在自己的应用程序中使用它。RoomCaptureView主要负责三件事情:

  • 根据扫描到的物理环境空间实时在屏幕上进行反馈;
  • 实时生成当前扫描得到的房间模型;
  • 在一些特殊情况时候显示对用户的引导;

使用RoomCaptureView只需要通过四个简单的步骤。

  • 首先,我们需要在对应的 ViewController 中创建一个 RoomCaptureView 引用。
  • 其次,我们需要创建对 RoomCaptureSession 配置对象的引用。
  • 第三,创建开始扫描的函数,在run中置传递相关参数。
  • 最后,创建停止扫描函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import UIKit
import RoomPlan

class RoomCaptureViewController: UIViewController {
private var roomCaptureView: RoomCaptureView!
private var roomCaptureSessionConfig: RoomCaptureSession.Configuration

override func viewDidLoad() {
super.viewDidLoad()

// Set up after loading the view.
setupRoomCaptureView()
}

private func setupRoomCaptureView() {
roomCaptureView = RoomCaptureView(frame: view.bounds)
roomCaptureView.captureSession.delegate = self
roomCaptureView.delegate = self

view.insertSubview(roomCaptureView, at: 0)
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
startSession()
}

override func viewWillDisappear(_ flag: Bool) {
super.viewWillDisappear(flag)
stopSession()
}

private func startSession() {
roomCaptureView?.captureSession.run(configuration: roomCaptureSessionConfig)
}

private func stopSession() {
roomCaptureView?.captureSession.stop()
}
}

我们可以通过遵循RoomCaptureViewDelegate协议,选择扫描结束后是否要进行后期优化处理,以及存储和导出USDZ文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class RoomCaptureViewController: UIViewController, RoomCaptureViewDelegate{
// ...
private var finalResults: CapturedRoom?

// 选择扫描结束后是否要进行后期处理
func captureView(shouldPresent roomDataForProcessing: CapturedRoomData, error: Error?) -> Bool {
return true
}

// 选择最终模型如何处理
func captureView(didPresent processedResult: CapturedRoom, error: Error?) {
// 存储以便后期使用
finalResults = processdResult
// 或者导出
try processdResult.export(to: destinationURL)
}
}

以上就是RoomCaptureView的完整使用,通过简短的代码就能创建房间空间的模型。

不足

对我来说RoomPlan最大的不足在于纹理上,扫描出来的模型文件没有纹理数据。当然这应该也是苹果对这个产品的定位问题吧,也是出于性能和当前实现的效果考量吧。另外,RoomPlan当前还存在一些测量尺寸不准确的bug,以及一些识别不对的bug