基本的なスクリプトの作成

カメラの初期化

カメラを初期化するためには、以下の手順で行ないます。

  1. カメラデバイスの定義ファイルを読み込む
  2. カメラパラメータファイル(カメラの歪みなどを調整する)を読み込む


カメラを初期化し、カメラからの映像を表示するためのサンプルコードはこんな感じです。(data/camera.js)

// camera.js: ただカメラを初期化するだけ

printLine("初期化開始");

// カメラの関連付け
window.initVideo("WDM_camera_flipV.xml");
// カメラパラメータに基づいてウィンドウ初期化
window.initWindow("camera_para.dat");

printLine("初期化完了");

実行方法

  1. テキストエディタを使用し、適当なフォルダにcamera.jsとして上記コードを記述する(文字コードはShift-JIS)
  2. 記述したjsファイルと同じフォルダにWDM_camera_flipV.xml, camera_para.datをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data内にあります)
  3. ARgilを起動し、jsファイルへのパスを入力し、[Execute]をクリックする

実行結果

カメラの設定ダイアログが表示されます。ここで設定を行ない、[OK]を押すと以下のようにカメラの映像が表示されます。

うまく動かない場合


マーカーの読み込み

ARgilでは、マーカーのパターンファイルを読み込ませておくと、カメラにマーカーが現れたかどうかを検出し、その上に3Dモデルなどをオーバーレイすることができます。

マーカーはARToolkitの仕様に準拠しています。サンプルとして、data/patt内にpatt.*としてパターンファイルが、*.pdfとして印刷用PDFファイルが用意されています。

オリジナルのパターンを作成したい場合はmk_pattを使用してpatt.*ファイルを生成してください。


サンプルコードはこんな感じです。(data/patt.js)

// patt.js: パターンの検出

printLine("初期化開始");

// カメラの関連付け
window.initVideo("WDM_camera_flipV.xml");
// カメラパラメータに基づいてウィンドウ初期化
window.initWindow("camera_para.dat");

printLine("初期化完了");


var pattern = null;

// "Hiro"パターンの読み込み
// data/patt/pattHiro.pdfを印刷してください
pattern = window.loadPattern("patt/patt.hiro");

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: Hiro");
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: Hiro");
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: Hiro";
};

// "A"パターンの読み込み
// data/patt/pattMulti.pdfを印刷してください
pattern = window.loadPattern("patt/patt.a");

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: A");
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: A");
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: A";
};

実行方法

  1. テキストエディタを使用し、適当なフォルダにpatt.jsとして上記コードを記述する(文字コードはShift-JIS)
  2. 記述したjsファイルと同じフォルダにWDM_camera_flipV.xml, camera_para.datをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data内にあります)
  3. 記述したjsファイルと同じフォルダにpattフォルダを作成し、以下にpatt.hiro, patt.aをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data/patt内にあります)
  4. ARgilを起動し、jsファイルへのパスを入力し、[Execute]をクリックする
  5. HiroとAのパターンファイルを印刷してカメラにかざす(これらのPDFファイルは(インストールしたディレクトリ)/data/patt内にあります)

実行結果

カメラの初期化と同様にカメラ設定を行なった後、カメラにマーカーをかざすと、コンソールにonfound, onlostなどイベントに応じたメッセージが表示されます。


画像の表示

検出したマーカー上に画像を表示してみましょう。

ARgilでは複数のWorld(座標系)を定義し、その座標系をマーカーと対応付けることでマーカー上への3Dオブジェクトの表示を実現します。

基本的な手順は以下のとおりです。

  1. window.addWorldメソッドを呼び出し座標系を作成
  2. loadImage,addContainerメソッドなどを利用して座標系内に3Dオブジェクトを構築
  3. マーカーを検出、移動、見失ったのに応じて、Worldの位置を調整


サンプルコードはこんな感じです。(data/image.js)

// image.js: 画像の表示

printLine("初期化開始");

// カメラの関連付け
window.initVideo("WDM_camera_flipV.xml");
// カメラパラメータに基づいてウィンドウ初期化
window.initWindow("camera_para.dat");

printLine("初期化完了");


