Help us understand the problem. What is going on with this article?

Vuforia の External Camera (File Driver) を使う

More than 1 year has passed since last update.

概要

前回の記事 では Vuforia の File Driver をビルドしました.

今回の記事では実際に Unity のプロジェクトに組み込んで外部カメラとしてローカルの画像ファイルを読み込ませたいと思います.

出来上がったものがこちらになります(3分クッキング的な).

image.png

動画はこちらから御覧ください

作業したプロジェクトはこれです

※ ファイルサイズの関係で一部のみアップロードしています.

ノウハウ

基本的には Vuforia の公式サイトにある Building and Using the File Driver Sample を動かしただけなのでそんなに難しいことは無いのですがいくつか気がついた点を書いていきます.

Unity Editor では普通のカメラを使う

FileDriver は UWP もしくは Android 上でしか動きません(2018/10/08現在). そのため、 UnityEditor 上で動かそうとすると警告が表示されてしまいます.

なので UWP として実行しているときだけ FileDriver を使うように以下のようにコードを変更しました. Android の場合もよしなに #if すれば大丈夫です.

    void Awake()
    {
#if UNITY_WSA && !UNITY_EDITOR
        string filePath = Application.streamingAssetsPath.Replace("/", "\\");

        userData = new FileDriverUserData()
        {
            sequenceDirectoryAbsolutePath = filePath
        };

        userDataPrt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FileDriverUserData)));
        Marshal.StructureToPtr(userData, userDataPrt, false);


        VuforiaUnity.SetDriverLibrary("FileDriver.dll", userDataPrt);
#endif
        VuforiaRuntime.Instance.InitVuforia();
    }

常に同じ画像を使う

sequence.txtNumberOfImage を 1 にして image00000.png という画像をおいておけばその画像だけを永遠にループし続けるので静止画を認識させるときに使えます.

アニメーションの画像を作る

こちらは Photoshop の機能なのですが、2つのコマから間のコマを作って出力する事ができます. photoshop タイムライン とかでググるとやり方が出てきます.

↑ で作った画像を image00000.png 形式にリネームするのがめんどい

こうやりました.

const fs = require("fs");
const regex = () => /.+ ([0-9]+)\.png/
const pad = 5
let dry = true

/**
 *
 * @param {string} path
 */
const toMap = path => {

  const re = regex()
  const match = re.exec(path)
  const valid = match && typeof match[1] == "string" && !isNaN(parseInt(match[1], 10))
  return {
    valid,
    path,
    replacePath: valid ? `image${match[1].padStart(pad, "0")}.png`: null,
    match: valid ? parseInt(match[1]) : null
  }
}

fs.readdirSync(".", { encoding: "utf8" })
  .map(toMap)
  .filter(f => f.valid)
  .sort((a, b) => a.match - b.match)
  .forEach(f => {
    console.log(`Rename: "${f.path}" => "${f.replacePath}"`)
    if (dry === false) {
      fs.renameSync(f.path, f.replacePath)
    }
  })

mironal
✩*⋆¸¸.•*¨*꒰⁎˃ ॢꇴ ॢ˂⁎꒱*¨*•.¸¸⋆*✩
http://mironal-memo.blogspot.jp/
covelline
もっと楽しい明日をつくる
http://covelline.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away