通过代码配置 mesh observers
本文将讨论一些关键机制和api,以编程方式配置空间感知系统和相关的 Mesh Observer data providers。
访问 mesh observers
mesh observers类实现了IMixedRealitySpatialAwarenessMeshObserver
接口,为空间感知系统提供特定平台的网格数据。可以在空间感知配置文件中配置多个Observers。
访问空间感知系统的数据提供者与访问任何其他混合现实工具箱服务基本相同。必须将空间感知服务绑定到IMixedRealityDataProviderAccess
接口,通过GetDataProvider<T>
api进行访问,然后可以使用该api在运行时直接访问Mesh Observer对象。
// 使用核心服务来快速访问 IMixedRealitySpatialAwarenessSystem
var spatialAwarenessService = CoreServices.SpatialAwarenessSystem;
// 转换到 IMixedRealityDataProviderAccess 以访问 data providers
var dataProviderAccess = spatialAwarenessService as IMixedRealityDataProviderAccess;
var meshObserver = dataProviderAccess.GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
The CoreServices.GetSpatialAwarenessSystemDataProvider<T>()
helper simplifies this access pattern as demonstrated below.
// 获得第一个可用 Mesh Observer , 通常我们只注册一个
var meshObserver = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
// 获取 SpatialObjectMeshObserver
var meshObserverName = "Spatial Object Mesh Observer";
var spatialObjectMeshObserver = dataProviderAccess.GetDataProvider<IMixedRealitySpatialAwarenessMeshObserver>(meshObserverName);
开始和停止 mesh observation
在处理空间感知系统时,最常见的任务之一是在运行时动态地关闭/打开该特性。这样做是每个Observers通过IMixedRealitySpatialAwarenessObserver.Resume
和 IMixedRealitySpatialAwarenessObserver.Suspend
APIs。
// 获得第一个可用 Mesh Observer , 通常我们只注册一个
var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
// 暂停空间网格数据的观察
observer.Suspend();
// 恢复空间网格数据的观察
observer.Resume();
还可以通过直接通过空间感知系统进行访问来简化此代码功能。
var meshObserverName = "Spatial Object Mesh Observer";
CoreServices.SpatialAwarenessSystem.ResumeObserver<IMixedRealitySpatialAwarenessMeshObserver>(meshObserverName);
开始和停止所有mesh observation
在应用程序中启动/停止所有mesh observation通常很方便。这可以通过有用的空间感知系统APIs, ResumeObservers()
和 SuspendObservers()
.
// 恢复所有Observers的网格观察
CoreServices.SpatialAwarenessSystem.ResumeObservers();
// 暂停所有Observers的网格观察
CoreServices.SpatialAwarenessSystem.SuspendObservers();
枚举和访问网格
每个Observers都可以访问网格,然后对其枚举
Mesh Observer通过IMixedRealitySpatialAwarenessMeshObserver
API知道网格。
如果在editor中运行,可以使用AssetDatabase.CreateAsset()
将Mesh
对象保存到一个资源文件中。
如果在设备上运行,有许多社区和存储插件可用于将MeshFilter
数据序列化为模型文件类型(OBJ示例)。
// 获得第一个可用 Mesh Observer , 通常我们只注册一个
var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
// 遍历所有已知的网格
foreach (SpatialAwarenessMeshObject meshObject in observer.Meshes.Values)
{
Mesh mesh = meshObject.Filter.mesh;
// 对网格对象做一些操作
}
显示和隐藏空间网格
可以使用以下示例代码隐藏/显示网格:
// 获得第一个可用 Mesh Observer , 通常我们只注册一个
var observer = CoreServices.GetSpatialAwarenessSystemDataProvider<IMixedRealitySpatialAwarenessMeshObserver>();
// 设置为不可见
observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.None;
// 设置为可见和遮挡材质
observer.DisplayOption = SpatialAwarenessMeshDisplayOptions.Occlusion;
注册 mesh observation events
组件可以实现IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessMeshObject>
,然后向空间感知系统注册以接收 Mesh Observation events.
DemoSpatialMeshHandler
(Assets/MRTK/Examples/Demos/SpatialAwareness/Scripts)脚本是一个有用的例子,也是侦听Mesh Observer events的起点。
这是一个简单的例子 DemoSpatialMeshHandler脚本和Mesh Observation event监听。
// 简化类型
using SpatialAwarenessHandler = IMixedRealitySpatialAwarenessObservationHandler<SpatialAwarenessMeshObject>;
public class MyMeshObservationExample : MonoBehaviour, SpatialAwarenessHandler
{
private void OnEnable()
{
// Register组件监听Mesh Observation events,通常在OnEnable()中完成
CoreServices.SpatialAwarenessSystem.RegisterHandler<SpatialAwarenessHandler>(this);
}
private void OnDisable()
{
//从Mesh Observation events注销组件,通常在OnDisable()中完成
CoreServices.SpatialAwarenessSystem.UnregisterHandler<SpatialAwarenessHandler>(this);
}
public virtual void OnObservationAdded(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData)
{
// Do stuff
}
public virtual void OnObservationUpdated(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData)
{
// Do stuff
}
public virtual void OnObservationRemoved(MixedRealitySpatialAwarenessEventData<SpatialAwarenessMeshObject> eventData)
{
// Do stuff
}
}