var pattern = null;
var worldHiro = window.addWorld();
// 画像の読み込み: 表示幅は80mm
var imageHiro = worldHiro.loadImage("png", "image/test-hiro.png", 80.0, 
    function(source, result){
        var targetPath = "image/test-hiro.png";
        if(result == 0) {
            // 成功
            printLine("Loaded: " + targetPath);
            // 不透明
            source.props.alpha = 1.0;
        }else{
            // 失敗
            alert("Failed: " + targetPath);
        }
    });

// "Hiro"パターンの読み込み
// data/patt/pattHiro.pdfを印刷してください
pattern = window.loadPattern("patt/patt.hiro");
// Hiroパターンの1辺は80mm
pattern.width = 80.0;

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: Hiro");
    
    worldHiro.translate = ev.translate;
    worldHiro.visible = true;
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: Hiro");
    
    worldHiro.visible = false;
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: Hiro";
    
    worldHiro.translate = ev.translate;
};

var worldA = window.addWorld();
// 画像の読み込み: 表示幅は80mm
var imageA = worldA.loadImage("png", "image/test-a.png", 80.0, 
    function(source, result){
        var targetPath = "image/test-a.png";
        if(result == 0) {
            // 成功
            printLine("Loaded: " + targetPath);
            // 半透明に変更
            source.props.alpha = 0.8;
        }else{
            // 失敗
            alert("Failed: " + targetPath);
        }
    });

// "A"パターンの読み込み
// data/patt/pattMulti.pdfを印刷してください
pattern = window.loadPattern("patt/patt.a");
// Aパターンの1辺は40mm
pattern.width = 40.0;

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: A");
    
    worldA.translate = ev.translate;
    worldA.visible = true;
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: A");
    
    worldA.visible = false;
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: A";
    
    worldA.translate = ev.translate;
};


実行方法

  1. テキストエディタを使用し、適当なフォルダにimage.jsとして上記コードを記述する(文字コードはShift-JIS)
  2. 記述したjsファイルと同じフォルダにWDM_camera_flipV.xml, camera_para.datをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data内にあります)
  3. 記述したjsファイルと同じフォルダにpattフォルダを作成し、以下にpatt.hiro, patt.aをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data/patt内にあります)
  4. 記述したjsファイルと同じフォルダにimageフォルダを作成し、以下にtest-hiro.png, test-a.pngをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data/image内にあります)
  5. ARgilを起動し、jsファイルへのパスを入力し、[Execute]をクリックする
  6. HiroとAのパターンファイルを印刷してカメラにかざす(これらのPDFファイルは(インストールしたディレクトリ)/data/patt内にあります)

実行結果

カメラの初期化と同様にカメラ設定を行なった後、カメラにマーカーをかざすと、マーカー上に画像が表示されます。


オブジェクトの平行移動・拡大縮小・回転

オブジェクトのサイズを調整するためには、コンテナを利用すると便利です。

コンテナは3Dのオブジェクトを仮想的にグループ化するもので、以下のプロパティを設定することでグループ内のオブジェクトに対して各種変換をおこなうことができます。


サンプルコードはこんな感じです。(data/container.js)

// container.js: コンテナを利用した平行移動・拡大縮小・回転

printLine("初期化開始");

// カメラの関連付け
window.initVideo("WDM_camera_flipV.xml");
// カメラパラメータに基づいてウィンドウ初期化
window.initWindow("camera_para.dat");

printLine("初期化完了");


var pattern = null;
var worldHiro = window.addWorld();
var containerHiro = worldHiro.addContainer();
// 1/2に縮小
containerHiro.scale = {x: 0.5, y: 0.5, z: 0.5};
containerHiro.visible = true;
// 画像の読み込み: 表示幅は80mm
var imageHiro = containerHiro.loadImage("png", "image/test-hiro.png", 80.0, 
    function(source, result){
        var targetPath = "image/test-hiro.png";
        if(result == 0) {
            // 成功
            printLine("Loaded: " + targetPath);
            // 不透明
            source.props.alpha = 1.0;
        }else{
            // 失敗
            alert("Failed: " + targetPath);
        }
    });

