かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WindowsでC++で加速度センサーの値をとりたい

追記

2021/04/14: 以下のサイトのほうがコードが洗練されていて綺麗。

qiita.com

本文

ぐぐってもWinRTの情報はよくひっかかるんですけどねぇ。

情報ソースはここらへんを見ればいいらしい。

個人的に超参考になるなと思ったのは以下のサイトです。 software.intel.com

ということで、今回はUnity向けにdllとして提供しないといけなかったのでこんな感じになりました。

ヘッダー。

extern "C"
{
    struct PluginVector3
    {
        double x;
        double y;
        double z;
    };

    __declspec (dllexport) PluginVector3 GetAccelerometer();
}

cpp

#include "stdafx.h"
#include <InitGuid.h>
#include <SensorsApi.h>
#include <Sensors.h>
#pragma comment(lib, "Sensorsapi.lib")

__declspec (dllexport) PluginVector3 GetAccelerometer()
{
    ISensorManager *pSensorManager;
    ISensorCollection *pMotionSensorCollection;
    ISensor *pMotionSensor;

    if (!SUCCEEDED(::CoCreateInstance(CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pSensorManager))))
    {
        return PluginVector3();
    }
    if (!SUCCEEDED(pSensorManager->GetSensorsByCategory(SENSOR_TYPE_ACCELEROMETER_3D, &pMotionSensorCollection)))
    {
        pSensorManager->Release();
        return PluginVector3();
    }
    if (!SUCCEEDED(pMotionSensorCollection->GetAt(0, &pMotionSensor)))
    {
        pMotionSensorCollection->Release();
        pSensorManager->Release();
        return PluginVector3();
    }

    ISensorDataReport *pData;
    if (!SUCCEEDED(pMotionSensor->GetData(&pData)))
    {
        pMotionSensor->Release();
        pMotionSensorCollection->Release();
        pSensorManager->Release();
        return PluginVector3();
    }

    PROPVARIANT x = {};
    if (!SUCCEEDED(pData->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_X_G, &x)))
    {
        pData->Release();
        pMotionSensor->Release();
        pMotionSensorCollection->Release();
        pSensorManager->Release();
        return PluginVector3();
    }
    PROPVARIANT y = {};
    if (!SUCCEEDED(pData->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Y_G, &y)))
    {
        pData->Release();
        pMotionSensor->Release();
        pMotionSensorCollection->Release();
        pSensorManager->Release();
        return PluginVector3();
    }
    PROPVARIANT z = {};
    if (!SUCCEEDED(pData->GetSensorValue(SENSOR_DATA_TYPE_ACCELERATION_Z_G, &z)))
    {
        pData->Release();
        pMotionSensor->Release();
        pMotionSensorCollection->Release();
        pSensorManager->Release();
        return PluginVector3();
    }

    pData->Release();
    pMotionSensor->Release();
    pMotionSensorCollection->Release();
    pSensorManager->Release();

    PluginVector3 v;
    v.x = x.dblVal;
    v.y = y.dblVal;
    v.z = z.dblVal;
    return v;
}

これをUnityのプラグイン機能で取り込むことで、Win32でも加速度センサー使えるようになりそうだ。