iOS ArbiTrack の基礎

このチュートリアルは、Kudan ArbiTrack 機能の使用に関する基礎を紹介します。

このチュートリアルは、ターゲット ノードと画像ノードのアセットを使用します。これらのアセットは、こちらからダウンロードできます。

このアセット バンドルには、次のものが含まれます。

  • Cow Target.png – ターゲット ノードに使用する画像です。デバイスのジャイロスコープとともに移動して、ArbiTracker のプレビューとして機能します。
  • Cow Tracking.png – 画像ノードに使用する画像です。ArbiTrack がトラッキングを開始すると表示されます。

ファイルをダウンロードしたら、展開してアセットを Xcode プロジェクトに追加します。

ArbiTrack の初期化

Kudan ArbiTrack 機能を使用する前に、2 つのものを初期化する必要があります。1 つは、環境内の一連の特徴点をトラッキングしてノードを所定の位置にロックする ARArbiTrackerManager です。もう 1 つは、デバイスのジャイロスコープを使用してノードを配置する ARGyroPlaceManager です。これらを初期化するには、次のコードをビュー コントローラーに追加します。

ViewController.swiftViewController.m
override func setupContent() 
{
  // ArbiTrack を初期化
  let arbiTrack = ARArbiTrackerManager.getInstance()
  arbiTrack?.initialise()
        
  // ジャイロスコープの配置を初期化
  // ジャイロスコープの位置で仮想床面にコンテンツを配置
  let gyroPlaceManager = ARGyroPlaceManager.getInstance()
  gyroPlaceManager?.initialise() 
}
- (void)setupContent
{
  // ArbiTrack を初期化
  ARArbiTrackerManager *arbiTrack = [ARArbiTrackerManager getInstance];
  [arbiTrack initialise];

  // ジャイロスコープの配置を初期化
  // ジャイロスコープの位置で仮想床面にコンテンツを配置
  ARGyroPlaceManager *gyroPlaceManager = [ARGyroPlaceManager getInstance];
  [gyroPlaceManager initialise];
}

このコードは、ジャイロスコープと KudanCV の ArbiTracker を含む、ArbiTrack が必要とするすべてのものを初期化します。

特徴点が少ない環境

ArbiTrack は、正確にトラッキングするため、環境内の多数の特徴点を使用します。特徴点の少ない環境では、トラッキングの一貫性が損なわれることがあります。

ターゲット ノードの設定

ワールド空間にモデルを配置するには、ターゲット ノードを使用する必要があります。このノードは、トラッキングの開始点を決定します。デバイスの向きに応じてターゲット ノードの位置は変わるため、ターゲット ノードの位置をグラフィカルに表現すると便利です。

ターゲット ノードは ARNode であるため、単純なプレビュー画像やトラッキング対象のモデルを含む、あらゆるものをプレビューすることが可能です。このチュートリアルでは、ターゲットに Kudan Cow を使用します。

ターゲット ノードを作成して ArbiTracker に追加するには、次のコードを setupContent メソッドの最後に追加します。

ViewController.swiftViewController.m
// ターゲットとして使用されるノードを作成
let targetImageNode = ARImageNode(image: UIImage(named:"Cow Target"))
        
// デバイスのジャイロスコープとともに移動するように、ジャイロスコープ配置マネージャーのワールド空間にターゲット ノードを追加
gyroPlaceManager?.world.addChild(targetImageNode)
        
// 正しく表示されるようにノードを回転およびスケーリング
targetImageNode?.rotate(byDegrees: 90, axisX: 1, y: 0, z: 0)
targetImageNode?.rotate(byDegrees: 180, axisX: 0, y: 1, z: 0)

targetImageNode?.scale(byUniform: 0.3)
        
// ArbiTracker のターゲット ノードを設定
arbiTrack?.targetNode = targetImageNode
// ターゲットとして使用されるノードを作成
ARImageNode *targetImageNode = [[ARImageNode alloc] initWithImage:[UIImage imageNamed:@"Cow Target"]];

// デバイスのジャイロスコープとともに移動するように、ジャイロスコープ配置マネージャーのワールド空間にターゲット ノードを追加
[gyroPlaceManager.world addChild:targetImageNode];

// 正しく表示されるようにノードを回転およびスケーリング
[targetImageNode rotateByDegrees:90 axisX:1 y:0 z:0];
[targetImageNode rotateByDegrees:180 axisX:0 y:1 z:0];

[targetImageNode scaleByUniform:0.3];
 
// ArbiTracker のターゲット ノードを設定
arbiTrack.targetNode = targetImageNode;

このコードは、画像ノードを作成して、ジャイロスコープ配置マネージャーのワールド空間に追加し、ArbiTracker に割り当てます。

ArbiTrack でのコンテンツの設定

ターゲット ノードは作成しましたが、ArbiTrack の開始時に表示するものが必要です。ターゲット ノードと同様に、ArbiTrack では任意のノードを使用して任意のコンテンツを表示できます。このチュートリアルでは、画像ノードを使用します。次のコードを setupContent メソッドの最後に追加します。