// "Hiro"パターンの読み込み
// data/patt/pattHiro.pdfを印刷してください
pattern = window.loadPattern("patt/patt.hiro");
// Hiroパターンの1辺は80mm
pattern.width = 80.0;

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: Hiro");
    
    worldHiro.translate = ev.translate;
    worldHiro.visible = true;
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: Hiro");
    
    worldHiro.visible = false;
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: Hiro";
    
    worldHiro.translate = ev.translate;
};

var worldA = window.addWorld();
// 40mm浮かせる
var containerA1 = worldA.addContainer();
containerA1.translate = {x: 0, y: 0, z: 40.0};
containerA1.visible = true;
// 90°回転
var containerA2 = containerA1.addContainer();
containerA2.rotate = {angle: 90.0, x: 1.0, y: 0.0, z: 0.0};
containerA2.visible = true;

// 画像の読み込み: 表示幅は80mm
var imageA = containerA2.loadImage("png", "image/test-a.png", 80.0, 
    function(source, result){
        var targetPath = "image/test-a.png";
        if(result == 0) {
            // 成功
            printLine("Loaded: " + targetPath);
            // 半透明に変更
            source.props.alpha = 0.8;
        }else{
            // 失敗
            alert("Failed: " + targetPath);
        }
    });

// "A"パターンの読み込み
// data/patt/pattMulti.pdfを印刷してください
pattern = window.loadPattern("patt/patt.a");
// Aパターンの1辺は40mm
pattern.width = 40.0;

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: A");
    
    worldA.translate = ev.translate;
    worldA.visible = true;
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: A");
    
    worldA.visible = false;
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: A";
    
    worldA.translate = ev.translate;
};

実行方法

  1. テキストエディタを使用し、適当なフォルダにcontainer.jsとして上記コードを記述する(文字コードはShift-JIS)
  2. 記述したjsファイルと同じフォルダにWDM_camera_flipV.xml, camera_para.datをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data内にあります)
  3. 記述したjsファイルと同じフォルダにpattフォルダを作成し、以下にpatt.hiro, patt.aをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data/patt内にあります)
  4. ARgilを起動し、jsファイルへのパスを入力し、[Execute]をクリックする
  5. HiroとAのパターンファイルを印刷してカメラにかざす(これらのPDFファイルは(インストールしたディレクトリ)/data/patt内にあります)

実行結果

カメラの初期化と同様にカメラ設定を行なった後、カメラにマーカーをかざすと、マーカー上に画像が表示されます。

先のimage.jsの例と異なり、画像オブジェクトに対して移動・拡大縮小・回転の効果が設定されているはずです。


MikuMikuDanceモデルの表示

MMDプラグインを読み込むことで、MikuMikuDanceのPMDファイルとVMDファイルを再生することができます。(※物理演算は非対応)

ここでは作者の個人的な趣味で、あずにゃんにゃんをARで実現してみることにしましょう。
以下の手順が必要になります。

  1. argmmd.dllの読み込み
  2. PMDファイル・VMDファイルの読み込み
  3. MMDオブジェクトの再生開始


サンプルコードはこんな感じです。(data/mmd.js)

// mmd.js: MikuMikuDanceモデルの表示

printLine("初期化開始");

// カメラの関連付け
window.initVideo("WDM_camera_flipV.xml");
// カメラパラメータに基づいてウィンドウ初期化
window.initWindow("camera_para.dat");

// dllはexeとの相対パスで指定
plugins.load("argmmd.dll", "MMD");

printLine("初期化完了");


var pattern = null;

var worldA = window.addWorld();
var currentMMDA = null;
// 倍率x5でMMDモデルをロード
var mmdObj = worldA.loadMMD("mmd/中野梓.pmd", "mmd/azunyan207.vmd", 5.0, function(source, result){
    if(result == 0) {
        // 成功
        printLine("Loaded");
        currentMMDA = source.params;
        if(currentMMDA != null) {
            // あずにゃんモデルの場合は腕IKを無効化
            for(var i = 0; i < currentMMDA.ikCount; i ++) {
                var name = currentMMDA.ikTarget(i);
                if(name.indexOf("腕") > 0) {
                    currentMMDA.setIKEnabled(i, false);
                }
            }
        }
    }else{
        // 失敗
        alert("Failed");
    }
    });
mmdObj.rotate = {angle: 90.0, x: 1.0, y: 0.0, z: 0.0};

