HoloToolkit项目是一组开发包,是微软基于unity内置的底层API封装的一套工具集合,帮助我们快速使用Unity集成开发hololens应用。

本文主要通过源码研究其中Spatial Mapping的实现,学会如何使用实现自己的三维空间重建。

0x00 组件结构


Spatial Mapping目录下有很多内容,其中Prefabs目录里有我们可以直接使用的预置组件,本文关注的重点是Scripts目录的脚本。组件目录结构如下:

本文重点研究SpatialMappingObserver.cs和SpatialMappingSource.cs,这是当前组件的核心内容。

0x01 SpatialMappingObserver.cs


源码地址:https://github.com/Microsoft/HoloToolkit-Unity/blob/master/Assets/HoloToolkit/SpatialMapping/Scripts/SpatialMappingObserver.cs

我们先分析其属性,如下:

[代码]:

01 //每立方米网格三角形数量,控制mesh质量
02         public float TrianglesPerCubicMeter = 500f;
03  
04        //当前Observer检测的空间范围
05         public Vector3 Extents = Vector3.one * 10.0f;
06  
07         //刷新时间间隔
08         public float TimeBetweenUpdates = 3.5f;
09  
10         //用于扫描空间平面的核心组件
11         private SurfaceObserver observer;
12  
13         //存储已构建的空间网格对象
14         private Diction<a href="http://www.52vr.com/armr/" style="font-weight: bold;color: ;" target="_blank">AR</a>y<int, gameobject=""> surfaces = new Dictionary<int, gameobject="">();
15  
16         //SurfaceData队列,用于生成空间mesh
17         private Queue<surfacedata> surfaceWorkQueue = new Queue<surfacedata>();
18  
19         //为了避免同一时刻生成太多mesh,保证同一时刻只生成一个mesh,这个变量用于判断当前时刻是否有mesh正在创建
20         private bool surfaceWorkOutstanding = false;
21  
22         //用于追踪Observer对象上次更新时间
23         private float updateTime;
24  
25         //表示当前扫描状态,Running和Stopped两种状态
26         public ObserverStates ObserverState { getprivate set; }</surfacedata></surfacedata></int,></int,>

再分析其程序逻辑及流程:

  • Awake()方法最先被执行,这里对SurfaceObserver对象进行了初始化。

[代码]:

1 private void Awake()
2        {
3            observer = new SurfaceObserver();
4            ObserverState = ObserverStates.Stopped;
5        }

  • 接下来是Start()方法,里面设定了扫描的空间范围。

[代码]:

1 private void Start()
2         {
3             observer.SetVolumeAsAxisAlignedBox(Vector3.zero, Extents);
4         }

  • Update()方法中则会根据当前状态来调用API请求空间表面信息或者生成mesh对象

[代码]:

01 private void Update()
02         {
03              
04             if (ObserverState == ObserverStates.Running)
05             {
06                 // 如果当前没有再生成mesh,且SurfaceData中有需要生成mesh的对象
07                 if (surfaceWorkOutstanding == false && surfaceWorkQueue.Count > 0)
08                 {
09                      
10                     SurfaceData surfaceData = surfaceWorkQueue.Dequeue();
11  
12                     // 如果能成功请求到mesh对象,当前任务状态变为生成mesh中
13                     surfaceWorkOutstanding = observer.RequestMeshAsync(surfaceData, SurfaceObserver_OnDataReady);
14                 }
15                 //如果当前没有任务运行且上次更新距现在大于时间间隔,则重新请求SurfaceData数据
16                 else if (surfaceWorkOutstanding == false && (Time.time - updateTime) >= TimeBetweenUpdates)
17                 {
18                     observer.Update(SurfaceObserver_OnSurfaceChanged);
19                     updateTime = Time.time;
20                 }
21             }
22         }

  • SurfaceObserver_OnDataReady()事件方法用于处理使用SurfaceData请求到的mesh对象信息,用于后续的使用,比如处理其材质效果等。

[代码]:

01 private void SurfaceObserver_OnDataReady(SurfaceData cookedData, bool outputWritten, float elapsedCookTimeSeconds)
02         {
03             GameObject surface;
04             if (surfaces.TryGetValue(cookedData.id.handle, out surface))
05             {
06                 // 设置 renderer组件的材质.
07                 MeshRenderer renderer = surface.GetComponent<meshrenderer>();
08                 renderer.sharedMaterial = SpatialMappingManager.Instance.SurfaceMaterial;
09                 //是否渲染mesh对象
10                 renderer.enabled = SpatialMappingManager.Instance.DrawVisualMeshes;
11  
12                 if (SpatialMappingManager.Instance.CastShadows == false)
13                 {
14                     renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
15                 }
16             }
17  
18             surfaceWorkOutstanding = false;
19         }</meshrenderer>

  • SurfaceObserver_OnSurfaceChanged()事件方法用于处理SurfaceObserver获取到的空间表面数据,用于后续的请求mesh对象操作。

[代码]:

