DirectX の場所を特定できるカメラLocatable camera in DirectX

このトピックでは、設定する方法を説明します、メディア ファンデーションパイプラインへのアクセスをカメラDirectX アプリで、イメージを配置することを許可するフレームのメタデータを含む、現実の世界で生成されました。This topic describes how to set up a Media Foundation pipeline to access the camera in a DirectX app, including the frame metadata that will allow you to locate the images produced in the real world.

Windows Media のキャプチャおよび Media Foundation 開発:IMFAttributesWindows Media Capture and Media Foundation Development: IMFAttributes

各イメージ フレーム座標システムを含む、2 つの重要な変換とします。Each image frame includes a coordinate system , as well as two important transforms. "View"は、カメラに指定された座標システムからのマップおよびイメージのピクセルにカメラからの「射影」マップを変換します。The "view" transform maps from the provided coordinate system to the camera, and the "projection" maps from the camera to pixels in the image. メディア ファンデーションを使用してイメージ フレームごとに、座標系と 2 つの変換は、メタデータとして埋め込まれているIMFAttributesします。The coordinate system and the 2 transforms are embedded as metadata in every image frame via Media Foundation's IMFAttributes.

MF カスタム シンクを持つ属性の読み取りとプロジェクションの実行の使用例Sample usage of reading attributes with MF custom sink and doing projection

カスタム MF シンク ストリームで (IMFStreamSink)、取得、 IMFSampleサンプル属性を持つ。In your custom MF Sink stream (IMFStreamSink), you will get IMFSample with sample attributes:

WinRT ベースのコードの次 MediaExtensions を定義する必要があります。The following MediaExtensions must be defined for WinRT based code:

EXTERN_GUID(MFSampleExtension_Spatial_CameraViewTransform, 0x4e251fa4, 0x830f, 0x4770, 0x85, 0x9a, 0x4b, 0x8d, 0x99, 0xaa, 0x80, 0x9b);
EXTERN_GUID(MFSampleExtension_Spatial_CameraCoordinateSystem, 0x9d13c82f, 0x2199, 0x4e67, 0x91, 0xcd, 0xd1, 0xa4, 0x18, 0x1f, 0x25, 0x34);
EXTERN_GUID(MFSampleExtension_Spatial_CameraProjectionTransform, 0x47f9fcb5, 0x2a02, 0x4f26, 0xa4, 0x77, 0x79, 0x2f, 0xdf, 0x95, 0x88, 0x6a);

メディア拡張機能の実装が必要ですが、WinRT Api からこれらの属性にアクセスできないIMFTransform (影響) 用またはIMFMediaSinkIMFStreamSink (カスタム シンク)。You can't access these attributes from WinRT APIs, but requires Media Extension implementation of IMFTransform (for Effect) or IMFMediaSink and IMFStreamSink (for Custom Sink). いずれかのサンプルでは、この拡張機能を処理する場合にIMFTransform::ProcessInput()/IMFTransform::ProcessOutput()またはIMFStreamSink::ProcessSample()、この例のように属性を照会することができます。When you process the sample in this extension either in IMFTransform::ProcessInput()/IMFTransform::ProcessOutput() or IMFStreamSink::ProcessSample(), you can query attributes like this sample.

ComPtr<IUnknown> spUnknown;
ComPtr<Windows::Perception::Spatial::ISpatialCoordinateSystem> spSpatialCoordinateSystem;
ComPtr<Windows::Foundation::IReference<Windows::Foundation::Numerics::Matrix4x4>> spTransformRef;
Windows::Foundation::Numerics::Matrix4x4 worldToCameraMatrix;
Windows::Foundation::Numerics::Matrix4x4 viewMatrix;
Windows::Foundation::Numerics::Matrix4x4 projectionMatrix;
UINT32 cbBlobSize = 0;
hr = pSample->GetUnknown(MFSampleExtension_Spatial_CameraCoordinateSystem, IID_PPV_ARGS(&spUnknown));
if (SUCCEEDED(hr))
{
    hr = spUnknown.As(&spSpatialCoordinateSystem);
    if (FAILED(hr))
    {
        return hr;
    }
    hr = pSample->GetBlob(MFSampleExtension_Spatial_CameraViewTransform,
                          (UINT8*)(&viewMatrix),
                          sizeof(viewMatrix),
                          &cbBlobSize);
    if (SUCCEEDED(hr) && cbBlobSize == sizeof(Windows::Foundation::Numerics::Matrix4x4))
    {
        hr = pSample->GetBlob(MFSampleExtension_Spatial_CameraProjectionTransform,
                              (UINT8*)(&projectionMatrix),
                              sizeof(projectionMatrix),
                              &cbBlobSize);
        if (SUCCEEDED(hr) && cbBlobSize == sizeof(Windows::Foundation::Numerics::Matrix4x4))
        {
            // Assume m_spCurrentCoordinateSystem is representing
            // world coordinate system application is using
            hr = m_spCurrentCoordinateSystem->TryGetTransformTo(spSpatialCoordinateSystem.Get(),
                                                                &spTransformRef);
            if (FAILED(hr))
            {
                return hr;
            }
            hr = spTransformRef->get_Value(&worldToCameraMatrix);
            if (FAILED(hr))
            {
                return hr;
            }
        }
    }
}

カメラからのテクスチャにアクセスするには、同じの D3D デバイスのカメラ枠のテクスチャを作成する必要があります。To access the texture from the camera, you need same D3D device which creates camera frame texture. この D3D デバイスがIMFDXGIDeviceManagerキャプチャ パイプライン。This D3D device is in IMFDXGIDeviceManager in the capture pipeline. メディアのキャプチャを使用することから、DXGI デバイス マネージャーを取得するIAdvancedMediaCaptureIAdvancedMediaCaptureSettingsインターフェイス。To get the DXGI Device manager from Media Capture you can use IAdvancedMediaCapture and IAdvancedMediaCaptureSettings interfaces.

Microsoft::WRL::ComPtr<IAdvancedMediaCapture> spAdvancedMediaCapture;
Microsoft::WRL::ComPtr<IAdvancedMediaCaptureSettings> spAdvancedMediaCaptureSettings;
Microsoft::WRL::ComPtr<IMFDXGIDeviceManager> spDXGIDeviceManager;
// Assume mediaCapture is Windows::Media::Capture::MediaCapture and initialized
if (SUCCEEDED(((IUnknown *)(mediaCapture))->QueryInterface(IID_PPV_ARGS(&spAdvancedMediaCapture))))
{
    if (SUCCEEDED(spAdvancedMediaCapture->GetAdvancedMediaCaptureSettings(&spAdvancedMediaCaptureSettings)))
    {
        spAdvancedMediaCaptureSettings->GetDirectxDeviceManager(&spDXGIDeviceManager);
    }
}

マウスとキーボードの Windows Mixed Reality アプリの省略可能な入力メソッドとして入力することもできます。You can also enable mouse and keyboard input as optional input methods for your Windows Mixed Reality app. これは、HoloLens などのデバイス用の優れたデバッグ機能をすることもでき、Pc に接続されている、イマーシブ ヘッドセットで実行されている複合現実アプリでのユーザー入力のことが望ましい場合があります。This can also be a great debugging feature for devices such as HoloLens, and may be desirable for user input in mixed reality apps running in immersive headsets attached to PCs.