You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++/WinRT从SpatialSurfaceMesh的IBuffer获取顶点位置遇问题

问题:HoloLens C++/WinRT项目提取SpatialSurfaceMesh顶点数据的错误与异常结果

一、IBuffer转换时的越界访问错误

开发基于C++/WinRT的HoloLens项目时,需从SpatialSurfaceMesh::VertexPositions()返回的IBuffer中提取顶点位置数据。参考全息空间映射示例项目(实现网格IBuffer数据渲染),将示例中的C++/CX版本GetDataFromIBuffer函数转换为C++/WinRT版本:

template <typename t = byte>
t* GetDataFromIBuffer(IBuffer container)
{
    if (container == nullptr)
    {
        return nullptr;
    }

    unsigned int bufferLength = container.Length();

    if (!(bufferLength > 0))
    {
        return nullptr;
    }

    HRESULT hr = S_OK;

    Microsoft::WRL::ComPtr<IUnknown> pUnknown = reinterpret_cast<IUnknown*>(&container);
    Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> spByteAccess;
    hr = pUnknown.As(&spByteAccess);
    if (FAILED(hr))
    {
        return nullptr;
    }

    byte* pRawData = nullptr;
    hr = spByteAccess->Buffer(&pRawData);
    if (FAILED(hr))
    {
        return nullptr;
    }

    return reinterpret_cast<t*>(pRawData);
}

运行时触发错误:Unhandled exception at 0x00007FF985543848 (ntdll.dll) in Project.exe: RangeChecks instrumentation code detected an out of range array access.,错误发生在Microsoft::WRL::ComPtr<IUnknown> pUnknown = reinterpret_cast<IUnknown*>(&container);行的转换操作中。

尝试另一种实现方式:

byte* GetDataFromIBuffer(IBuffer container)
{
    if (container == nullptr)
    {
        return nullptr;
    }

    unsigned int bufferLength = container.Length();

    if (!(bufferLength > 0))
    {
        return nullptr;
    }

    HRESULT hr = S_OK;

    IUnknown* pUnk = reinterpret_cast<IUnknown*>(&container);
    Windows::Storage::Streams::IBufferByteAccess * spByteAccess = nullptr;
    hr = pUnk->QueryInterface(IID_PPV_ARGS(&spByteAccess));
    if (FAILED(hr))
    {
        return nullptr;
    }

    byte* pRawData = nullptr;
    hr = spByteAccess->Buffer(&pRawData);
    if (FAILED(hr))
    {
        return nullptr;
    }

    return reinterpret_cast<byte*>(pRawData);
}

仍出现相同错误,错误位置变为hr = pUnk->QueryInterface(IID_PPV_ARGS(&spByteAccess));行。

二、修复转换错误后顶点数据不符合空间逻辑

经IInspectable解答后,转换代码不再报错,但获取的顶点位置结果不符合空间逻辑。后续处理代码如下:

auto position = surfaceMesh.second->VertexPositions();
auto stride = position.Stride();
auto scale = surfaceMesh.second->VertexPositionScale();
auto positionCoordinateSystem = surfaceMesh.second->CoordinateSystem();

auto transform = positionCoordinateSystem.TryGetTransformTo(currentCoordinateSystem).Value();

...
// 在循环中:

auto rawData = GetDataFromIBuffer(position.Data());

float x = BytesToShort(rawData + i) / scale.x;
i += stride;
float y = BytesToShort(rawData + i) / scale.y;
i += stride;
float z = BytesToShort(rawData + i) / scale.z;
i += stride * 2;

float3 vertex = MultVectByMat({ x, y, z }, transform);

得到的结果存在不合理值,例如z=5,意味着设备检测到自身后方5米处有表面,与实际情况不符。


内容的提问来源于stack exchange,提问作者Nikow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 08:02:48