view source print?
01 private void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
02         {
03             // 判断当前扫描状态
04             if (ObserverState != ObserverStates.Running)
05             {
06                 return;
07             }
08  
09             GameObject surface;
10  
11             switch (changeType)
12             {
13                  
14                 case SurfaceChange.Added:
15                 case SurfaceChange.Updated:
16                     // 检测当前表面是否已被扫描过
17                     if (!surfaces.TryGetValue(id.handle, out surface))
18                     {
19                         // 创建一个和当前表面关联的mesh对象
20                         surface = AddSurfaceObject(nullstring.Format("Surface-{0}", id.handle), transform);
21  
22                         surface.AddComponent<worldanchor>();
23  
24                         // 将surface对象加入已知空间表面字典
25                         surfaces.Add(id.handle, surface);
26                     }
27  
28                     // 请求生成或更新对应的mesh对象
29                     QueueSurfaceDataRequest(id, surface);
30                     break;
31  
32                 case SurfaceChange.Removed:
33                     // 移除关联的mesh对象
34                     if (surfaces.TryGetValue(id.handle, out surface))
35                     {
36                         surfaces.Remove(id.handle);
37                         Destroy(surface);
38                     }
39                     break;
40             }
41         }</worldanchor>
本文转自:52VR.com  Hololens http://www.52vr.com/article-794-1.html

Hololens Spatial Mapping功能实现相关推荐

  1. Unity中实现Hololens的三维空间映射Spatial mapping

    hololens最出色的功能就是他对环境的空间扫描和重建功能,在unity的Hololens示例中,有完整的三维重建代码,本文主要讨论如何在Unity项目中集成空间映射功能.Unity内置了对空间映射 ...

  2. [洪流学堂]Hololens开发高级篇5:空间映射(Spatial mapping)

    本教程基于Unity2017.2及Visual Studio 2017 本教程编写时间:2017年12月16日 本文内容提要 空间映射让holograms了解周围环境,将真实世界和虚拟世界更好地结合在 ...

  3. Hololens 开发笔记(2)——Spatial Mapping

    原文链接:Hololens 开发笔记(11)--Spatial Mapping_Jitwxs的博客-CSDN博客 Hololens 作为一款混合现实设备,其与传统 VR/AR 设备最大的区别是,能够和 ...

  4. Hololens官方教程精简版 - 07. Spatial mapping(空间映射)

    前言 注意:本文已更新到5.5.1f1版本 个人建议,学习Holograms 230之前,一定完成<Hololens官方教程精简版 - 02. Introduction with Device& ...

  5. SAP ABAP实用技巧介绍系列之 使用simple transformation的mapping功能

    Created by Jerry Wang, last modified on Jun 25, 2014 Simple transformation如下: 当node VALTO_DATE的value ...

  6. HoloLens开发与性能优化实践

    HoloLens中国版终于于5月底在中国上市,同时国内的技术社区经过一年的成长也有了很大的扩张,越来越多的开发者开始进入了HoloLens开发领域,尝试着使用混合现实(Mixed Reality)技术 ...

  7. [洪流学堂]Hololens开发入门篇3:使用基本功能开发一个小应用

    本文首发于"洪流学堂"公众号. 洪流学堂,让你快人几步 本教程基于Unity2017.2及Visual Studio 2017 本教程编写时间:2017年12月4日 本文内容提要 ...

  8. HoloLens开发之远程视频AR标注功能开发

    HoloLens2系统自带的软件中包含的官方开发的Dynamics 365 Remote Assist软件,想必大部分用户及开发者看过官方的宣传视频,通过移动端和HoloLens视频通话进行远程协作, ...

  9. HoloLens开发手记 - Unity development overview 使用Unity开发概述

    Unity Technical Preview for HoloLens最新发行版为:Beta 24,发布于 09/07/2016 开始使用Unity开发HoloLens应用之前,确保你已经安装好了必 ...

最新文章

  1. 自学python的网站-python有哪些学习网站
  2. 五边形创意画_绝了,自己做吊灯,创意满满!不仅好看还省钱!
  3. 炫界 (978) -(建工发现应用克隆漏)_湖南建工装配式建筑迈入“加速度”
  4. python从数分到数编(part1)--基础
  5. linux系统启动流程及常见问题的解决
  6. 可视化:动态气泡图,拿走不谢!
  7. 对服务与工厂感到困惑
  8. 如何调用showapiRequest解决图片验证码识别?
  9. 网站创业项目商业计划书的写法
  10. 下载百度网盘资源不限速的两种方法
  11. Lotka–Volterra equation Competitive Lotka–Volterra equations
  12. 新款苹果手机_售价千元!苹果今日推出新款手机壳,买吗
  13. msi 微星b350 tomahawk主板 刷bios教程
  14. python嵌入式系统开发_图解嵌入式系统开发之语言篇:初识Python
  15. 淘宝教育视频加速观看(在淘宝教育上看学习视频,需要加速,在谷歌浏览器上安装视频加速插件)
  16. Python项目--批量下载小姐姐壁纸
  17. userdel删除用户时候提示:userdel: user xx is currently logged in
  18. nba2k14mod android,nba2k14安卓mod
  19. 计算机二级C语言操作题怎么做?注意事项(难点易错点总结笔记)
  20. XiaoHu日志 11/22~12/3

热门文章

  1. 在AngularJS中读取查询参数的最简洁方法是什么?
  2. 企业应用程序部署在iOS 7.1上不起作用
  3. 如何从文件的完整路径获取目录?
  4. Akka实战:HTTP大文件断点上传、下载,秒传
  5. K-近邻(KNN)算法
  6. 【推荐】大型网站图片服务器架构的演进
  7. sybase笔记 2762错误
  8. OC实例变量和属性-@synthesize与@property
  9. sql server datetime转char的方法
  10. 批量插入数据的存储过程