// "A"パターンの読み込み
// data/patt/pattMulti.pdfを印刷してください
pattern = window.loadPattern("patt/patt.a");
// Aパターンの1辺は40mm
pattern.width = 40.0;

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: A");
    refreshMMD(currentMMDA);
    
    worldA.translate = ev.translate;
    worldA.visible = true;
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: A");
    
    worldA.visible = false;
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: A";
    refreshMMD(currentMMDA);
    
    worldA.translate = ev.translate;
};

// モデルを更新します。
function refreshMMD(model)
{
    if(model != null) {
        if(model.playing == false) {
            printLine("Play");
            model.play(0);
        }else if(model.currentFrame >= model.maxFrame) {
            printLine("Replay");
            model.play(0);
        }
    }
}


実行方法

  1. テキストエディタを使用し、適当なフォルダにmmd.jsとして上記コードを記述する(文字コードはShift-JIS)
  2. 記述したjsファイルと同じフォルダにWDM_camera_flipV.xml, camera_para.datをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data内にあります)
  3. 記述したjsファイルと同じフォルダにpattフォルダを作成し、以下にpatt.aをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data/patt内にあります)
  4. MMDモデルをダウンロードする
    1. 「けいおん!」中野梓 MikuMikuDance用モデルデータ(.pmd)をダウンロード
    2. このフォルダに[けいおん中野梓腕IkPMD090701_1]内のファイルを展開
    3. あずにゃんにゃんの動画説明文中のモーションファイルのURLを開き、zipファイルをダウンロード
    4. このフォルダに[あずにゃんにゃん]内のファイルを展開
  5. ARgilを起動し、jsファイルへのパスを入力し、[Execute]をクリックする
  6. Aのパターンファイルを印刷してカメラにかざす(これらのPDFファイルは(インストールしたディレクトリ)/data/patt内にあります)

実行結果

カメラの初期化と同様にカメラ設定を行なった後、カメラにマーカーをかざすと、マーカー上にMMDモデルが表示され、モーションが再生されます。


iTunes関連

argitunesプラグインを使用することで、iTunesと連携することができます。

詳細な仕様はiTunes COM for Windows SDKを参照してください。


サンプルコードはこんな感じです。(data/itunes.js)

// ituens.js: iTunesの制御

printLine("初期化開始");

// カメラの関連付け
window.initVideo("WDM_camera_flipV.xml");
// カメラパラメータに基づいてウィンドウ初期化
window.initWindow("camera_para.dat");

plugins.load("argitunes.dll", "iTunes");

printLine("初期化完了");


var itunes = iTunes;

var pattern = null;
var targetTrack = null;
var notFound = false;

// "A"パターンの読み込み
// data/patt/pattMulti.pdfを印刷してください
pattern = window.loadPattern("patt/patt.a");

// 再生対象のトラック名
var trackName = "ハレ晴レユカイ";

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: A");
    
    // 再生開始
    if(notFound) {
        return;
    }
    if(targetTrack == null) {
        targetTrack = findTrackFromSourceCollection(iTunes.Sources, trackName);
        if(targetTrack == null) {
            alert("Not found: " + trackName);
            notFound = true;
            return;
        }
    }
    targetTrack.Play();
    
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: A");
    
    // 一時停止
    iTunes.Pause();
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: A";
};


// トラックを検索します。
function findTrackFromSourceCollection(sources, name)
{
    for(var i = 0; i < sources.Count; i ++) {
        var source = sources.Item(i+1);
        
        var result = findTrackFromSource(source, name);
        if(result != undefined) {
            return result;
        }
    }
    return undefined;
};

// トラックを検索します。
function findTrackFromSource(source, name)
{
    var playlists = source.Playlists;
    for(var i = 0; i < playlists.Count; i ++) {
        var playlist = playlists.Item(i+1);
        
        var result = findTrackFromPlaylist(playlist, name);
        if(result != undefined) {
            return result;
        }
    }
    return undefined;
};

// トラックを検索します。
function findTrackFromPlaylist(source, name)
{
    var tracks = source.Tracks;
    return tracks.ItemByName(name);
};

