本文主要讨论如何在Unity项目中集成空间映射功能。Unity内置了对空间映射功能的支持,通过以下两种方式提供给开发者:

  1. HoloToolkit项目中你可以找到空间映射组件,这可以让你便捷快速地开始使用空间映射特性。
  2. Unity还提供更多底层的空间映射API,以便开发者能够完全控制空间映射特性,满足定制复杂的应用需求

为了在应用使用空间映射特性,你必须在应用权限清单中启用SpatialPerception能力。

Setting the SpatialPerception capability 设置SpatialPerception能力


为了使应用能够使用空间映射数据,SpatialPerception能力必须被启用。

使用以下步骤启用此能力:

  1. 在Unity编辑器中,进入Player Settings选项(Edit > Project Settings > Player)
  2. 点击Window Store选项卡
  3. 展开Publish Settings选项,并在Capabilities列表勾选SpatialPerception选项

注意:如果你已经把Unity项目导出为Visual Studio项目,你需要重新导出修改后的项目到新文件夹或者手动在VS中修改AppxManifest应用清单

空间映射特性也要求项目MaxVersionTested版本最低为10.0.10586.0

  1. 在VS项目解决方案中,双击Package.appxmanifest文件,并右键选中查看源码方式打开
  2. 找到TargetDeviceFamily这一行,并将MaxVersionTested="10.0.10240.0" 修改为 MaxVersionTested="10.0.10586.0"
  3. 保存Package.appmanifest文件

Spatial mapping components 空间映射组件


HoloToolkit项目提供了几个方案帮助你简单快速集成空间映射特性。

对于默认的空间映射需求,我们推荐使用SpatialMappingComponent目录下的 SpatialMappingCollider.csSpatialMapppingRenderer.cs脚本。如果你需要从网络或者文件载入空间网格,可以使用SpatialMapping目录下的脚本。

额外的信息可以在HoloToolkit项目Github主页上找到。

How to use the API 如何使用底层API


命名空间UnityEngine.VR.WSA

类型: SurfaceObserverSurfaceChangeSurfaceDataSurfaceId

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 空间映射的更多相关文章

  1. HoloLens开发手记 - Unity之Spatial Sounds 空间声音

    本文主要讲述如何在项目中使用空间声音特性.我们主要讲述必须的插件组件和Unity声音组件和属性的设置来确保空间声音的实现. Enabling Spatial Sound in Unity 在Unity ...

  2. HoloLens开发手记 - Unity之World Anchor空间锚

    World Anchor空间锚提供了一种能够将物体保留在特定位置和旋转状态上的方法.这保证了全息对象的稳定性,同时提供了后续在真实世界中保持全息对象位置的能力.简单地说,你可以为全息物体来添加空间锚点 ...

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

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

  4. HoloLens开发手记 - Unity之Recommended settings 推荐设置

    Unity提供了大量的设置选项来满足全平台的配置,对于HoloLens,Unity可以通过切换一些特定的设置来启用HoloLens特定的行为. Holographic splash screen 闪屏 ...

  5. HoloLens开发手记 - Unity之场景共享 Shared holographic experiences in Unity

    佩戴HoloLens的多个用户可以使用场景共享特性来获取集合视野,并可以与固定在空间中某个位置的同一全息对象进行交互操作.这一切是通过空间锚共享(Anchor Sharing)来实现的. 为了使用共享 ...

  6. HoloLens开发手记 - Unity之摄像头篇

    当你穿戴好HoloLens后,你就会处在全息应用世界的中心.当你的项目开启了"Virtual Reality Support"选项并选中了"Windows Hologra ...

  7. HoloLens开发手记 - Unity之Persistence 场景保持

    Persistence 场景保持是HoloLens全息体验的一个关键特性,当用户离开原场景中时,原场景中全息对象会保持在特定位置,当用户回到原场景时,能够准确还原原场景的全息内容.WorldAncho ...

  8. HoloLens开发手记 - Unity之Tracking loss

    当HoloLens设备不能识别到自己在世界中的位置时,应用就会发生tracking loss.默认情况下,Unity会暂停Update更新循环并显示一张闪屏图片给用户.当设备重新能追踪到位置时,闪屏图 ...

  9. HoloLens开发手记 - Unity之Gaze凝视射线

    凝视是HoloLens首要输入方式,形式功能类似于桌面系统的光标,用于选择操作全息对象.然而在Unity中并没有明确的Gaze API或者组件. 实现Gaze Implementing Gaze 概念 ...

随机推荐

  1. PYTHON3 urllib2库

    python 3.x中urllib库和urilib2库合并成了urllib库..其中urllib2.urlopen()变成了urllib.request.urlopen() urllib2.Reque ...

  2. MongoDB 存储引擎Wiredtiger原理剖析

    今天开始看MongoDB 3.2的文档,发现了这么两句话 Support for Multiple Storage Engines MongoDB supports multiple storage ...

  3. Intent详解

    ntent组件虽然不是四大组件,但却是连接四大组件的桥梁,学习好这个知识,也非常的重要. 一.什么是Intent 1.Intent的概念: Android中提供了Intent机制来协助应用间的交互与通 ...

  4. Lua环境

    1.前言 Lua将其所有的全局变量保存在一个常规的table中,这个table称为“环境”.这种组织结构的优点在于,其一,不需要再为全局变量创造一种新的数据结构,因此简化了Lua的内部实现:另一个优点 ...

  5. mysql启动不成功显示The server quit without updating PID file的解决方法

    上午在编译安装mysql的时候 就出现标题中的错误,经实践在第二步操作后启动成功,参考链接 链接http://linuxadministrator.pro/blog/?p=225 You may fa ...

  6. SSIS ETL BEST PRACTICE

    PackageRunLog(ExecutionGuid,PackageName,SourceTableName,DestinationTableName,StartTimeUTC,EndTimeUTC ...

  7. 怎么运用ZBrush中的Z球制作身体部分

    本文主要讲解利用ZSphere[Z球]创建人体的大体轮廓,这是ZBrush®软件制作模型的第一步,这一阶段中我们需要反复调节人体比例结构,为以后深入制作打下基础,具体制作过程如下. 查看更多内容请直接 ...

  8. codeforces 713A A. Sonya and Queries(状态压缩)

    题目链接: A. Sonya and Queries time limit per test 1 second memory limit per test 256 megabytes input st ...

  9. linux --备份oracle

    1.exp\imp 导入导出命令使用exp username/pwd@sid file=path.dmp owner=user 不导出表数据:rows=n举例:exp iflashbuy/qwerwh ...

  10. [2]Telerik Extensions for ASP.NET MVC 中文教程(2)

    上一篇文章对Telerik MVC Extensions作了一个大概的介绍,这篇文章将介绍如何将Telerik MVC Extensions添加到项目中.有以下两种方式可以将Telerik MVC E ...