HoloToolkit项目源码剖析 - Spatial Mapping功能实现
就像我之前所描述的,HoloToolkit项目是微软基于Unity内置的底层API封装的一套工具集合,帮助我们快速使用Unity集成开发HoloLens应用。
本文主要通过源码研究其中Spatial Mapping的实现,关于底层的API细节,请阅读我前一篇文章:HoloLens开发手记 - Unity之Spatial mapping 空间映射
0x00 组件结构
Spatial Mapping目录下有很多内容,其中Prefabs目录里有我们可以直接使用的预置组件,本文关注的重点是Scripts目录的脚本。组件目录结构如下:
本文重点研究SpatialMappingObserver.cs和SpatialMappingSource.cs,这是当前组件的核心内容。
0x01 SpatialMappingObserver.cs
我们先分析其属性,如下:
//每立方米网格三角形数量,控制mesh质量
public float TrianglesPerCubicMeter = 500f; //当前Observer检测的空间范围
public Vector3 Extents = Vector3.one * 10.0f; //刷新时间间隔
public float TimeBetweenUpdates = 3.5f; //用于扫描空间平面的核心组件
private SurfaceObserver observer; //存储已构建的空间网格对象
private Dictionary<int, GameObject> surfaces = new Dictionary<int, GameObject>(); //SurfaceData队列,用于生成空间mesh
private Queue<SurfaceData> surfaceWorkQueue = new Queue<SurfaceData>(); //为了避免同一时刻生成太多mesh,保证同一时刻只生成一个mesh,这个变量用于判断当前时刻是否有mesh正在创建
private bool surfaceWorkOutstanding = false; //用于追踪Observer对象上次更新时间
private float updateTime; //表示当前扫描状态,Running和Stopped两种状态
public ObserverStates ObserverState { get; private set; }
再分析其程序逻辑及流程:
- Awake()方法最先被执行,这里对SurfaceObserver对象进行了初始化。
private void Awake()
{
observer = new SurfaceObserver();
ObserverState = ObserverStates.Stopped;
}
- 接下来是Start()方法,里面设定了扫描的空间范围。
private void Start()
{
observer.SetVolumeAsAxisAlignedBox(Vector3.zero, Extents);
}
- Update()方法中则会根据当前状态来调用API请求空间表面信息或者生成mesh对象
private void Update()
{ if (ObserverState == ObserverStates.Running)
{
// 如果当前没有再生成mesh,且SurfaceData中有需要生成mesh的对象
if (surfaceWorkOutstanding == false && surfaceWorkQueue.Count > )
{ SurfaceData surfaceData = surfaceWorkQueue.Dequeue(); // 如果能成功请求到mesh对象,当前任务状态变为生成mesh中
surfaceWorkOutstanding = observer.RequestMeshAsync(surfaceData, SurfaceObserver_OnDataReady);
}
//如果当前没有任务运行且上次更新距现在大于时间间隔,则重新请求SurfaceData数据
else if (surfaceWorkOutstanding == false && (Time.time - updateTime) >= TimeBetweenUpdates)
{
observer.Update(SurfaceObserver_OnSurfaceChanged);
updateTime = Time.time;
}
}
}
- SurfaceObserver_OnDataReady()事件方法用于处理使用SurfaceData请求到的mesh对象信息,用于后续的使用,比如处理其材质效果等。
private void SurfaceObserver_OnDataReady(SurfaceData cookedData, bool outputWritten, float elapsedCookTimeSeconds)
{
GameObject surface;
if (surfaces.TryGetValue(cookedData.id.handle, out surface))
{
// 设置 renderer组件的材质.
MeshRenderer renderer = surface.GetComponent<MeshRenderer>();
renderer.sharedMaterial = SpatialMappingManager.Instance.SurfaceMaterial;
//是否渲染mesh对象
renderer.enabled = SpatialMappingManager.Instance.DrawVisualMeshes; if (SpatialMappingManager.Instance.CastShadows == false)
{
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
}
} surfaceWorkOutstanding = false;
}
- SurfaceObserver_OnSurfaceChanged()事件方法用于处理SurfaceObserver获取到的空间表面数据,用于后续的请求mesh对象操作。
private void SurfaceObserver_OnSurfaceChanged(SurfaceId id, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
{
// 判断当前扫描状态
if (ObserverState != ObserverStates.Running)
{
return;
} GameObject surface; switch (changeType)
{ case SurfaceChange.Added:
case SurfaceChange.Updated:
// 检测当前表面是否已被扫描过
if (!surfaces.TryGetValue(id.handle, out surface))
{
// 创建一个和当前表面关联的mesh对象
surface = AddSurfaceObject(null, string.Format("Surface-{0}", id.handle), transform); surface.AddComponent<WorldAnchor>(); // 将surface对象加入已知空间表面字典
surfaces.Add(id.handle, surface);
} // 请求生成或更新对应的mesh对象
QueueSurfaceDataRequest(id, surface);
break; case SurfaceChange.Removed:
// 移除关联的mesh对象
if (surfaces.TryGetValue(id.handle, out surface))
{
surfaces.Remove(id.handle);
Destroy(surface);
}
break;
}
}
HoloToolkit项目源码剖析 - Spatial Mapping功能实现的更多相关文章
- java crm 进销存 springmvc SSM 项目 源码 系统
系统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3 SSM ...
- Java SSM 客户管理 商户 管理系统 库存管理 销售报表 项目源码
系统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3 SSM ...
- 基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析
项目简单说明 mybatis-generator,是根据数据库表.字段反向生成实体类等代码文件.我在国庆时候,没事剖析了mybatis-generator-core源码,写了相当详细的中文注释,可以去 ...
- Dubbo源码剖析六之SPI扩展点的实现之Adaptive功能实现原理
接Dubbo源码剖析六之SPI扩展点的实现之getExtensionLoader - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)继续分析Adaptive功能实现原理.Adaptive的主 ...
- 一个Python开源项目-腾讯哈勃沙箱源码剖析(上)
前言 2019年来了,2020年还会远吗? 请把下一年的年终奖发一下,谢谢... 回顾逝去的2018年,最大的改变是从一名学生变成了一位工作者,不敢说自己多么的职业化,但是正在努力往那个方向走. 以前 ...
- 【java集合框架源码剖析系列】java源码剖析之HashMap
前言:之所以打算写java集合框架源码剖析系列博客是因为自己反思了一下阿里内推一面的失败(估计没过,因为写此博客已距阿里巴巴一面一个星期),当时面试完之后感觉自己回答的挺好的,而且据面试官最后说的这几 ...
- JS魔法堂:mmDeferred源码剖析
一.前言 avalon.js的影响力愈发强劲,而作为子模块之一的mmDeferred必然成为异步调用模式学习之旅的又一站呢!本文将记录我对mmDeferred的认识,若有纰漏请各位指正,谢谢.项目请见 ...
- 玩转Android之Picasso使用详详详详详详解,从入门到源码剖析!!!!
Picasso是Squareup公司出的一款图片加载框架,能够解决我们在Android开发中加载图片时遇到的诸多问题,比如OOM,图片错位等,问题主要集中在加载图片列表时,因为单张图片加载谁都会写.如 ...
- (升级版)Spark从入门到精通(Scala编程、案例实战、高级特性、Spark内核源码剖析、Hadoop高端)
本课程主要讲解目前大数据领域最热门.最火爆.最有前景的技术——Spark.在本课程中,会从浅入深,基于大量案例实战,深度剖析和讲解Spark,并且会包含完全从企业真实复杂业务需求中抽取出的案例实战.课 ...
随机推荐
- Effective Java 35 Prefer annotations to naming patterns
Disadvantages of naming patterns Typographical errors may result in silent failures. There is no way ...
- C#调用C++ DLL 文件
说来惭愧,都注册一年多了,却没有发表过一篇正式的博文,中间很多学习的过程也没有记录下来.如今到了一个新的环境,也有了学习的机会,一定要把每天的收获记录一下. 要做的东西需要引用C++编写的DLL,刚开 ...
- html页面识别当前系统和语言
项目中需要一个下载功能,根据系统跳转到不同的页面,如iphone跳转到IOS页面,android跳转到android页面. 下面为页面判断页面: <!DOCTYPE HTML> <h ...
- PHP正则中的捕获组与非捕获组
今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可 ...
- FAQ-Ubuntu12.04 15.04禁止移动介质自动播放
网上有有很多关于Ubuntu10.04关闭移动介质自动播放的方法,包括在文件管理器里面设置或者使用gconf-editor,但是从12.04开始这两种方法都不再好用了,关于移动介质的处理方法被移到了S ...
- Python pass语句作用与用法
Python中的pass语句作用是什么?表示它不做任何事情,一般用做占位语句.pass语句具体作用及使用方法,我们往下看. pass语句在函数中的作用 当你在编写一个程序时,执行语句部分思路还没有完成 ...
- Linux命令的类型
1.内建命令: 由shell程序自带的命令,最常见的有cd.pwd等. 使用type命令即可查看命令属于哪种,比如: #type cd cd is a shell builtin ————>看到 ...
- myeclipse中运行tomcat报错java.lang.NoClassDefFoundError
有关myeclipse的小问题,在myeclipse中运行tomcat时显示已启动,但是无法访问localhost:8080/,显示404错误.在控制台中发现报错代码如下: java.lang.NoC ...
- IOS添加手势识别
ios里面有手势识别,多点触控等功能,过去要实现手势识别很复杂,现在苹果为我们实现了,手势识别变得很简单 1.向视图添加手势识别器:(一般由controller完成,有时View也可以添加) 2.提供 ...
- jquery 地址栏链接与a标签链接匹配 特效代码总结(二)
如题所述,当出现这样的功能,点击某个链接后,给跳转后的该链接地址添加样式,通过添加class为current来增加特殊样式. 如图所示:点击HTML+css3跳转后,给其添加如图样式: js代码如下: ...