ViewController.swiftViewController.m
// トラッキングされるノードを作成
let trackingImageNode = ARImageNode(image: UIImage(named:"Cow Tracking"))
        
// 正しく表示されるようにノードを回転
trackingImageNode?.rotate(byDegrees: 90, axisX: 1, y: 0, z: 0)
trackingImageNode?.rotate(byDegrees: 180, axisX: 0, y: 1, z: 0)
        
// ArbiTracker のワールド空間に子としてノードを追加
arbiTrack?.world.addChild(trackingImageNode)
// トラッキングされるノードを作成
ARImageNode *trackingImageNode = [[ARImageNode alloc] initWithImage:[UIImage imageNamed:@"Cow Tracking"]];

// 正しく表示されるようにノードを回転
[trackingImageNode rotateByDegrees:90 axisX:1 y:0 z:0];
[trackingImageNode rotateByDegrees:180 axisX:0 y:1 z:0];

// ArbiTracker のワールド空間に子としてノードを追加
[arbiTrack.world addChild:trackingImageNode];

このコードは、トラッキング画像を使用して画像ノードを作成し、ArbiTracker のワールド空間に追加します。

タッチ入力の実装と ArbiTrack の開始

これで、ターゲット ノードとコンテンツの画像ノードを作成し、ArbiTrack とジャイロスコープの設定が完了しましたが、どのようにトラッキングを開始したらよいのでしょうか? 画像トラッカーは、マーカーを探すだけだったため自動で開始できましたが、ArbiTracker には探すものがありません。つまり、いつ開始すべきかを知らせる必要があります。幸いにも、これは非常に簡単です。

さまざまな入力方法を利用できます。例えば、画面にボタンを追加できます。しかし、これには多くの設定と IBOutlets の調整が必要です。より簡単な方法は、ビュー コントローラーで実装することです。次のメソッドをビュー コントローラーに追加します。

ViewController.swiftViewController.m
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
{
  let arbiTrack = ARArbiTrackerManager.getInstance()
  arbiTrack?.start()
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    ARArbiTrackerManager *arbiTrack = [ARArbiTrackerManager getInstance];
    [arbiTrack start];
}

このメソッドは、アプリが画面のタップに応答できるようにします。画面がタップされたらトラッキングを開始するように ArbiTracker に指示しています。

アプリをビルドして実行すると、画面の中央にターゲット ノードが表示されます。デバイスを移動すると、ターゲット ノードも一緒に移動します。画面をタップすると、ArbiTrack はトラッキングを開始します。しかし、ターゲット ノードは表示されたままです。さらに、画面を再度タップすると、画像は新しい位置に移動してそこからトラッキングを開始します。これらの問題に対処する必要があります。

ターゲット ノードの非表示とトラッキングの切り替え

touchesBegan メソッドにいくつかの変更を適用する必要があります。最初に、ターゲット ノードを非表示にします。これは 1 行のコードを追加するだけで済みます。

ViewController.swiftViewController.m
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
{
  let arbiTrack = ARArbiTrackerManager.getInstance()
  arbiTrack?.start()
  arbiTrack?.targetNode.visible = false
}

– (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
ARArbiTrackerManager *arbiTrack = [ARArbiTrackerManager getInstance];
[arbiTrack start];
arbiTrack.targetNode.visible = NO;
}

これで、トラッキングが有効な間はターゲット ノードが非表示になります。アプリを再度ビルドして実行すると、画面をタップしたときにトラッキング画像ノードのみが表示されます。

次に、タップするたびにトラッキングを再開するのではなく、停止できるようにします。再度、touchesBegan メソッドを変更します。

ViewController.swiftViewController.m
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
    let arbiTrack = ARArbiTrackerManager.getInstance()
        
    if (arbiTrack?.isTracking)!
    {
        arbiTrack?.stop()
        arbiTrack?.targetNode.visible = true
    }
    else
    {
        arbiTrack?.start()
        arbiTrack?.targetNode.visible = false
    }
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    ARArbiTrackerManager *arbiTrack = [ARArbiTrackerManager getInstance];
    
    if (arbiTrack.isTracking)
    {
        [arbiTrack stop];
        arbiTrack.targetNode.visible = YES;
    }
    
    else
    {
        [arbiTrack start];
        arbiTrack.targetNode.visible = NO;
    }
}

ここでは、arbiTrack.isTracking を使用して、画面をタップしたときにトラッカーが実行中かどうかをチェックします。トラッカーが実行中の場合は、トラッキングを停止してターゲット ノードを表示します。そうすることで、「ターゲット」モードに戻ることができます。トラッカーが実行中でない場合は、前述のように、トラッキングを開始してターゲット ノードを非表示にします。

アプリを再度ビルドして実行すると、画面をタップしたときにターゲット ノードが非表示になり、その位置にトラッキング ノードが表示されます。再度タップすると、トラッキング ノードが非表示になり、ターゲット ノードが表示されます。