Tango3DR_Configによる3DRのチューニング

小ネタあるいは備忘録。

## はじめに
C 3D Reconstruction Libraryのリファレンスによると、Tango3DR_Configで3DR実行時の設定を行うことができる。
https://developers.google.com/tango/apis/c/reconstruction/reference/group/config-params

Unity SDKの場合、TangoManeger（TangoApplication.cs）で上記を設定できる[^1]が、両者を見比べるとパフォーマンスに影響しそうないくつかのパラメータが変更できない。

* use_parallel_integration
  * マルチスレッドを有効にするか。デフォルトはfalse。
* min_depth
  * デフォルトは0.6(m)。設定した距離よりも近い物体は、スキャンされない。
* max_depth
  * デフォルトは3.5(m)。設定した距離よりも遠い物体は、スキャンされない。
* max_voxel_weight
  * デフォルトは16383。値が大きいと品質が向上、小さいと応答性が向上。

[^1]: [Tangoの3DRをチューニングしてみた](http://qiita.com/jyuko/items/4753f0c228e8db7701bf)


## 設定方法
C APIのラッパーにあたるクラス（TangoWrappers/Tango3DReconstruction.cs）でconfigを設定しているので、インターフェースを拡張してあげればよい。

```Tango3DReconstruction.cs
internal Tango3DReconstruction(float resolution, bool generateColor, bool spaceClearing, int minNumVertices,
                               UpdateMethod updateMethod, bool useParallel, double minDepth, double maxDepth,
                               int maxVoxelWeight) // inputを追加
{
    IntPtr config = API.Tango3DR_Config_create((int)APIConfigType.Context);
    API.Tango3DR_Config_setDouble(config, "resolution", resolution);
    API.Tango3DR_Config_setBool(config, "generate_color", generateColor);
    API.Tango3DR_Config_setBool(config, "use_space_clearing", spaceClearing);
    API.Tango3DR_Config_setInt32(config, "min_num_vertices", minNumVertices);
    API.Tango3DR_Config_setInt32(config, "update_method", (int)updateMethod);

    // configを追加
    /*** ここから ***/
    API.Tango3DR_Config_setBool(config, "use_parallel_integration", useParallel);
    API.Tango3DR_Config_setDouble(config, "min_depth", minDepth);
    API.Tango3DR_Config_setDouble(config, "max_depth", maxDepth);
    API.Tango3DR_Config_setInt32(config, "max_voxel_weight", maxVoxelWeight);
    /*** ここまで ***/

    // The 3D Reconstruction library can not handle a left handed transformation during update.  Instead,
    // transform into the Unity world space via the external_T_tango config.
    APIMatrix3x3 unityWorld_T_startService = new APIMatrix3x3();
    unityWorld_T_startService.SetRow(0, new Vector3(1, 0, 0));
    unityWorld_T_startService.SetRow(1, new Vector3(0, 0, 1));
    unityWorld_T_startService.SetRow(2, new Vector3(0, 1, 0));
    API.Tango3DR_Config_setMatrix3x3(config, "external_T_tango", ref unityWorld_T_startService);
    API.Tango3DR_Config_setBool(config, "use_clockwise_winding_order", true);

    m_context = API.Tango3DR_create(config);
    API.Tango3DR_Config_destroy(config);
}
```

呼び出し例は、以下のようになる。デフォルト値から変更したい場合は、Tango3DReconstructionのインスタンスを作成する前に変数の値を書き換える。

```TangoApplication.cs

Public bool m_3drUseParallel = false;
Public double m_3drMinDepth = 0.6d;
Public double m_3drMaxDepth = 3.5d;
Public int m_3drMaxVoxelWeight = 16383;

...

if (m_enable3DReconstruction)
{
    m_tango3DReconstruction = new Tango3DReconstruction(
    resolution: m_3drResolutionMeters,
    generateColor: m_3drGenerateColor,
    spaceClearing: m_3drSpaceClearing,
    minNumVertices: m_3drMinNumVertices,
    updateMethod: m_3drUpdateMethod,
    useParallel: m_3drUseParallel,
    minDepth: m_3drMinDepth,
    maxDepth: m_3drMaxDepth,
    maxVoxelWeight: m_3drMaxVoxelWeight
    );
    m_tango3DReconstruction.m_useAreaDescriptionPose = m_3drUseAreaDescriptionPose;
    m_tango3DReconstruction.m_sendColorToUpdate = m_3drGenerateColor;
}
```

これらを調整することで、メッシュの解像度を高めに設定した場合のパフォーマンスが多少は改善できる。
また、min_depth、max_depthを変更することで、手前にある物体だけをスキャンし、背景（壁）はスキャンしないといった使い方もできる。