実行方法

  1. テキストエディタを使用し、適当なフォルダにitunes.jsとして上記コードを記述する(文字コードはShift-JIS)
  2. 記述したjsファイルと同じフォルダにWDM_camera_flipV.xml, camera_para.datをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data内にあります)
  3. 記述したjsファイルと同じフォルダにpattフォルダを作成し、以下にpatt.aをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data/patt内にあります)
  4. ARgilを起動し、jsファイルへのパスを入力し、[Execute]をクリックする

    iTunesの起動に時間がかかりますのでしばらくお待ちください。

  5. Aのパターンファイルを印刷してカメラにかざす(これらのPDFファイルは(インストールしたディレクトリ)/data/patt内にあります)

実行結果

カメラの初期化と同様にカメラ設定を行なうとiTunesが自動的に起動されます。カメラにマーカーをかざすと、曲が再生されます。


映像のキャプチャ・他のアプリケーションとの連携

argcaptureプラグインを使用することで、ARgilをビデオキャプチャデバイスのように利用することができるようになります。

インストーラによって登録される「ARgil Capture Source」とargcaptureプラグインを併用することで、ビデオキャプチャデバイスに対応したアプリケーションに対して、ARgilのAR表示をリアルタイムに流すことができます。

以下の手順でargcaptureプラグインを実行することができます。

  1. argcapture.dllのロード - plugins.load("argcapture.dll", "Capture");
  2. Capture.startCapture()の呼び出し


サンプルコードはこんな感じです。(data/capture.js)
「画像の表示」サンプルにキャプチャ機能を追加しています。(ただし、説明の長さの都合で、"Hiro"マーカーのみ実装しています。)

// capture.js: キャプチャ処理

printLine("初期化開始");

// カメラの関連付け
window.initVideo("WDM_camera_flipV.xml");
// カメラパラメータに基づいてウィンドウ初期化
window.initWindow("camera_para.dat");

// キャプチャの開始
plugins.load("argcapture.dll", "Capture");
Capture.startCapture();


printLine("初期化完了");


var pattern = null;
var worldHiro = window.addWorld();
// 画像の読み込み: 表示幅は80mm
var imageHiro = worldHiro.loadImage("png", "image/test-hiro.png", 80.0, 
    function(source, result){
        var targetPath = "image/test-hiro.png";
        if(result == 0) {
            // 成功
            printLine("Loaded: " + targetPath);
            // 不透明
            source.props.alpha = 1.0;
        }else{
            // 失敗
            alert("Failed: " + targetPath);
        }
    });

// "Hiro"パターンの読み込み
// data/patt/pattHiro.pdfを印刷してください
pattern = window.loadPattern("patt/patt.hiro");
// Hiroパターンの1辺は80mm
pattern.width = 80.0;

// パターンを発見した時の処理
pattern.onfound = function(ev)
{
    printLine("onfound: Hiro");
    
    worldHiro.translate = ev.translate;
    worldHiro.visible = true;
};

// パターンを見失った時の処理
pattern.onlost = function(ev)
{
    printLine("onlost: Hiro");
    
    worldHiro.visible = false;
};

// パターンの位置が変化した時の処理
pattern.onchanged = function(ev)
{
    window.status = "onchanged: Hiro";
    
    worldHiro.translate = ev.translate;
};

実行方法

  1. テキストエディタを使用し、適当なフォルダにcapture.jsとして上記コードを記述する(文字コードはShift-JIS)
  2. 記述したjsファイルと同じフォルダにWDM_camera_flipV.xml, camera_para.datをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data内にあります)
  3. 記述したjsファイルと同じフォルダにpattフォルダを作成し、以下にpatt.aをコピーする(これらのオリジナルファイルは(インストールしたディレクトリ)/data/patt内にあります)
  4. ARgilを起動し、jsファイルへのパスを入力し、[Execute]をクリックする
  5. 適当なビデオキャプチャソフトを起動し、ビデオソースとして[ARgil Capture Source]を選択する

実行結果

ビデオキャプチャソフトのプレビュー画面に「画像の表示」サンプル相当の表示("Hiro"マーカーをかざした場合)がおこなわれます。


iTunesとMMDモーションの同期

(準備中)

Metasequoiaの読み込み

(準備中)

VRMLの読み込み

(準備中)



Copyright(C) 2010 やざわラボ
Powered by Carabiner BEITEL