HoloLens开发手记 - Unity之Spatial mapping 空间映射
本文主要讨论如何在Unity项目中集成空间映射功能。Unity内置了对空间映射功能的支持,通过以下两种方式提供给开发者:
- HoloToolkit项目中你可以找到空间映射组件,这可以让你便捷快速地开始使用空间映射特性。
- Unity还提供更多底层的空间映射API,以便开发者能够完全控制空间映射特性,满足定制复杂的应用需求
为了在应用使用空间映射特性,你必须在应用权限清单中启用SpatialPerception能力。
Setting the SpatialPerception capability 设置SpatialPerception能力
为了使应用能够使用空间映射数据,SpatialPerception能力必须被启用。
使用以下步骤启用此能力:
- 在Unity编辑器中,进入Player Settings选项(Edit > Project Settings > Player)
- 点击Window Store选项卡
- 展开Publish Settings选项,并在Capabilities列表勾选SpatialPerception选项
注意:如果你已经把Unity项目导出为Visual Studio项目,你需要重新导出修改后的项目到新文件夹或者手动在VS中修改AppxManifest应用清单。
空间映射特性也要求项目MaxVersionTested版本最低为10.0.10586.0:
- 在VS项目解决方案中,双击Package.appxmanifest文件,并右键选中查看源码方式打开
- 找到TargetDeviceFamily这一行,并将MaxVersionTested="10.0.10240.0" 修改为 MaxVersionTested="10.0.10586.0"
- 保存Package.appmanifest文件
Spatial mapping components 空间映射组件
HoloToolkit项目提供了几个方案帮助你简单快速集成空间映射特性。
对于默认的空间映射需求,我们推荐使用SpatialMappingComponent目录下的 SpatialMappingCollider.cs 和 SpatialMapppingRenderer.cs脚本。如果你需要从网络或者文件载入空间网格,可以使用SpatialMapping目录下的脚本。
额外的信息可以在HoloToolkit项目Github主页上找到。
How to use the API 如何使用底层API
命名空间: UnityEngine.VR.WSA
类型: SurfaceObserver, SurfaceChange, SurfaceData, SurfaceId
SurfaceObserver是主要使用到的API对象,下面是应用使用空间映射特性推荐的大致流程。
Set up the SurfaceObserver(s) 设定SurfaceObserver对象
你要为每一个需要空间映射数据的空间区域在应用中初始化一个SurfaceObserver对象。
SurfaceObserver surfaceObserver; void Start () {
surfaceObserver = new SurfaceObserver();
}
通过调用SetVolumeAsSphere、SetVolumeAsAxisAlignedBox、 SetVolumeAsOrientedBox、 或 SetVolumeAsFrustum方法可以为每个SurfaceObserver对象指定它们需要获取数据的空间范围。以后你还可以通过再次调用它们来重新设定检测的空间范围。
void Start () {
...
surfaceObserver.SetVolumeAsAxisAlignedBox(Vector3.zero, new Vector3(, , ));
}
当你调用SurfaceObserver.Update()方法时,需要每一个SurfaceObserver对象检测区域中的空间表面(spatial surface)指定事件处理方法。
private void OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
{
//处理空间表面变化
}
Handling Surface Changes 处理空间表面变化
关于空间表面变化,有几个典型情形需要处理。Added状态和Updated状态可以使用相同的代码处理,Removed状态则使用另一种代码来处理。
- 在Added和Updated情形下,我们从字典中添加或者获取代码当前网格的对象,使用必要的组件来创建一个SurfaceData结构体,然后调用RequestMeshDataAsync方法在场景中使用网格数据和位置来填充对象。
- 在Removed情形下,我们从字典中移除当前网格代表的对象并销毁它。
System.Collections.Generic.Dictionary<SurfaceId, GameObject> spatialMeshObjects = new System.Collections.Generic.Dictionary<SurfaceId, GameObject>(); private void OnSurfaceChanged(SurfaceId surfaceId, SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
{
switch (changeType)
{
case SurfaceChange.Added:
case SurfaceChange.Updated:
if (!spatialMeshObjects.ContainsKey(surfaceId))
{
spatialMeshObjects[surfaceId] = new GameObject("spatial-mapping-" + surfaceId);
spatialMeshObjects[surfaceId].transform.parent = this.transform;
spatialMeshObjects[surfaceId].AddComponent<MeshRenderer>();
}
GameObject target = spatialMeshObjects[surfaceId];
SurfaceData sd = new SurfaceData(
//系统返回的surface id,
//当前对象的MeshFilter组件
target.GetComponent<MeshFilter>() ?? target.AddComponent<MeshFilter>(),
//用于在空间中定位对象的空间锚
target.GetComponent<WorldAnchor>() ?? target.AddComponent<WorldAnchor>(),
//当前网格对象的MeshCollider组件
target.GetComponent<MeshCollider>() ?? target.AddComponent<MeshCollider>(),
//每立方米网格三角形的数量
,
//bakeMeshes -如果是true,MeshCollider会被数据填充,反之MeshCollider为空
true
); SurfaceObserver.RequestMeshAsync(sd, OnDataReady);
break;
case SurfaceChange.Removed:
var obj = spatialMeshObjects[surfaceId];
spatialMeshObjects.Remove(surfaceId);
if (obj != null)
{
GameObject.Destroy(obj);
}
break;
default:
break;
}
}
Handing Data Ready 处理DataReady事件
OnDataReady事件方法会接收到一个SurfaceData对象,它包含了WorldAnchor、MeshFilter和MeshCollider对象数据,表示了当前关联的空间表面最新状态。通过访问Mesh Filter对象的Mesh数据可以进行性能分析或者处理网格。使用最新的Mesh数据来渲染空间表面并将它用于物理碰撞或者射线击中对象。确认SurfaceData内容不为空很重要。
Start processing on updates 处理更新操作
SurfaceObserver.Update()方法只能延时调用,可以每帧更新都调用。
void Start () {
...
StartCoroutine(UpdateLoop());
} IEnumerator UpdateLoop()
{
var wait = new WaitForSeconds(2.5f);
while(true)
{
surfaceObserver.Update(OnSurfaceChanged);
yield return wait;
}
}
HoloToolKit
HoloToolkit项目是基于Unity API封装的一系列很有用的全息开发代码工具集合,能帮助开发者快速集成HoloLens特性。
Troubleshooting 问题诊断
确保你启用了 SpatialPreception能力
- 当追踪焦点丢失时,在接下来的OnSurfaceChanged事件处理中将会移除现有所有的网格。
HoloLens开发手记 - Unity之Spatial mapping 空间映射的更多相关文章
- HoloLens开发手记 - Unity之Spatial Sounds 空间声音
本文主要讲述如何在项目中使用空间声音特性.我们主要讲述必须的插件组件和Unity声音组件和属性的设置来确保空间声音的实现. Enabling Spatial Sound in Unity 在Unity ...
- HoloLens开发手记 - Unity之World Anchor空间锚
World Anchor空间锚提供了一种能够将物体保留在特定位置和旋转状态上的方法.这保证了全息对象的稳定性,同时提供了后续在真实世界中保持全息对象位置的能力.简单地说,你可以为全息物体来添加空间锚点 ...
- HoloLens开发手记 - Unity development overview 使用Unity开发概述
Unity Technical Preview for HoloLens最新发行版为:Beta 24,发布于 09/07/2016 开始使用Unity开发HoloLens应用之前,确保你已经安装好了必 ...
- HoloLens开发手记 - Unity之Recommended settings 推荐设置
Unity提供了大量的设置选项来满足全平台的配置,对于HoloLens,Unity可以通过切换一些特定的设置来启用HoloLens特定的行为. Holographic splash screen 闪屏 ...
- HoloLens开发手记 - Unity之场景共享 Shared holographic experiences in Unity
佩戴HoloLens的多个用户可以使用场景共享特性来获取集合视野,并可以与固定在空间中某个位置的同一全息对象进行交互操作.这一切是通过空间锚共享(Anchor Sharing)来实现的. 为了使用共享 ...
- HoloLens开发手记 - Unity之摄像头篇
当你穿戴好HoloLens后,你就会处在全息应用世界的中心.当你的项目开启了"Virtual Reality Support"选项并选中了"Windows Hologra ...
- HoloLens开发手记 - Unity之Persistence 场景保持
Persistence 场景保持是HoloLens全息体验的一个关键特性,当用户离开原场景中时,原场景中全息对象会保持在特定位置,当用户回到原场景时,能够准确还原原场景的全息内容.WorldAncho ...
- HoloLens开发手记 - Unity之Tracking loss
当HoloLens设备不能识别到自己在世界中的位置时,应用就会发生tracking loss.默认情况下,Unity会暂停Update更新循环并显示一张闪屏图片给用户.当设备重新能追踪到位置时,闪屏图 ...
- HoloLens开发手记 - Unity之Gaze凝视射线
凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象.然而在Unity中并没有明确的Gaze API或者组件. 实现Gaze Implementing Gaze 概念 ...
随机推荐
- .net WEB程序访问locahost和IP使用
1.服务都在本机调用用 localost 2.部署站点访问时用ip
- .net串口通信
背景: 前一段时间需要写一个向蓝牙模块发消息的功能. 对蓝牙的机制不太了解,所以一直在查资料, 但始终没找到我需要的东西,还误以为需要配套的一套开发模板和开发包, 偶然间发现只需要简单的串口通信,并且 ...
- Spring学习笔记之 Spring IOC容器(二) 之注入参数值,自动组件扫描方式,控制Bean实例化方式,使用注解方式
本节主要内容: 1. 给MessageBean注入参数值 2. 测试Spring自动组件扫描方式 3. 如何控制ExampleBean实例化方式 4. 使用注解方式重构Jdb ...
- spring 容器加载完成后执行某个方法
理论 刚好再开发过程中遇到了要在项目启动后自动开启某个服务,由于使用了spring,我在使用了spring的listener,它有onApplicationEvent()方法,在Spring容器将所有 ...
- Add Binary
Add Binary https://leetcode.com/problems/add-binary/ Given two binary strings, return their sum (als ...
- HDU 1878 欧拉回路
并查集水题. 一个图存在欧拉回路的判断条件: 无向图存在欧拉回路的充要条件 一个无向图存在欧拉回路,当且仅当该图所有顶点度数都是偶数且该图是连通图. 有向图存在欧拉回路的充要条件 一个有向图存在欧拉回 ...
- RMQ之ST算法模板
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; ; ],M ...
- C/C++学习----使用C语言代替cmd命令、cmd命令大全
[开发环境] 物理机版本:Win 7 旗舰版(64位) IDE版本:Visual Studio 2013简体中文旗舰版(cn_visual_studio_ultimate_2013_with_upda ...
- 定制你的Unity编辑器
Unity的编辑器可以通过写脚本进行界面定制,包括添加功能菜单,今天写游戏Demo用到了记录一下. 为Unity添加子菜单 示例程序 [AddComponentMenu("Defend Ho ...
- Linux下php安装memcache扩展
安装环境:CentOS 6.4 php扩展memcache的作用是为了支持memcached数据库缓存服务器,下面是安装方法. 1.下载 下载地址:http://pecl.php.net/packag ...