Tango SDKの中にある MarkerDetection というサンプルを見ればすぐわかると思いますが、要点をまとめておきます。
Texture and Raw Bytes
Tango Manager の Enable Video Overlay にチェックを入れ、Method は「Texture and Raw Bytes」を選びます。「Raw Bytes」があるやつを選ばないと後述の OnTangoImageAvailableEventHandler が呼ばれません。また、「Texture」があるやつでないと画面にカメラの映像が出てきません。
大きなQRコードを使う
自分が使っている端末は ZenFone AR なのですが、そのままではカメラのフォーカスが合っておらず、またTango SDK内にフォーカスを設定するAPIも見当たらないようだったので、10cm角程度の大きなQRコードを使う必要がありました。いずれフォーカスを設定するAPIの整備もされると思いますが、現状はこのような状況のようです。
TangoSupport.DetectMarkers にはQRコードの正確なサイズを渡す
TangoSupport.DetectMarkers の4番目の引数は、TangoSupport.csのドキュメントコメントによると Physical size of marker's length. となっています。ここに適当な値を渡してもQRコードの認識はしてくれるので、自分は最初、この値はヒント的なものと思い込んでいました。しかし、よく調べてみると TangoSupport.DetectMarkers から返される TangoSupport.Marker の m_corner3DP0 などの値がおかしくなっていました。QRコードの空間内での位置も利用したい場合には、ここにQRコードの正確なサイズを渡す必要があります。
(深度センサーの値からよしなにやってくれるとよいのですが、そうではないようです)
OnTangoImageAvailableEventHandler
コード内でカメラの映像を利用するには ITangoVideoOverlay インターフェースを実装します。このインターフェースには OnTangoImageAvailableEventHandler というメソッド1つだけがあり、次のように実装します。
public class DetectMarker : MonoBehaviour, ITangoVideoOverlay {
void Start () {
TangoApplication tangoApp = FindObjectOfType<TangoApplication> ();
tangoApp.Register (this);
}
public void OnTangoImageAvailableEventHandler(
TangoEnums.TangoCameraId cameraId,
TangoUnityImageData imageBuffer)
{
List<TangoSupport.Marker> markerList = new List<TangoSupport.Marker> ();
TangoSupport.DetectMarkers (imageBuffer, cameraId, TangoSupport.MarkerType.QRCODE, 0.0945, markerList);
if (markerList.Count > 0) {
TangoSupport.Marker marker = markerList[0];
Debug.Log (marker.m_content);
transform.position = marker.m_translation;
transform.rotation = marker.m_orientation;
var bottomToTop = marker.m_corner3DP3 - marker.m_corner3DP0;
var leftToRight = marker.m_corner3DP1 - marker.m_corner3DP0;
transform.localScale = new Vector3(leftToRight.magnitude, 1, bottomToTop.magnitude);
}
}
}
