我有一个用C ++ / WinRT编写的Hololens应用程序,该应用程序使用SpatialSurfaceObserver
查询空间表面。为此,应用程序响应ObservedSurfacesChanged
事件,并运行一个函数,该函数获取带有GetObservedSurfaces
的空间网格列表。然后,为每个条目构建并渲染一个网格。
我在致电GetObservedSurfaces
时遇到问题。测量表明,它通常运行120-140毫秒。应用程序启动后的前几次运行需要将近500毫秒。就其本身而言,这是可以接受的。但是,该调用似乎会阻塞整个应用程序,直到返回为止,这将导致渲染循环丢失几帧,从而破坏用户体验。 MyApp::UpdateSpatialMeshes
运行时,没有锁定会冻结应用程序。如果我将呼叫auto surfaces = observer.GetObservedSurfaces();
替换为一秒钟的简单等待(并根据surfaces
注释掉所有内容),一切都很好,不会发生丢帧现象。
有人知道为什么GetObservedSurfaces
会阻止我的应用程序,或者我该怎么做才能更正确地使用它?
更新:大约有。返回的集合中有40个曲面网格,包含约10万个三角形。
初始化:
winrt::Windows::Foundation::IAsyncAction MyApp::InitSurfaceObserver()
{
co_await winrt::resume_background();
auto status = co_await SpatialSurfaceObserver::RequestAccessAsync();
if (status == SpatialPerceptionAccessStatus::Allowed)
{
auto coordSys = m_stationaryReferenceFrame.CoordinateSystem();
m_surfaceObserver = SpatialSurfaceObserver();
m_surfaceObserver.ObservedSurfacesChanged([this](auto&& sender, auto&& args)
{
UpdateSpatialMeshes(m_surfaceObserver, coordSys); // runs in background
});
SpatialBoundingBox aabb = { { 0.0f, 0.0f, 0.0f }, { 20.0f, 20.0f, 5.0f } };
auto bounds = SpatialBoundingVolume::FromBox(coordSys, aabb);
m_surfaceObserver.SetBoundingVolume(bounds);
}
// else: complain
}
处理:
winrt::fire_and_forget MyApp::UpdateSpatialMeshes(const SpatialCoordinateSystem& coordSys,
const SpatialSurfaceObserver& observer)
{
if (coordSys /* AND no other UpdateSpatialMeshes is currently running*/)
{
SpatialCoordinateSystem scs{ coordSys }; // back up the coordinate system
co_await winrt::resume_background();
auto surfaces = observer.GetObservedSurfaces(); // <<< FREEZES EVERYTHING
for (auto const& pair : surfaces)
{
const GUID& id = pair.Key();
auto surfaceInfo = pair.Value();
if (!surfaceInfo) continue;
// TryComputeLatestMeshAsync, then render
}
}
}